From 1b40ad6c8ff27120197c0b6edb29781ab7d6bf59 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 30 Jun 2024 17:21:55 -0700 Subject: [PATCH 01/29] migrate servicebus to token auth --- .../servicebus/IntegrationTestBase.java | 99 ++++++++++++++----- .../servicebus/ProxyReceiveTest.java | 6 +- .../servicebus/ProxySelectorTest.java | 3 +- .../messaging/servicebus/ProxySendTest.java | 3 +- .../ServiceBusClientBuilderTest.java | 3 + .../ServiceBusMixClientIntegrationTest.java | 20 ++-- ...viceBusProcessorClientIntegrationTest.java | 73 +------------- ...BusReceiverAsyncClientIntegrationTest.java | 40 ++++---- ...rviceBusReceiverClientIntegrationTest.java | 6 +- ...ceBusSenderAsyncClientIntegrationTest.java | 32 +++--- ...rviceBusSessionManagerIntegrationTest.java | 10 +- .../servicebus/TracingIntegrationTests.java | 52 +++++----- ...inistrationAsyncClientIntegrationTest.java | 34 ++++--- ...usAdministrationClientIntegrationTest.java | 36 ++++--- sdk/servicebus/test-resources.json | 10 -- sdk/servicebus/tests.yml | 19 +++- 16 files changed, 220 insertions(+), 226 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 5fe821608315..a64999906790 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -21,7 +21,7 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; @@ -59,6 +59,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; public abstract class IntegrationTestBase extends TestBase { + protected static final boolean USE_CREDENTIALS = true; protected static final Duration OPERATION_TIMEOUT = Duration.ofSeconds(30); protected static final Duration TIMEOUT = Duration.ofSeconds(60); // Tests use timeouts of 20-60 seconds to verify something has happened @@ -118,7 +119,9 @@ public TestMode getTestMode() { return TestMode.PLAYBACK; } - return CoreUtils.isNullOrEmpty(getConnectionString()) ? TestMode.PLAYBACK : TestMode.RECORD; + return TestMode.RECORD; + // TODO (anu): alternative for this approach? + // return CoreUtils.isNullOrEmpty(getConnectionString()) ? TestMode.PLAYBACK : TestMode.RECORD; } public static String getConnectionString() { @@ -203,14 +206,6 @@ public ProxyOptions getProxyConfiguration() { return new ProxyOptions(authenticationType, proxy, username, password); } - /** - * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings and uses a - * connection string to authenticate. - */ - protected ServiceBusClientBuilder getBuilder() { - return getBuilder(false); - } - /** * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings and uses a * connection string to authenticate if {@code useCredentials} is false. Otherwise, uses a service principal through @@ -232,7 +227,7 @@ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = new DefaultAzureCredentialBuilder().build(); + final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); return builder.credential(fullyQualifiedDomainName, tokenCredential); } else { @@ -240,6 +235,27 @@ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { } } + /** + * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings and uses a + * token credentials to authenticate. + */ + protected ServiceBusClientBuilder getBuilder() { + return getBuilder(USE_CREDENTIALS); + } + + protected ServiceBusClientBuilder getBuilder(boolean useCredentials, boolean sharedConnection) { + ServiceBusClientBuilder builder; + if (sharedConnection && sharedBuilder == null) { + sharedBuilder = getBuilder(useCredentials); + builder = sharedBuilder; + } else if (sharedConnection) { + builder = sharedBuilder; + } else { + builder = getBuilder(useCredentials); + } + return builder; + } + protected ServiceBusSenderClientBuilder getSenderBuilder(boolean useCredentials, MessagingEntityType entityType, int entityIndex, boolean isSessionAware, boolean sharedConnection) { @@ -313,6 +329,54 @@ protected ServiceBusSessionReceiverClientBuilder getSessionReceiverBuilder(boole } } + protected ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBuilder(boolean useCredentials, + MessagingEntityType entityType, int entityIndex, boolean sharedConnection) { + + ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + switch (entityType) { + case QUEUE: + final String queueName = getQueueName(entityIndex); + assertNotNull(queueName, "'queueName' cannot be null."); + + return builder.processor().queueName(queueName); + case SUBSCRIPTION: + final String topicName = getTopicName(entityIndex); + final String subscriptionName = getSubscriptionBaseName(); + assertNotNull(topicName, "'topicName' cannot be null."); + assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); + + return builder.processor().topicName(topicName).subscriptionName(subscriptionName); + default: + throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); + } + } + + protected ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessionProcessorBuilder(boolean useCredentials, + MessagingEntityType entityType, int entityIndex, boolean sharedConnection, AmqpRetryOptions amqpRetryOptions) { + + ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + builder.retryOptions(amqpRetryOptions); + + switch (entityType) { + case QUEUE: + final String queueName = getSessionQueueName(entityIndex); + assertNotNull(queueName, "'queueName' cannot be null."); + return builder + .sessionProcessor() + .queueName(queueName); + + case SUBSCRIPTION: + final String topicName = getTopicName(entityIndex); + final String subscriptionName = getSessionSubscriptionBaseName(); + assertNotNull(topicName, "'topicName' cannot be null."); + assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); + return builder.sessionProcessor() + .topicName(topicName).subscriptionName(subscriptionName); + default: + throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); + } + } + protected static Stream messagingEntityProvider() { return Stream.of( Arguments.of(MessagingEntityType.QUEUE), @@ -453,19 +517,6 @@ protected void assertMessageEquals(ServiceBusReceivedMessage message, String mes } } - protected ServiceBusClientBuilder getBuilder(boolean useCredentials, boolean sharedConnection) { - ServiceBusClientBuilder builder; - if (sharedConnection && sharedBuilder == null) { - sharedBuilder = getBuilder(useCredentials); - builder = sharedBuilder; - } else if (sharedConnection) { - builder = sharedBuilder; - } else { - builder = getBuilder(useCredentials); - } - return builder; - } - protected final Configuration v1OrV2(boolean isV2) { final TestConfigurationSource configSource = new TestConfigurationSource(); if (isV2) { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index f35d3e10ded5..adf71ac5e16c 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -5,6 +5,7 @@ import com.azure.core.amqp.AmqpTransportType; import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.jproxy.ProxyServer; import com.azure.messaging.servicebus.jproxy.SimpleProxy; import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; @@ -82,8 +83,7 @@ public void receiveMessage() { final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) - .connectionString(getConnectionString()) - + .credential(new AzurePowerShellCredentialBuilder().build()) .sender() .queueName(queueName) .buildAsyncClient(); @@ -93,7 +93,7 @@ public void receiveMessage() { final ServiceBusReceiverAsyncClient receiver = new ServiceBusClientBuilder() .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) - .connectionString(getConnectionString()) + .credential(new AzurePowerShellCredentialBuilder().build()) .receiver() .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .queueName(queueName) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java index 1dff7bec6184..dc1587238f21 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java @@ -8,6 +8,7 @@ import com.azure.core.util.BinaryData; import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.logging.LogLevel; +import com.azure.identity.AzurePowerShellCredentialBuilder; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -69,7 +70,7 @@ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + .credential(new AzurePowerShellCredentialBuilder().build()) .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) .sender() diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index 78833565375c..104d55dac5fa 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -6,6 +6,7 @@ import com.azure.core.amqp.AmqpRetryOptions; import com.azure.core.amqp.AmqpTransportType; import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.jproxy.ProxyServer; import com.azure.messaging.servicebus.jproxy.SimpleProxy; import org.apache.qpid.proton.engine.SslDomain; @@ -78,7 +79,7 @@ public void sendEvents() { final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + .credential(new AzurePowerShellCredentialBuilder().build()) .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index 57e91cd71f69..4b3ae1225e05 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -17,6 +17,7 @@ import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import com.azure.messaging.servicebus.models.SubQueue; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -267,6 +268,7 @@ public void testConnectionStringWithSas() { } @Test + @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureNameKeyCredential() { ConnectionStringProperties properties = getConnectionStringProperties(); String fullyQualifiedNamespace = getFullyQualifiedDomainName(); @@ -291,6 +293,7 @@ public void testBatchSendEventByAzureNameKeyCredential() { } @Test + @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureSasCredential() { ConnectionStringProperties properties = getConnectionStringProperties(true); String fullyQualifiedNamespace = getFullyQualifiedDomainName(); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java index 9709bc8f7726..bf0e6bfe1f20 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java @@ -84,7 +84,6 @@ protected void afterTest() { void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { // Arrange - final boolean useCredentials = false; final MessagingEntityType entityType = MessagingEntityType.QUEUE; final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; @@ -99,7 +98,7 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(useCredentials).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); @@ -171,7 +170,7 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc // Verify that message is received by queue B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, false); + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); StepVerifier.create(receiver.receiveMessages().take(1)) .assertNext(receivedMessage -> { assertMessageEquals(receivedMessage, messageId, isSessionEnabled); @@ -193,7 +192,6 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { // Arrange - final boolean useCredentials = false; final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; @@ -209,7 +207,7 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(useCredentials).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); @@ -289,7 +287,7 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru // Verify that message is received by queue B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, false); + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); StepVerifier.create(receiver.receiveMessages().take(1)) .assertNext(receivedMessage -> { assertMessageEquals(receivedMessage, messageId, isSessionEnabled); @@ -311,7 +309,6 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { // Arrange - final boolean useCredentials = false; final MessagingEntityType entityType = MessagingEntityType.QUEUE; final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; @@ -326,7 +323,7 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(useCredentials).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); @@ -376,7 +373,7 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) // Assert // Verify that message is received by entity B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, false); + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); StepVerifier.create(receiver.receiveMessages() .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())).take(1)) .assertNext(receivedMessage -> { @@ -399,7 +396,6 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { // Arrange - final boolean useCredentials = false; final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; @@ -414,7 +410,7 @@ void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionE message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(useCredentials).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); @@ -462,7 +458,7 @@ void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionE // Assert // Verify that message is received by entity B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, false); + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); StepVerifier.create(receiver.receiveMessages().take(1)) .assertNext(receivedMessage -> { assertMessageEquals(receivedMessage, messageId, isSessionEnabled); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index 8c0440f72887..cad23138cf20 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -4,8 +4,6 @@ package com.azure.messaging.servicebus; import com.azure.core.amqp.AmqpRetryOptions; -import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.amqp.ProxyOptions; import com.azure.core.util.CoreUtils; import com.azure.core.util.logging.ClientLogger; import com.azure.messaging.servicebus.implementation.MessagingEntityType; @@ -24,8 +22,6 @@ import java.util.concurrent.atomic.AtomicReference; import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; -import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; -import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -84,7 +80,7 @@ void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) th assertNotNull(sessionId, "'sessionId' should have been set."); AmqpRetryOptions amqpRetryOptions = new AmqpRetryOptions() .setTryTimeout(Duration.ofSeconds(2 * lockTimeoutDurationSeconds)); - processor = toClose(getSessionProcessorBuilder(false, entityType, entityIndex, false, amqpRetryOptions) + processor = toClose(getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, amqpRetryOptions) .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) .disableAutoComplete() .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) @@ -92,7 +88,7 @@ void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) th .buildProcessorClient()); } else { - processor = toClose(getProcessorBuilder(false, entityType, entityIndex, false) + processor = toClose(getProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false) .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) .disableAutoComplete() .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) @@ -117,7 +113,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = - getSessionProcessorBuilder(false, entityType, entityIndex, false, RETRY_OPTIONS) + getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, RETRY_OPTIONS) .sessionIdleTimeout(sessionIdleTimeout) .disableAutoComplete(); @@ -132,7 +128,7 @@ void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws Interrupt ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = - getSessionProcessorBuilder(false, entityType, entityIndex, false, + getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, new AmqpRetryOptions().setTryTimeout(tryTimeout)) .disableAutoComplete(); @@ -198,68 +194,9 @@ private void processError(ServiceBusErrorContext context, CountDownLatch countdo context.getFullyQualifiedNamespace(), context.getEntityPath()); } - private ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection) { - - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); - switch (entityType) { - case QUEUE: - final String queueName = getQueueName(entityIndex); - assertNotNull(queueName, "'queueName' cannot be null."); - - return builder.processor().queueName(queueName); - case SUBSCRIPTION: - final String topicName = getTopicName(entityIndex); - final String subscriptionName = getSubscriptionBaseName(); - assertNotNull(topicName, "'topicName' cannot be null."); - assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - - return builder.processor().topicName(topicName).subscriptionName(subscriptionName); - default: - throw LOGGER.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); - } - } - - protected ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessionProcessorBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection, AmqpRetryOptions amqpRetryOptions) { - - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); - builder.retryOptions(amqpRetryOptions); - - switch (entityType) { - case QUEUE: - final String queueName = getSessionQueueName(entityIndex); - assertNotNull(queueName, "'queueName' cannot be null."); - return builder - .sessionProcessor() - .queueName(queueName); - - case SUBSCRIPTION: - final String topicName = getTopicName(entityIndex); - final String subscriptionName = getSessionSubscriptionBaseName(); - assertNotNull(topicName, "'topicName' cannot be null."); - assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - return builder.sessionProcessor() - .topicName(topicName).subscriptionName(subscriptionName); - default: - throw LOGGER.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); - } - } - - protected ServiceBusClientBuilder getBuilder(boolean useCredentials, boolean sharedConnection) { - return new ServiceBusClientBuilder() - .connectionString(getConnectionString()) - .proxyOptions(ProxyOptions.SYSTEM_DEFAULTS) - .retryOptions(RETRY_OPTIONS) - .transportType(AmqpTransportType.AMQP) - .scheduler(scheduler) - .configuration(v1OrV2(true)); - } - private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { final boolean shareConnection = false; - final boolean useCredentials = false; - return toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionEnabled, shareConnection) + return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index d06803c10c61..c80c0fbbd7bf 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -242,11 +242,10 @@ void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { // Arrange final boolean shareConnection = true; - final boolean useCredentials = false; final int entityIndex = 0; - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) .buildAsyncClient()); final String messageId = UUID.randomUUID().toString(); @@ -287,10 +286,9 @@ void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSe // Arrange final int entityIndex = 0; final boolean shareConnection = false; - final boolean useCredentials = false; final Duration shortWait = Duration.ofSeconds(3); - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); final String messageId = UUID.randomUUID().toString(); @@ -300,11 +298,11 @@ void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSe // Now create receiver if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .buildAsyncClient()); this.receiver = toClose(sessionReceiver.acceptSession(sessionId).block()); } else { - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) .buildAsyncClient()); } @@ -328,9 +326,8 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio // Arrange final int entityIndex = USE_CASE_AUTO_COMPLETE; final boolean shareConnection = false; - final boolean useCredentials = false; - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); final String messageId = CoreUtils.randomUuid().toString(); final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); @@ -342,11 +339,11 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio // Now create receiver if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .buildAsyncClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); } else { - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) .buildAsyncClient()); } @@ -702,11 +699,10 @@ void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEn // Arrange final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; final boolean shareConnection = false; - final boolean useCredentials = false; final Duration shortWait = Duration.ofSeconds(3); final Long expectedLongValue = Long.parseLong("6"); - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); // Send value Object @@ -728,11 +724,11 @@ void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEn // Now create receiver if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .buildAsyncClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); } else { - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) .buildAsyncClient()); } @@ -1157,7 +1153,7 @@ void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnab final String queueName = isSessionEnabled ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); assertNotNull(queueName, "'queueName' cannot be null."); - deadLetterReceiver = toClose(getBuilder(false).receiver() + deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() .queueName(queueName) .subQueue(SubQueue.DEAD_LETTER_QUEUE) .buildAsyncClient()); @@ -1168,7 +1164,7 @@ void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnab assertNotNull(topicName, "'topicName' cannot be null."); assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - deadLetterReceiver = toClose(getBuilder(false).receiver() + deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() .topicName(topicName) .subscriptionName(subscriptionName) .subQueue(SubQueue.DEAD_LETTER_QUEUE) @@ -1443,7 +1439,7 @@ void autoComplete(MessagingEntityType entityType) { .verifyComplete(); final ServiceBusReceiverAsyncClient autoCompleteReceiver = - toClose(getReceiverBuilder(false, entityType, index, false) + toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, index, false) .buildAsyncClient()); Set sequenceNumbers = new HashSet<>(); @@ -1494,10 +1490,9 @@ private void setReceiver(MessagingEntityType entityType, int entityIndex, boolea private ServiceBusReceiverAsyncClient createReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, ClientCreationOptions options) { final boolean shareConnection = false; - final boolean useCredentials = false; if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - sessionReceiver = toClose(getSessionReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .maxAutoLockRenewDuration(options.getMaxAutoLockRenewDuration()) .sessionIdleTimeout(options.getSessionIdleTimeout()) .disableAutoComplete() @@ -1505,7 +1500,7 @@ private ServiceBusReceiverAsyncClient createReceiver(MessagingEntityType entityT return toClose(sessionReceiver.acceptSession(sessionId).block()); } - return toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, shareConnection) + return toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) .maxAutoLockRenewDuration(options.getMaxAutoLockRenewDuration()) .disableAutoComplete() .buildAsyncClient()); @@ -1513,8 +1508,7 @@ private ServiceBusReceiverAsyncClient createReceiver(MessagingEntityType entityT private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { final boolean shareConnection = false; - final boolean useCredentials = false; - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index 75286f87f34a..f6da6d0d638b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -855,18 +855,18 @@ private void setSender(MessagingEntityType entityType, int entityIndex, boolean } private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { - this.sender = toClose(getSenderBuilder(false, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); } private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(false, entityType, entityIndex, sharedConnection, null) + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection, null) .buildClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId)); } else { - this.receiver = toClose(getReceiverBuilder(false, entityType, entityIndex, sharedConnection) + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection) .buildClient()); } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index d62e825e3a4d..06d2170dc48b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -37,7 +37,7 @@ @Tag("integration") class ServiceBusSenderAsyncClientIntegrationTest extends IntegrationTestBase { private static final ClientLogger LOGGER = new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class); - + private ServiceBusSenderAsyncClient sender; private ServiceBusReceiverAsyncClient receiver; private final AtomicInteger messagesPending = new AtomicInteger(); @@ -93,7 +93,7 @@ static Stream transactionMessageSendAndCompleteTransaction() { @ParameterizedTest void nonSessionQueueSendMessage(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, 0, false); + setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); final String messageId = UUID.randomUUID().toString(); final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); @@ -111,7 +111,7 @@ void nonSessionQueueSendMessage(MessagingEntityType entityType) { @ParameterizedTest void nonSessionEntitySendMessageList(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); int count = 4; final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); @@ -130,7 +130,7 @@ void nonSessionEntitySendMessageList(MessagingEntityType entityType) { @ParameterizedTest void nonSessionMessageBatch(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); final String messageId = UUID.randomUUID().toString(); final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); @@ -156,7 +156,6 @@ void nonSessionMessageBatch(MessagingEntityType entityType) { @Test void viaQueueMessageSendTest() { // Arrange - final boolean useCredentials = false; final Duration shortTimeout = Duration.ofSeconds(15); final int viaIntermediateEntity = TestUtils.USE_CASE_TXN_1; final int destinationEntity = TestUtils.USE_CASE_TXN_2; @@ -169,13 +168,13 @@ void viaQueueMessageSendTest() { final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); final String viaQueueName = getQueueName(viaIntermediateEntity); - setSenderAndReceiver(entityType, viaIntermediateEntity, useCredentials); + setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); - final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(useCredentials, entityType, + final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, destinationEntity, false, shareConnection) //.viaQueueName(viaQueueName) .buildAsyncClient()); - final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(useCredentials, entityType, + final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, destinationEntity, shareConnection) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .disableAutoComplete() @@ -245,7 +244,6 @@ void viaQueueMessageSendTest() { @Test void viaTopicMessageSendTest() { // Arrange - final boolean useCredentials = false; final Duration shortTimeout = Duration.ofSeconds(15); final int viaIntermediateEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_1; final int destinationEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_2; @@ -258,16 +256,16 @@ void viaTopicMessageSendTest() { final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); final String viaTopicName = getTopicName(viaIntermediateEntity); - setSenderAndReceiver(entityType, viaIntermediateEntity, useCredentials); + setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); final ServiceBusReceiverAsyncClient intermediateReceiver = receiver; final ServiceBusSenderAsyncClient intermediateSender = sender; - final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(useCredentials, entityType, + final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, destinationEntity, false, shareConnection) //.viaTopicName(viaTopicName) .buildAsyncClient()); - final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(useCredentials, entityType, + final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, destinationEntity, shareConnection) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .disableAutoComplete() @@ -334,7 +332,7 @@ void viaTopicMessageSendTest() { void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { // Arrange Duration shortTimeout = Duration.ofSeconds(15); - setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, false); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, USE_CREDENTIALS); final boolean isSessionEnabled = false; final String messageId = UUID.randomUUID().toString(); final int total = 3; @@ -393,7 +391,7 @@ void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType @ParameterizedTest void sendWithCredentials(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, 0, true); + setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); final String messageId = UUID.randomUUID().toString(); final List messages = TestUtils.getServiceBusMessages(5, messageId, CONTENTS_BYTES); @@ -418,7 +416,7 @@ void transactionScheduleAndCommitTest(MessagingEntityType entityType) { // Arrange boolean isSessionEnabled = false; - setSenderAndReceiver(entityType, 0, isSessionEnabled); + setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); final Duration scheduleDuration = Duration.ofSeconds(3); final String messageId = UUID.randomUUID().toString(); final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); @@ -464,7 +462,7 @@ void transactionScheduleMessagesTest(MessagingEntityType entityType) { final int total = 2; final Duration shortWait = Duration.ofSeconds(3); - setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, isSessionEnabled); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, USE_CREDENTIALS); final Duration scheduleDuration = Duration.ofSeconds(5); final String messageId = UUID.randomUUID().toString(); @@ -519,7 +517,7 @@ void cancelScheduledMessagesTest(MessagingEntityType entityType) { final boolean isSessionEnabled = false; final Duration shortWaitTime = Duration.ofSeconds(5); final int total = 2; - setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, isSessionEnabled); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, USE_CREDENTIALS); final Duration scheduleDuration = Duration.ofSeconds(15); final String messageId = UUID.randomUUID().toString(); final List messages = new ArrayList<>(); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index c2edf791e44d..f6e525483d21 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -106,7 +106,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup final Duration sessionIdleTimeout = Duration.ofSeconds(3); setSender(entityType, entityIndex); - this.receiver = toClose(getSessionReceiverBuilder(false, + this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) .disableAutoComplete() .maxConcurrentSessions(1) @@ -124,7 +124,7 @@ void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws Interrupt final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); setSender(entityType, entityIndex); - this.receiver = toClose(getSessionReceiverBuilder(false, + this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, false, retryOptions) .disableAutoComplete() .maxConcurrentSessions(1) @@ -165,7 +165,7 @@ void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); - this.receiver = toClose(getSessionReceiverBuilder(false, + this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, false, retryOptions) .disableAutoComplete() .sessionIdleTimeout(sessionIdleTimeout) @@ -191,13 +191,13 @@ void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. */ private void setSender(MessagingEntityType entityType, int entityIndex) { - this.sender = toClose(getSenderBuilder(false, entityType, entityIndex, true, false) + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, true, false) .buildAsyncClient()); } private void setReceiver(MessagingEntityType entityType, int entityIndex, Function onBuild) { - ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(false, + ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); this.sessionReceiver = toClose(onBuild.apply(sessionBuilder).buildAsyncClient()); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java index 6bc5730921d2..248566011864 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java @@ -78,15 +78,15 @@ protected void beforeTest() { .build()); clientOptions = new ClientOptions().setTracingOptions(tracingOptions); - sender = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder senderBuilder = getBuilder(); + sender = toClose(senderBuilder .clientOptions(clientOptions) .sender() .queueName(getQueueName(0)) .buildAsyncClient()); - receiver = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder receiverBuilder = getBuilder(); + receiver = toClose(receiverBuilder .clientOptions(clientOptions) .receiver() .maxAutoLockRenewDuration(Duration.ZERO) @@ -94,8 +94,8 @@ protected void beforeTest() { .disableAutoComplete() .buildAsyncClient()); - receiverSync = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder receiverSyncBuilder = getBuilder(); + receiverSync = toClose(receiverSyncBuilder .clientOptions(clientOptions) .receiver() .queueName(getQueueName(0)) @@ -190,15 +190,15 @@ public void receiveAndRenewSessionLockWithDuration() throws InterruptedException .setSessionId(sessionId); OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), getSessionQueueName(0)); - sender = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder senderBuilder = getBuilder(); + sender = toClose(senderBuilder .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) .sender() .queueName(getSessionQueueName(0)) .buildAsyncClient()); - ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder receiverBuilder = getBuilder(); + ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(receiverBuilder .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) .sessionReceiver() .disableAutoComplete() @@ -287,8 +287,8 @@ public void sendAndReceiveParallelNoAutoCompleteAndLockRenewal() throws Interrup CountDownLatch processedFound = new CountDownLatch(messageCount); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder receiverBuilder = getBuilder(); + ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(receiverBuilder .clientOptions(clientOptions) .receiver() .queueName(getQueueName(0)) @@ -348,8 +348,8 @@ public void sendAndReceiveParallelAutoComplete() throws InterruptedException { CountDownLatch processedFound = new CountDownLatch(messageCount); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder receiverBuilder = getBuilder(); + ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(receiverBuilder .clientOptions(clientOptions) .receiver() .queueName(getQueueName(0)) @@ -548,8 +548,8 @@ public void sendAndProcessNoAutoComplete() throws InterruptedException { AtomicReference currentInProcess = new AtomicReference<>(); AtomicReference receivedMessage = new AtomicReference<>(); - processor = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder processorBuilder = getBuilder(); + processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() .queueName(getQueueName(0)) @@ -600,8 +600,8 @@ public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), sessionQueueName); clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); - sender = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder senderBuilder = getBuilder(); + sender = toClose(senderBuilder .clientOptions(clientOptions) .sender() .queueName(sessionQueueName) @@ -614,8 +614,8 @@ public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { AtomicReference currentInProcess = new AtomicReference<>(); AtomicReference receivedMessage = new AtomicReference<>(); - processor = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder processorBuilder = getBuilder(); + processor = toClose(processorBuilder .clientOptions(clientOptions) .sessionProcessor() .maxConcurrentSessions(1) @@ -668,8 +668,8 @@ public void sendAndProcessParallel() throws InterruptedException { CountDownLatch processedFound = new CountDownLatch(messageCount * 2); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); - processor = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder processorBuilder = getBuilder(); + processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() .queueName(getQueueName(0)) @@ -710,8 +710,8 @@ public void sendAndProcessParallelNoAutoComplete() throws InterruptedException { CountDownLatch processedFound = new CountDownLatch(messageCount); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - processor = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder processorBuilder = getBuilder(); + processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() .queueName(getQueueName(0)) @@ -753,8 +753,8 @@ public void sendProcessAndFail() throws InterruptedException { "ServiceBus.process".equals(span.getName()) && span.getParentSpanContext().getSpanId().equals(message1SpanId)); AtomicReference receivedMessage = new AtomicReference<>(); - processor = toClose(new ServiceBusClientBuilder() - .connectionString(getConnectionString()) + final ServiceBusClientBuilder processorBuilder = getBuilder(); + processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() .queueName(getQueueName(0)) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index a64d6ac584d1..98bb1a2989f2 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus.administration; -import com.azure.core.credential.AccessToken; import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; @@ -14,11 +13,14 @@ import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; import com.azure.core.http.policy.HttpLogDetailLevel; import com.azure.core.http.policy.HttpLogOptions; +import com.azure.core.test.InterceptorManager; import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.models.CustomMatcher; import com.azure.core.test.models.TestProxyRequestMatcher; import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; +import com.azure.core.test.utils.MockTokenCredential; +import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -115,13 +117,7 @@ public static Stream createHttpClients() { void azureIdentityCredentials(HttpClient httpClient) { final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - final TokenCredential tokenCredential; - if (interceptorManager.isPlaybackMode()) { - tokenCredential = request -> Mono.fromCallable(() -> - new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); - } else { - tokenCredential = new DefaultAzureCredentialBuilder().build(); - } + final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); @@ -1212,13 +1208,9 @@ void updateRuleResponse(HttpClient httpClient) { } private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { - final String connectionString = interceptorManager.isPlaybackMode() - ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" - : TestUtils.getConnectionString(false); - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .connectionString(connectionString); + .credential(getTestTokenCredential(interceptorManager)); if (interceptorManager.isPlaybackMode()) { builder.httpClient(interceptorManager.getPlaybackClient()); @@ -1235,4 +1227,20 @@ private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) return builder.buildAsyncClient(); } + + /** + * Retrieve the appropriate TokenCredential based on the test mode. + * + * @param interceptorManager the interceptor manager + * @return The appropriate token credential + */ + private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { + if (interceptorManager.isLiveMode()) { + return new AzurePowerShellCredentialBuilder().build(); + } else if (interceptorManager.isRecordMode()) { + return new DefaultAzureCredentialBuilder().build(); + } else { + return new MockTokenCredential(); + } + } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 021dea3c418a..fd6dfb9548f7 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus.administration; -import com.azure.core.credential.AccessToken; import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; @@ -15,8 +14,11 @@ import com.azure.core.http.policy.RetryOptions; import com.azure.core.http.rest.PagedIterable; import com.azure.core.http.rest.Response; +import com.azure.core.test.InterceptorManager; import com.azure.core.test.TestProxyTestBase; +import com.azure.core.test.utils.MockTokenCredential; import com.azure.core.util.Context; +import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -44,7 +46,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import reactor.core.publisher.Mono; import java.time.Clock; import java.time.Duration; @@ -58,7 +59,6 @@ import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; -import static com.azure.messaging.servicebus.TestUtils.getFullyQualifiedDomainName; import static com.azure.messaging.servicebus.TestUtils.getQueueBaseName; import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; @@ -89,13 +89,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest void azureIdentityCredentials() { // Arrange final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - final TokenCredential tokenCredential; - if (interceptorManager.isPlaybackMode()) { - tokenCredential = request -> Mono.fromCallable(() -> - new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); - } else { - tokenCredential = new DefaultAzureCredentialBuilder().build(); - } + final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); @@ -932,13 +926,9 @@ void listRules() { //endregion private ServiceBusAdministrationClient getClient() { - final String connectionString = interceptorManager.isPlaybackMode() - ? "Endpoint=sb://" + getFullyQualifiedDomainName() + ";SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" - : TestUtils.getConnectionString(false); - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .connectionString(connectionString) + .credential(getTestTokenCredential(interceptorManager)) .retryOptions(new RetryOptions(new FixedDelayOptions(1, TIMEOUT))); if (interceptorManager.isPlaybackMode()) { @@ -954,4 +944,20 @@ private ServiceBusAdministrationClient getClient() { return builder.buildClient(); } + + /** + * Retrieve the appropriate TokenCredential based on the test mode. + * + * @param interceptorManager the interceptor manager + * @return The appropriate token credential + */ + private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { + if (interceptorManager.isLiveMode()) { + return new AzurePowerShellCredentialBuilder().build(); + } else if (interceptorManager.isRecordMode()) { + return new DefaultAzureCredentialBuilder().build(); + } else { + return new MockTokenCredential(); + } + } } diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index c30d4ef9dfee..cf3fe3c25a60 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -35,12 +35,6 @@ "description": "The application client id used to run tests." } }, - "testApplicationSecret": { - "type": "string", - "metadata": { - "description": "The application client secret used to run tests." - } - }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", @@ -227,10 +221,6 @@ "type": "string", "value": "[parameters('testApplicationId')]" }, - "AZURE_CLIENT_SECRET": { - "type": "string", - "value": "[parameters('testApplicationSecret')]" - }, "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME": { "type": "string", "value": "[concat(variables('namespaceName'), parameters('serviceBusEndpointSuffix'))]" diff --git a/sdk/servicebus/tests.yml b/sdk/servicebus/tests.yml index 255795fc2aae..74e5e7b206e7 100644 --- a/sdk/servicebus/tests.yml +++ b/sdk/servicebus/tests.yml @@ -3,12 +3,17 @@ trigger: none extends: template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml parameters: + UseFederatedAuth: true ServiceDirectory: servicebus - Artifacts: - - name: azure-messaging-servicebus - groupId: com.azure - safeName: azuremessagingservicebus - SupportedClouds: 'Public,UsGov,China' + TestResourceDirectories: + - servicebus + SupportedClouds: 'Public' + CloudConfig: + Public: + ServiceConnection: azure-sdk-tests + SubscriptionConfigurationFilePaths: + - eng/common/TestResources/sub-config/AzurePublicMsft.json + SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources) EnvVars: AZURE_LOG_LEVEL: 1 AZURE_CLIENT_ID: $(SERVICEBUS_CLIENT_ID) @@ -20,3 +25,7 @@ extends: Path: sdk/servicebus/version-overrides-matrix.json Selection: all GenerateVMJobs: true + Artifacts: + - name: azure-messaging-servicebus + groupId: com.azure + safeName: azuremessagingservicebus From b1844f8817946f5a6423241eb7ed927084b9b1aa Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 30 Jun 2024 22:51:04 -0700 Subject: [PATCH 02/29] verify some --- .../servicebus/ProxyReceiveTest.java | 241 +- .../servicebus/ProxySelectorTest.java | 175 +- .../messaging/servicebus/ProxySendTest.java | 194 +- .../ServiceBusClientBuilderTest.java | 796 ++--- .../ServiceBusMixClientIntegrationTest.java | 963 +++--- ...viceBusProcessorClientIntegrationTest.java | 411 +-- ...BusReceiverAsyncClientIntegrationTest.java | 2865 +++++++++-------- ...rviceBusReceiverClientIntegrationTest.java | 1786 +++++----- ...ceBusSenderAsyncClientIntegrationTest.java | 1102 +++---- ...ServiceBusSenderClientIntegrationTest.java | 408 +-- ...rviceBusSessionManagerIntegrationTest.java | 424 +-- .../servicebus/TracingIntegrationTests.java | 1973 ++++++------ ...inistrationAsyncClientIntegrationTest.java | 2449 +++++++------- ...usAdministrationClientIntegrationTest.java | 1655 +++++----- sdk/servicebus/test-resources.json | 24 - 15 files changed, 7781 insertions(+), 7685 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index adf71ac5e16c..fb606440490b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -3,123 +3,128 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.AzurePowerShellCredentialBuilder; -import com.azure.messaging.servicebus.jproxy.ProxyServer; -import com.azure.messaging.servicebus.jproxy.SimpleProxy; -import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -import org.apache.qpid.proton.engine.SslDomain; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.test.StepVerifier; +public class ProxyReceiveTest { -import java.io.IOException; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.SocketAddress; -import java.net.URI; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -/** - * Verify we can use jproxy hosted locally to receive messages. - */ -public class ProxyReceiveTest extends IntegrationTestBase { - private static final int PROXY_PORT = 9102; - private static final int NUMBER_OF_EVENTS = 10; - - private static ProxyServer proxyServer; - private static ProxySelector defaultProxySelector; - - public ProxyReceiveTest() { - super(new ClientLogger(ProxyReceiveTest.class)); - } - - @BeforeEach - public void setup() throws IOException { - proxyServer = new SimpleProxy(PROXY_PORT); - proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); - - defaultProxySelector = ProxySelector.getDefault(); - ProxySelector.setDefault(new ProxySelector() { - @Override - public List select(URI uri) { - List proxies = new ArrayList<>(); - proxies.add(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); - return proxies; - } - - @Override - public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { - // no-op - } - }); - } - - @AfterEach() - public void cleanup() throws Exception { - if (proxyServer != null) { - proxyServer.stop(); - } - - ProxySelector.setDefault(defaultProxySelector); - } - - @Test - public void receiveMessage() { - // Arrange - final String queueName = getQueueName(0); - - Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); - - final String messageTracking = UUID.randomUUID().toString(); - - final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageTracking); - final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() - .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) - .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) - .credential(new AzurePowerShellCredentialBuilder().build()) - .sender() - .queueName(queueName) - .buildAsyncClient(); - - toClose(sender); - - final ServiceBusReceiverAsyncClient receiver = new ServiceBusClientBuilder() - .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) - .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) - .credential(new AzurePowerShellCredentialBuilder().build()) - .receiver() - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .queueName(queueName) - .buildAsyncClient(); - - toClose(receiver); - - // Act & Assert - try { - StepVerifier.create(sender.createMessageBatch() - .flatMap(batch -> { - for (int i = 0; i < messages.size(); i++) { - Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); - } - - return sender.sendMessages(batch); - })) - .expectComplete() - .verify(Duration.ofSeconds(30)); - - StepVerifier.create(receiver.receiveMessages().take(NUMBER_OF_EVENTS)) - .expectNextCount(NUMBER_OF_EVENTS) - .expectComplete() - .verify(TIMEOUT); - } finally { - dispose(sender, receiver); - } - } } + +// +//import com.azure.core.amqp.AmqpTransportType; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.identity.AzurePowerShellCredentialBuilder; +//import com.azure.messaging.servicebus.jproxy.ProxyServer; +//import com.azure.messaging.servicebus.jproxy.SimpleProxy; +//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +//import org.apache.qpid.proton.engine.SslDomain; +//import org.junit.jupiter.api.AfterEach; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +//import reactor.test.StepVerifier; +// +//import java.io.IOException; +//import java.net.Proxy; +//import java.net.ProxySelector; +//import java.net.SocketAddress; +//import java.net.URI; +//import java.time.Duration; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.UUID; +// +///** +// * Verify we can use jproxy hosted locally to receive messages. +// */ +//public class ProxyReceiveTest extends IntegrationTestBase { +// private static final int PROXY_PORT = 9102; +// private static final int NUMBER_OF_EVENTS = 10; +// +// private static ProxyServer proxyServer; +// private static ProxySelector defaultProxySelector; +// +// public ProxyReceiveTest() { +// super(new ClientLogger(ProxyReceiveTest.class)); +// } +// +// @BeforeEach +// public void setup() throws IOException { +// proxyServer = new SimpleProxy(PROXY_PORT); +// proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); +// +// defaultProxySelector = ProxySelector.getDefault(); +// ProxySelector.setDefault(new ProxySelector() { +// @Override +// public List select(URI uri) { +// List proxies = new ArrayList<>(); +// proxies.add(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); +// return proxies; +// } +// +// @Override +// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { +// // no-op +// } +// }); +// } +// +// @AfterEach() +// public void cleanup() throws Exception { +// if (proxyServer != null) { +// proxyServer.stop(); +// } +// +// ProxySelector.setDefault(defaultProxySelector); +// } +// +// @Test +// public void receiveMessage() { +// // Arrange +// final String queueName = getQueueName(0); +// +// Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); +// +// final String messageTracking = UUID.randomUUID().toString(); +// +// final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageTracking); +// final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() +// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) +// .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) +// .credential(new AzurePowerShellCredentialBuilder().build()) +// .sender() +// .queueName(queueName) +// .buildAsyncClient(); +// +// toClose(sender); +// +// final ServiceBusReceiverAsyncClient receiver = new ServiceBusClientBuilder() +// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) +// .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) +// .credential(new AzurePowerShellCredentialBuilder().build()) +// .receiver() +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .queueName(queueName) +// .buildAsyncClient(); +// +// toClose(receiver); +// +// // Act & Assert +// try { +// StepVerifier.create(sender.createMessageBatch() +// .flatMap(batch -> { +// for (int i = 0; i < messages.size(); i++) { +// Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); +// } +// +// return sender.sendMessages(batch); +// })) +// .expectComplete() +// .verify(Duration.ofSeconds(30)); +// +// StepVerifier.create(receiver.receiveMessages().take(NUMBER_OF_EVENTS)) +// .expectNextCount(NUMBER_OF_EVENTS) +// .expectComplete() +// .verify(TIMEOUT); +// } finally { +// dispose(sender, receiver); +// } +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java index dc1587238f21..95211553f56b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java @@ -3,90 +3,95 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.AmqpRetryOptions; -import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.util.BinaryData; -import com.azure.core.util.logging.ClientLogger; -import com.azure.core.util.logging.LogLevel; -import com.azure.identity.AzurePowerShellCredentialBuilder; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import reactor.test.StepVerifier; +public class ProxySelectorTest { -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.SocketAddress; -import java.net.URI; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -public class ProxySelectorTest extends IntegrationTestBase { - private static final ClientLogger LOGGER = new ClientLogger(ProxySelectorTest.class); - - private static final int PROXY_PORT = 9002; - private static final InetSocketAddress SIMPLE_PROXY_ADDRESS = new InetSocketAddress("localhost", PROXY_PORT); - private ProxySelector defaultProxySelector; - - public ProxySelectorTest() { - super(new ClientLogger(ProxySelectorTest.class)); - } - - @Override - public void beforeTest() { - defaultProxySelector = ProxySelector.getDefault(); - } - - @Override - public void afterTest() { - ProxySelector.setDefault(defaultProxySelector); - } - - @Disabled("Fix when proxy error is propagated back up to receiver.") - @Test - public void proxySelectorConnectFailedInvokeTest() throws InterruptedException { - final String queueName = getQueueName(9); - - Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); - - // doesn't start proxy server and verifies that the connectFailed callback is invoked. - final CountDownLatch countDownLatch = new CountDownLatch(1); - ProxySelector.setDefault(new ProxySelector() { - @Override - public List select(URI uri) { - return Collections.singletonList(new Proxy(Proxy.Type.HTTP, SIMPLE_PROXY_ADDRESS)); - } - - @Override - public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { - countDownLatch.countDown(); - } - }); - - final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); - final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() - .credential(new AzurePowerShellCredentialBuilder().build()) - .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) - .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) - .sender() - .queueName(queueName) - .buildAsyncClient(); - - toClose(sender); - StepVerifier.create(sender.sendMessage(message)) - .expectErrorSatisfies(error -> { - // The message can vary because it is returned from proton-j, so we don't want to compare against that. - // This is a transient error from ExceptionUtil.java: line 67. - LOGGER.log(LogLevel.VERBOSE, () -> "Error", error); - }) - .verify(TIMEOUT); - - final boolean awaited = countDownLatch.await(2, TimeUnit.SECONDS); - Assertions.assertTrue(awaited); - } } + +// +//import com.azure.core.amqp.AmqpRetryOptions; +//import com.azure.core.amqp.AmqpTransportType; +//import com.azure.core.util.BinaryData; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.core.util.logging.LogLevel; +//import com.azure.identity.AzurePowerShellCredentialBuilder; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.Disabled; +//import org.junit.jupiter.api.Test; +//import reactor.test.StepVerifier; +// +//import java.io.IOException; +//import java.net.InetSocketAddress; +//import java.net.Proxy; +//import java.net.ProxySelector; +//import java.net.SocketAddress; +//import java.net.URI; +//import java.time.Duration; +//import java.util.Collections; +//import java.util.List; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.TimeUnit; +// +//public class ProxySelectorTest extends IntegrationTestBase { +// private static final ClientLogger LOGGER = new ClientLogger(ProxySelectorTest.class); +// +// private static final int PROXY_PORT = 9002; +// private static final InetSocketAddress SIMPLE_PROXY_ADDRESS = new InetSocketAddress("localhost", PROXY_PORT); +// private ProxySelector defaultProxySelector; +// +// public ProxySelectorTest() { +// super(new ClientLogger(ProxySelectorTest.class)); +// } +// +// @Override +// public void beforeTest() { +// defaultProxySelector = ProxySelector.getDefault(); +// } +// +// @Override +// public void afterTest() { +// ProxySelector.setDefault(defaultProxySelector); +// } +// +// @Disabled("Fix when proxy error is propagated back up to receiver.") +// @Test +// public void proxySelectorConnectFailedInvokeTest() throws InterruptedException { +// final String queueName = getQueueName(9); +// +// Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); +// +// // doesn't start proxy server and verifies that the connectFailed callback is invoked. +// final CountDownLatch countDownLatch = new CountDownLatch(1); +// ProxySelector.setDefault(new ProxySelector() { +// @Override +// public List select(URI uri) { +// return Collections.singletonList(new Proxy(Proxy.Type.HTTP, SIMPLE_PROXY_ADDRESS)); +// } +// +// @Override +// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { +// countDownLatch.countDown(); +// } +// }); +// +// final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); +// final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() +// .credential(new AzurePowerShellCredentialBuilder().build()) +// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) +// .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) +// .sender() +// .queueName(queueName) +// .buildAsyncClient(); +// +// toClose(sender); +// StepVerifier.create(sender.sendMessage(message)) +// .expectErrorSatisfies(error -> { +// // The message can vary because it is returned from proton-j, so we don't want to compare against that. +// // This is a transient error from ExceptionUtil.java: line 67. +// LOGGER.log(LogLevel.VERBOSE, () -> "Error", error); +// }) +// .verify(TIMEOUT); +// +// final boolean awaited = countDownLatch.await(2, TimeUnit.SECONDS); +// Assertions.assertTrue(awaited); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index 104d55dac5fa..8b4c53e374a8 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -3,100 +3,104 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.AmqpRetryOptions; -import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.AzurePowerShellCredentialBuilder; -import com.azure.messaging.servicebus.jproxy.ProxyServer; -import com.azure.messaging.servicebus.jproxy.SimpleProxy; -import org.apache.qpid.proton.engine.SslDomain; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.test.StepVerifier; +public class ProxySendTest { -import java.io.IOException; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.SocketAddress; -import java.net.URI; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -public class ProxySendTest extends IntegrationTestBase { - private static final int PROXY_PORT = 9101; - private static final int NUMBER_OF_EVENTS = 10; - - private static ProxyServer proxyServer; - private static ProxySelector defaultProxySelector; - - public ProxySendTest() { - super(new ClientLogger(ProxySendTest.class)); - } - - @BeforeEach - public void initialize() throws Exception { - proxyServer = new SimpleProxy(PROXY_PORT); - proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); - - defaultProxySelector = ProxySelector.getDefault(); - ProxySelector.setDefault(new ProxySelector() { - @Override - public List select(URI uri) { - return Collections.singletonList(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); - } - - @Override - public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { - // no-op - } - }); - } - - @AfterEach - public void cleanup() throws Exception { - ProxySelector.setDefault(defaultProxySelector); - - if (proxyServer != null) { - proxyServer.stop(); - } - } - - /** - * Verifies that we can send some number of events. - */ - @Test - public void sendEvents() { - // Arrange - final String queueName = getQueueName(TestUtils.USE_CASE_PROXY); - - Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); - - final String messageId = UUID.randomUUID().toString(); - - final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); - final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() - .credential(new AzurePowerShellCredentialBuilder().build()) - .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) - .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) - .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) - .sender() - .queueName(queueName) - .buildAsyncClient(); - toClose(sender); - // Act & Assert - StepVerifier.create(sender.createMessageBatch() - .flatMap(batch -> { - for (int i = 0; i < messages.size(); i++) { - Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); - } - - return sender.sendMessages(batch); - })) - .expectComplete() - .verify(Duration.ofSeconds(30)); - } } + +//import com.azure.core.amqp.AmqpRetryOptions; +//import com.azure.core.amqp.AmqpTransportType; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.identity.AzurePowerShellCredentialBuilder; +//import com.azure.messaging.servicebus.jproxy.ProxyServer; +//import com.azure.messaging.servicebus.jproxy.SimpleProxy; +//import org.apache.qpid.proton.engine.SslDomain; +//import org.junit.jupiter.api.AfterEach; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.Test; +//import reactor.test.StepVerifier; +// +//import java.io.IOException; +//import java.net.Proxy; +//import java.net.ProxySelector; +//import java.net.SocketAddress; +//import java.net.URI; +//import java.time.Duration; +//import java.util.Collections; +//import java.util.List; +//import java.util.UUID; +// +//public class ProxySendTest extends IntegrationTestBase { +// private static final int PROXY_PORT = 9101; +// private static final int NUMBER_OF_EVENTS = 10; +// +// private static ProxyServer proxyServer; +// private static ProxySelector defaultProxySelector; +// +// public ProxySendTest() { +// super(new ClientLogger(ProxySendTest.class)); +// } +// +// @BeforeEach +// public void initialize() throws Exception { +// proxyServer = new SimpleProxy(PROXY_PORT); +// proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); +// +// defaultProxySelector = ProxySelector.getDefault(); +// ProxySelector.setDefault(new ProxySelector() { +// @Override +// public List select(URI uri) { +// return Collections.singletonList(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); +// } +// +// @Override +// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { +// // no-op +// } +// }); +// } +// +// @AfterEach +// public void cleanup() throws Exception { +// ProxySelector.setDefault(defaultProxySelector); +// +// if (proxyServer != null) { +// proxyServer.stop(); +// } +// } +// +// /** +// * Verifies that we can send some number of events. +// */ +// @Test +// public void sendEvents() { +// // Arrange +// final String queueName = getQueueName(TestUtils.USE_CASE_PROXY); +// +// Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); +// +// final String messageId = UUID.randomUUID().toString(); +// +// final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); +// final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() +// .credential(new AzurePowerShellCredentialBuilder().build()) +// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) +// .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) +// .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) +// .sender() +// .queueName(queueName) +// .buildAsyncClient(); +// toClose(sender); +// // Act & Assert +// StepVerifier.create(sender.createMessageBatch() +// .flatMap(batch -> { +// for (int i = 0; i < messages.size(); i++) { +// Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); +// } +// +// return sender.sendMessages(batch); +// })) +// .expectComplete() +// .verify(Duration.ofSeconds(30)); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index 4b3ae1225e05..a4d33a0e4afa 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -3,401 +3,405 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.amqp.ProxyAuthenticationType; -import com.azure.core.amqp.ProxyOptions; -import com.azure.core.amqp.implementation.ConnectionStringProperties; -import com.azure.core.credential.AzureNamedKeyCredential; -import com.azure.core.credential.AzureSasCredential; -import com.azure.core.util.Configuration; -import com.azure.core.util.CoreUtils; -import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; -import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; -import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -import com.azure.messaging.servicebus.models.SubQueue; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.test.StepVerifier; - -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Locale; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import static java.nio.charset.StandardCharsets.UTF_8; - -class ServiceBusClientBuilderTest extends IntegrationTestBase { - private static final String NAMESPACE_NAME = "dummyNamespaceName"; - private static final String DEFAULT_DOMAIN_NAME = TestUtils.getEndpoint().substring(1) + "/"; - private static final String ENDPOINT_FORMAT = "sb://%s.%s"; - private static final String QUEUE_NAME = "test-queue-name"; - private static final String VIA_QUEUE_NAME = "test-via-queue-name"; - private static final String TOPIC_NAME = "test-topic-name"; - private static final String VIA_TOPIC_NAME = "test-via-queue-name"; - private static final String SHARED_ACCESS_KEY_NAME = "dummySasKeyName"; - private static final String SHARED_ACCESS_KEY = "dummySasKey"; - private static final String ENDPOINT = getUri(ENDPOINT_FORMAT, NAMESPACE_NAME, DEFAULT_DOMAIN_NAME).toString(); - private static final String DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$deadletterqueue"; - private static final String TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$Transfer/$deadletterqueue"; - private static final String JAVA_NET_USER_SYSTEM_PROXIES = "java.net.useSystemProxies"; - - private static final String PROXY_HOST = "127.0.0.1"; - private static final String PROXY_PORT = "3128"; - - private static final String NAMESPACE_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s", - ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY); - private static final String ENTITY_PATH_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s", - ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY, QUEUE_NAME); - private static final Proxy PROXY_ADDRESS = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, Integer.parseInt(PROXY_PORT))); - - private static final String TEST_MESSAGE = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \nUt sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \nAenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \nAenean fringilla quam elit, id mattis purus vestibulum nec. Praesent porta eros in dapibus molestie. Vestibulum orci libero, tincidunt et turpis eget, condimentum lobortis enim. Fusce suscipit ante et mauris consequat cursus nec laoreet lorem. Maecenas in sollicitudin diam, non tincidunt purus. Nunc mauris purus, laoreet eget interdum vitae, placerat a sapien. In mi risus, blandit eu facilisis nec, molestie suscipit leo. Pellentesque molestie urna vitae dui faucibus bibendum. \nDonec quis ipsum ultricies, imperdiet ex vel, scelerisque eros. Ut at urna arcu. Vestibulum rutrum odio dolor, vitae cursus nunc pulvinar vel. Donec accumsan sapien in malesuada tempor. Maecenas in condimentum eros. Sed vestibulum facilisis massa a iaculis. Etiam et nibh felis. Donec maximus, sem quis vestibulum gravida, turpis risus congue dolor, pharetra tincidunt lectus nisi at velit."; - - ServiceBusClientBuilderTest() { - super(new ClientLogger(ServiceBusClientBuilderTest.class)); - } - - @Test - void ensureIdentifierString() { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - final ServiceBusSenderAsyncClient client = toClose(builder - .connectionString(NAMESPACE_CONNECTION_STRING) - .sender() - .queueName(QUEUE_NAME) - .buildAsyncClient()); - - Assertions.assertFalse(CoreUtils.isNullOrEmpty(client.getIdentifier())); - } - - @Test - void deadLetterQueueClient() { - // Arrange - final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .receiver() - .queueName(QUEUE_NAME) - .subQueue(SubQueue.DEAD_LETTER_QUEUE); - - - // Act - final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); - - // Assert - assertTrue(client.getEntityPath().endsWith(DEAD_LETTER_QUEUE_NAME_SUFFIX)); - } - - @Test - void transferDeadLetterqueueClient() { - // Arrange - final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .receiver() - .queueName(QUEUE_NAME) - .subQueue(SubQueue.TRANSFER_DEAD_LETTER_QUEUE); - - // Act - final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); - - // Assert - assertTrue(client.getEntityPath().endsWith(TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX)); - } - - @Test - void missingConnectionString() { - assertThrows(IllegalArgumentException.class, () -> { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - builder.sender() - .queueName(QUEUE_NAME) - .buildAsyncClient(); - }); - } - - @Test - void defaultProxyConfigurationBuilder() { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - final ServiceBusSenderAsyncClient client = builder.connectionString(NAMESPACE_CONNECTION_STRING) - .sender() - .queueName(QUEUE_NAME) - .buildAsyncClient(); - - assertNotNull(client); - } - - @Test - void customNoneProxyConfigurationBuilder() { - // Arrange - final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.NONE, PROXY_ADDRESS, - null, null); - - // Act - final ServiceBusSenderClientBuilder builder = new ServiceBusClientBuilder() - .connectionString(ENTITY_PATH_CONNECTION_STRING) - .proxyOptions(proxyConfig) - .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) - .sender(); - - // Assert - assertNotNull(builder.buildAsyncClient()); - } - - @Test - void throwsWithProxyWhenTransportTypeNotChanged() { - assertThrows(IllegalArgumentException.class, () -> { - // Arrange - final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.BASIC, PROXY_ADDRESS, - null, null); - - // Act - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder() - .connectionString(ENTITY_PATH_CONNECTION_STRING) - .proxyOptions(proxyConfig); - - // Assert - assertNotNull(builder.sender().buildAsyncClient()); - }); - } - - private static Stream invalidEntityPathConfigurations() { - return Stream.of( - // When no queue or topic name is set for a sender or receiver. - Arguments.of(NAMESPACE_CONNECTION_STRING, null, null, null), - - // When both queue or topic name is set for a sender or receiver. - Arguments.of(NAMESPACE_CONNECTION_STRING, "baz", "bar", "foo"), - - // When queue name does not match an entity path connection string. - Arguments.of(ENTITY_PATH_CONNECTION_STRING, "baz", null, null), - - // When topic name does not match an entity path connection string. - Arguments.of(ENTITY_PATH_CONNECTION_STRING, null, "bar", "foo")); - } - - /** - * Tests different invalid entity path scenarios. - */ - @ParameterizedTest - @MethodSource - void invalidEntityPathConfigurations(String connectionString, String topicName, String queueName, - String subscriptionName) { - - // Arrange - final ServiceBusSenderClientBuilder senderBuilder = new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .sender(); - final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .receiver(); - - // Act & Assert - assertThrows(IllegalStateException.class, senderBuilder::buildAsyncClient); - assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); - } - - /** - * Throws when topic name is set for receiver, but no subscription name is set. - */ - @Test - void throwsWhenSubscriptionNameNotSet() { - // Arrange - final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .receiver() - .topicName("baz"); - - // Act & Assert - assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); - } - - /** - * Throws when the prefetch is less than 1. - */ - @Test - void invalidPrefetch() { - // Arrange - final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .receiver() - .topicName("baz").subscriptionName("bar") - .receiveMode(ServiceBusReceiveMode.PEEK_LOCK); - - // Act & Assert - assertThrows(IllegalArgumentException.class, () -> receiverBuilder.prefetchCount(-1)); - } - - @MethodSource("getProxyConfigurations") - @ParameterizedTest - public void testProxyOptionsConfiguration(String proxyConfiguration) { - Configuration configuration = TestUtils.getGlobalConfiguration().clone() - .put(Configuration.PROPERTY_HTTP_PROXY, proxyConfiguration) - .put(JAVA_NET_USER_SYSTEM_PROXIES, "true"); - - // Client creation should not fail with incorrect proxy configuration - toClose(new ServiceBusClientBuilder() - .connectionString(NAMESPACE_CONNECTION_STRING) - .configuration(configuration) - .receiver() - .topicName("baz").subscriptionName("bar") - .receiveMode(ServiceBusReceiveMode.PEEK_LOCK) - .buildClient()); - } - - @Test - public void testConnectionStringWithSas() { - String connectionStringWithEntityPath = "Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;" - + "SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name"; - assertNotNull(new ServiceBusClientBuilder() - .connectionString(connectionStringWithEntityPath)); - - assertThrows(IllegalArgumentException.class, - () -> new ServiceBusClientBuilder() - .connectionString("SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name")); - - assertThrows(IllegalArgumentException.class, - () -> new ServiceBusClientBuilder() - .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); - } - - @Test - @Disabled("Convert to use AzurePowerShellCredentials?") - public void testBatchSendEventByAzureNameKeyCredential() { - ConnectionStringProperties properties = getConnectionStringProperties(); - String fullyQualifiedNamespace = getFullyQualifiedDomainName(); - String sharedAccessKeyName = properties.getSharedAccessKeyName(); - String sharedAccessKey = properties.getSharedAccessKey(); - String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); - - final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); - - ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey)) - .sender() - .queueName(queueName) - .buildAsyncClient()); - StepVerifier.create( - senderAsyncClient.createMessageBatch().flatMap(batch -> { - assertTrue(batch.tryAddMessage(testData)); - return senderAsyncClient.sendMessages(batch); - })) - .expectComplete() - .verify(TIMEOUT); - } - - @Test - @Disabled("Convert to use AzurePowerShellCredentials?") - public void testBatchSendEventByAzureSasCredential() { - ConnectionStringProperties properties = getConnectionStringProperties(true); - String fullyQualifiedNamespace = getFullyQualifiedDomainName(); - String sharedAccessSignature = properties.getSharedAccessSignature(); - String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); - - final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); - - ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, - new AzureSasCredential(sharedAccessSignature)) - .sender() - .queueName(queueName) - .buildAsyncClient()); - - StepVerifier.create( - senderAsyncClient.createMessageBatch().flatMap(batch -> { - assertTrue(batch.tryAddMessage(testData)); - return senderAsyncClient.sendMessages(batch); - })) - .expectComplete() - .verify(TIMEOUT); - } - - @Test - public void testConnectionWithAzureNameKeyCredential() { - String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); - String sharedAccessKeyName = "SharedAccessKeyName test-value"; - String sharedAccessKey = "SharedAccessKey test-value"; - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(null, - new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); - - assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() - .credential("", - new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, - new AzureNamedKeyCredential(null, sharedAccessKey))); - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, - new AzureNamedKeyCredential(sharedAccessKeyName, null))); - - assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, - new AzureNamedKeyCredential("", sharedAccessKey))); - - assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, - new AzureNamedKeyCredential(sharedAccessKeyName, ""))); - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, (AzureNamedKeyCredential) null)); - - } - - @Test - public void testConnectionWithAzureSasCredential() { - String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); - String sharedAccessSignature = "SharedAccessSignature test-value"; - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(null, new AzureSasCredential(sharedAccessSignature))); - - assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() - .credential("", new AzureSasCredential(sharedAccessSignature))); - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, new AzureSasCredential(null))); - - assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, new AzureSasCredential(""))); - - assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, (AzureSasCredential) null)); - - } - - private static Stream getProxyConfigurations() { - return Stream.of( - Arguments.of("http://localhost:8080"), - Arguments.of("localhost:8080"), - Arguments.of("localhost_8080"), - Arguments.of("http://example.com:8080"), - Arguments.of("http://sub.example.com:8080"), - Arguments.of(":8080"), - Arguments.of("http://localhost"), - Arguments.of("sub.example.com:8080"), - Arguments.of("https://username:password@sub.example.com:8080"), - Arguments.of("https://username:password@sub.example.com") - ); - - } - - private static URI getUri(String endpointFormat, String namespace, String domainName) { - try { - return new URI(String.format(Locale.US, endpointFormat, namespace, domainName)); - } catch (URISyntaxException exception) { - throw new IllegalArgumentException(String.format(Locale.US, - "Invalid namespace name: %s", namespace), exception); - } - } +class ServiceBusClientBuilderTest { } +// +//import com.azure.core.amqp.AmqpTransportType; +//import com.azure.core.amqp.ProxyAuthenticationType; +//import com.azure.core.amqp.ProxyOptions; +//import com.azure.core.amqp.implementation.ConnectionStringProperties; +//import com.azure.core.credential.AzureNamedKeyCredential; +//import com.azure.core.credential.AzureSasCredential; +//import com.azure.core.util.Configuration; +//import com.azure.core.util.CoreUtils; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; +//import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; +//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +//import com.azure.messaging.servicebus.models.SubQueue; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.Disabled; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.Arguments; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.test.StepVerifier; +// +//import java.net.InetSocketAddress; +//import java.net.Proxy; +//import java.net.URI; +//import java.net.URISyntaxException; +//import java.util.Locale; +//import java.util.stream.Stream; +// +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertThrows; +//import static org.junit.jupiter.api.Assertions.assertTrue; +// +//import static java.nio.charset.StandardCharsets.UTF_8; +// +//class ServiceBusClientBuilderTest extends IntegrationTestBase { +// private static final String NAMESPACE_NAME = "dummyNamespaceName"; +// private static final String DEFAULT_DOMAIN_NAME = TestUtils.getEndpoint().substring(1) + "/"; +// private static final String ENDPOINT_FORMAT = "sb://%s.%s"; +// private static final String QUEUE_NAME = "test-queue-name"; +// private static final String VIA_QUEUE_NAME = "test-via-queue-name"; +// private static final String TOPIC_NAME = "test-topic-name"; +// private static final String VIA_TOPIC_NAME = "test-via-queue-name"; +// private static final String SHARED_ACCESS_KEY_NAME = "dummySasKeyName"; +// private static final String SHARED_ACCESS_KEY = "dummySasKey"; +// private static final String ENDPOINT = getUri(ENDPOINT_FORMAT, NAMESPACE_NAME, DEFAULT_DOMAIN_NAME).toString(); +// private static final String DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$deadletterqueue"; +// private static final String TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$Transfer/$deadletterqueue"; +// private static final String JAVA_NET_USER_SYSTEM_PROXIES = "java.net.useSystemProxies"; +// +// private static final String PROXY_HOST = "127.0.0.1"; +// private static final String PROXY_PORT = "3128"; +// +// private static final String NAMESPACE_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s", +// ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY); +// private static final String ENTITY_PATH_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s", +// ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY, QUEUE_NAME); +// private static final Proxy PROXY_ADDRESS = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, Integer.parseInt(PROXY_PORT))); +// +// private static final String TEST_MESSAGE = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \nUt sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \nAenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \nAenean fringilla quam elit, id mattis purus vestibulum nec. Praesent porta eros in dapibus molestie. Vestibulum orci libero, tincidunt et turpis eget, condimentum lobortis enim. Fusce suscipit ante et mauris consequat cursus nec laoreet lorem. Maecenas in sollicitudin diam, non tincidunt purus. Nunc mauris purus, laoreet eget interdum vitae, placerat a sapien. In mi risus, blandit eu facilisis nec, molestie suscipit leo. Pellentesque molestie urna vitae dui faucibus bibendum. \nDonec quis ipsum ultricies, imperdiet ex vel, scelerisque eros. Ut at urna arcu. Vestibulum rutrum odio dolor, vitae cursus nunc pulvinar vel. Donec accumsan sapien in malesuada tempor. Maecenas in condimentum eros. Sed vestibulum facilisis massa a iaculis. Etiam et nibh felis. Donec maximus, sem quis vestibulum gravida, turpis risus congue dolor, pharetra tincidunt lectus nisi at velit."; +// +// ServiceBusClientBuilderTest() { +// super(new ClientLogger(ServiceBusClientBuilderTest.class)); +// } +// +// @Test +// void ensureIdentifierString() { +// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); +// final ServiceBusSenderAsyncClient client = toClose(builder +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .sender() +// .queueName(QUEUE_NAME) +// .buildAsyncClient()); +// +// Assertions.assertFalse(CoreUtils.isNullOrEmpty(client.getIdentifier())); +// } +// +// @Test +// void deadLetterQueueClient() { +// // Arrange +// final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .receiver() +// .queueName(QUEUE_NAME) +// .subQueue(SubQueue.DEAD_LETTER_QUEUE); +// +// +// // Act +// final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); +// +// // Assert +// assertTrue(client.getEntityPath().endsWith(DEAD_LETTER_QUEUE_NAME_SUFFIX)); +// } +// +// @Test +// void transferDeadLetterqueueClient() { +// // Arrange +// final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .receiver() +// .queueName(QUEUE_NAME) +// .subQueue(SubQueue.TRANSFER_DEAD_LETTER_QUEUE); +// +// // Act +// final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); +// +// // Assert +// assertTrue(client.getEntityPath().endsWith(TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX)); +// } +// +// @Test +// void missingConnectionString() { +// assertThrows(IllegalArgumentException.class, () -> { +// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); +// builder.sender() +// .queueName(QUEUE_NAME) +// .buildAsyncClient(); +// }); +// } +// +// @Test +// void defaultProxyConfigurationBuilder() { +// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); +// final ServiceBusSenderAsyncClient client = builder.connectionString(NAMESPACE_CONNECTION_STRING) +// .sender() +// .queueName(QUEUE_NAME) +// .buildAsyncClient(); +// +// assertNotNull(client); +// } +// +// @Test +// void customNoneProxyConfigurationBuilder() { +// // Arrange +// final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.NONE, PROXY_ADDRESS, +// null, null); +// +// // Act +// final ServiceBusSenderClientBuilder builder = new ServiceBusClientBuilder() +// .connectionString(ENTITY_PATH_CONNECTION_STRING) +// .proxyOptions(proxyConfig) +// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) +// .sender(); +// +// // Assert +// assertNotNull(builder.buildAsyncClient()); +// } +// +// @Test +// void throwsWithProxyWhenTransportTypeNotChanged() { +// assertThrows(IllegalArgumentException.class, () -> { +// // Arrange +// final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.BASIC, PROXY_ADDRESS, +// null, null); +// +// // Act +// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder() +// .connectionString(ENTITY_PATH_CONNECTION_STRING) +// .proxyOptions(proxyConfig); +// +// // Assert +// assertNotNull(builder.sender().buildAsyncClient()); +// }); +// } +// +// private static Stream invalidEntityPathConfigurations() { +// return Stream.of( +// // When no queue or topic name is set for a sender or receiver. +// Arguments.of(NAMESPACE_CONNECTION_STRING, null, null, null), +// +// // When both queue or topic name is set for a sender or receiver. +// Arguments.of(NAMESPACE_CONNECTION_STRING, "baz", "bar", "foo"), +// +// // When queue name does not match an entity path connection string. +// Arguments.of(ENTITY_PATH_CONNECTION_STRING, "baz", null, null), +// +// // When topic name does not match an entity path connection string. +// Arguments.of(ENTITY_PATH_CONNECTION_STRING, null, "bar", "foo")); +// } +// +// /** +// * Tests different invalid entity path scenarios. +// */ +// @ParameterizedTest +// @MethodSource +// void invalidEntityPathConfigurations(String connectionString, String topicName, String queueName, +// String subscriptionName) { +// +// // Arrange +// final ServiceBusSenderClientBuilder senderBuilder = new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .sender(); +// final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .receiver(); +// +// // Act & Assert +// assertThrows(IllegalStateException.class, senderBuilder::buildAsyncClient); +// assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); +// } +// +// /** +// * Throws when topic name is set for receiver, but no subscription name is set. +// */ +// @Test +// void throwsWhenSubscriptionNameNotSet() { +// // Arrange +// final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .receiver() +// .topicName("baz"); +// +// // Act & Assert +// assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); +// } +// +// /** +// * Throws when the prefetch is less than 1. +// */ +// @Test +// void invalidPrefetch() { +// // Arrange +// final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .receiver() +// .topicName("baz").subscriptionName("bar") +// .receiveMode(ServiceBusReceiveMode.PEEK_LOCK); +// +// // Act & Assert +// assertThrows(IllegalArgumentException.class, () -> receiverBuilder.prefetchCount(-1)); +// } +// +// @MethodSource("getProxyConfigurations") +// @ParameterizedTest +// public void testProxyOptionsConfiguration(String proxyConfiguration) { +// Configuration configuration = TestUtils.getGlobalConfiguration().clone() +// .put(Configuration.PROPERTY_HTTP_PROXY, proxyConfiguration) +// .put(JAVA_NET_USER_SYSTEM_PROXIES, "true"); +// +// // Client creation should not fail with incorrect proxy configuration +// toClose(new ServiceBusClientBuilder() +// .connectionString(NAMESPACE_CONNECTION_STRING) +// .configuration(configuration) +// .receiver() +// .topicName("baz").subscriptionName("bar") +// .receiveMode(ServiceBusReceiveMode.PEEK_LOCK) +// .buildClient()); +// } +// +// @Test +// public void testConnectionStringWithSas() { +// String connectionStringWithEntityPath = "Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;" +// + "SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name"; +// assertNotNull(new ServiceBusClientBuilder() +// .connectionString(connectionStringWithEntityPath)); +// +// assertThrows(IllegalArgumentException.class, +// () -> new ServiceBusClientBuilder() +// .connectionString("SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name")); +// +// assertThrows(IllegalArgumentException.class, +// () -> new ServiceBusClientBuilder() +// .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); +// } +// +// @Test +// @Disabled("Convert to use AzurePowerShellCredentials?") +// public void testBatchSendEventByAzureNameKeyCredential() { +// ConnectionStringProperties properties = getConnectionStringProperties(); +// String fullyQualifiedNamespace = getFullyQualifiedDomainName(); +// String sharedAccessKeyName = properties.getSharedAccessKeyName(); +// String sharedAccessKey = properties.getSharedAccessKey(); +// String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); +// +// final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); +// +// ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey)) +// .sender() +// .queueName(queueName) +// .buildAsyncClient()); +// StepVerifier.create( +// senderAsyncClient.createMessageBatch().flatMap(batch -> { +// assertTrue(batch.tryAddMessage(testData)); +// return senderAsyncClient.sendMessages(batch); +// })) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// @Test +// @Disabled("Convert to use AzurePowerShellCredentials?") +// public void testBatchSendEventByAzureSasCredential() { +// ConnectionStringProperties properties = getConnectionStringProperties(true); +// String fullyQualifiedNamespace = getFullyQualifiedDomainName(); +// String sharedAccessSignature = properties.getSharedAccessSignature(); +// String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); +// +// final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); +// +// ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, +// new AzureSasCredential(sharedAccessSignature)) +// .sender() +// .queueName(queueName) +// .buildAsyncClient()); +// +// StepVerifier.create( +// senderAsyncClient.createMessageBatch().flatMap(batch -> { +// assertTrue(batch.tryAddMessage(testData)); +// return senderAsyncClient.sendMessages(batch); +// })) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// @Test +// public void testConnectionWithAzureNameKeyCredential() { +// String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); +// String sharedAccessKeyName = "SharedAccessKeyName test-value"; +// String sharedAccessKey = "SharedAccessKey test-value"; +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(null, +// new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); +// +// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() +// .credential("", +// new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, +// new AzureNamedKeyCredential(null, sharedAccessKey))); +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, +// new AzureNamedKeyCredential(sharedAccessKeyName, null))); +// +// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, +// new AzureNamedKeyCredential("", sharedAccessKey))); +// +// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, +// new AzureNamedKeyCredential(sharedAccessKeyName, ""))); +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, (AzureNamedKeyCredential) null)); +// +// } +// +// @Test +// public void testConnectionWithAzureSasCredential() { +// String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); +// String sharedAccessSignature = "SharedAccessSignature test-value"; +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(null, new AzureSasCredential(sharedAccessSignature))); +// +// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() +// .credential("", new AzureSasCredential(sharedAccessSignature))); +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, new AzureSasCredential(null))); +// +// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, new AzureSasCredential(""))); +// +// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() +// .credential(fullyQualifiedNamespace, (AzureSasCredential) null)); +// +// } +// +// private static Stream getProxyConfigurations() { +// return Stream.of( +// Arguments.of("http://localhost:8080"), +// Arguments.of("localhost:8080"), +// Arguments.of("localhost_8080"), +// Arguments.of("http://example.com:8080"), +// Arguments.of("http://sub.example.com:8080"), +// Arguments.of(":8080"), +// Arguments.of("http://localhost"), +// Arguments.of("sub.example.com:8080"), +// Arguments.of("https://username:password@sub.example.com:8080"), +// Arguments.of("https://username:password@sub.example.com") +// ); +// +// } +// +// private static URI getUri(String endpointFormat, String namespace, String domainName) { +// try { +// return new URI(String.format(Locale.US, endpointFormat, namespace, domainName)); +// } catch (URISyntaxException exception) { +// throw new IllegalArgumentException(String.format(Locale.US, +// "Invalid namespace name: %s", namespace), exception); +// } +// } +// +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java index bf0e6bfe1f20..cb2ec6fccef9 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java @@ -3,484 +3,489 @@ package com.azure.messaging.servicebus; -import com.azure.core.util.logging.ClientLogger; -import com.azure.core.util.logging.LogLevel; -import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import com.azure.messaging.servicebus.models.CompleteOptions; -import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import reactor.core.Disposable; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +public class ServiceBusMixClientIntegrationTest { -import java.time.Duration; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Consumer; - -/** - * Test where various clients are involved for example Sender, Receiver and Processor client. - */ -public class ServiceBusMixClientIntegrationTest extends IntegrationTestBase { - private static final ClientLogger LOGGER = new ClientLogger(ServiceBusMixClientIntegrationTest.class); - - private ServiceBusSenderAsyncClient sender; - private ServiceBusReceiverAsyncClient receiver; - private final AtomicInteger messagesPending = new AtomicInteger(); - - ServiceBusMixClientIntegrationTest() { - super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); - } - - @Override - protected void beforeTest() { - sessionId = UUID.randomUUID().toString(); - } - - @Override - protected void afterTest() { - dispose(sender); - - final int numberOfMessages = messagesPending.get(); - if (numberOfMessages < 1) { - dispose(receiver); - return; - } - - try { - if (receiver == null) { - return; - } - receiver.receiveMessages() - .take(numberOfMessages) - .map(message -> { - logger.info("Message received: {}", message.getSequenceNumber()); - return message; - }) - .timeout(Duration.ofSeconds(5), Mono.empty()) - .blockLast(); - } catch (Exception e) { - logger.warning("Error occurred when draining queue.", e); - } finally { - dispose(receiver); - } - } - - /** - * Use case: Test cross entity transaction using processor client and sender. - * 1. Read messages from entity A. - * 2. complete the messages from entity A and write to entity B. - * 2. commit the transaction. - */ - @ParameterizedTest - @ValueSource(strings = {"true", "false"}) - void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { - - // Arrange - final MessagingEntityType entityType = MessagingEntityType.QUEUE; - final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; - final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; - final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); - final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); - final AtomicBoolean transactionComplete = new AtomicBoolean(); - final CountDownLatch countdownLatch = new CountDownLatch(1); - final AtomicInteger receivedMessages = new AtomicInteger(); - - final String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - message.setSessionId(sessionId); - final List messages = Arrays.asList(message); - - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); - - // Initialize sender - final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); - final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); - - Consumer processMessage = (context) -> { - receivedMessages.incrementAndGet(); - messagesPending.incrementAndGet(); - ServiceBusReceivedMessage myMessage = context.getMessage(); - LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), - myMessage.getSequenceNumber(), myMessage.getBody()); - if (receivedMessages.get() == 1) { - - //Start a transaction - ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); - context.complete(new CompleteOptions().setTransactionContext(transactionId)); - senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); - senderSyncB.commitTransaction(transactionId); - transactionComplete.set(true); - countdownLatch.countDown(); - logger.info("Transaction committed."); - } - }; - - Consumer processError = context -> { - LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", - context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); - Assertions.fail("Failed processing of message.", context.getException()); - - if (!(context.getException() instanceof ServiceBusException)) { - LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); - } - }; - - final ServiceBusProcessorClient processorA; - // Initialize processor client - if (isSessionEnabled) { - processorA = toClose(builder.sessionProcessor().disableAutoComplete().queueName(queueA) - .processMessage(processMessage).processError(processError) - .buildProcessorClient()); - } else { - processorA = toClose(builder.processor().disableAutoComplete().queueName(queueA) - .processMessage(processMessage).processError(processError) - .buildProcessorClient()); - } - - // Send messages - StepVerifier.create(senderAsyncA.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - // Create an instance of the processor through the ServiceBusClientBuilder - - // Act - LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); - processorA.start(); - toClose((AutoCloseable) () -> processorA.stop()); - - // Assert - LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); - if (countdownLatch.await(10, TimeUnit.SECONDS)) { - LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); - Assertions.assertTrue(transactionComplete.get()); - } else { - LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); - Assertions.fail("Failed to process message."); - } - - processorA.close(); - - // Verify that message is received by queue B - if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); - StepVerifier.create(receiver.receiveMessages().take(1)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } - } - - /** - * Use case: Test cross entity transaction using processor client and sender. - * 1. Read messages from entity A. - * 2. complete the messages from entity A and write to entity B. - * 2. commit the transaction. - */ - @ParameterizedTest - @ValueSource(strings = {"true", "false"}) - void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { - - // Arrange - final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; - final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; - final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; - final String topicA = getTopicName(receiveQueueAIndex); - final String topicB = getTopicName(sendQueueBIndex); - final AtomicBoolean transactionComplete = new AtomicBoolean(); - - final CountDownLatch countdownLatch = new CountDownLatch(1); - final AtomicInteger receivedMessages = new AtomicInteger(); - - final String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - message.setSessionId(sessionId); - final List messages = Arrays.asList(message); - - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); - - // Initialize sender - final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); - final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); - - Consumer processMessage = (context) -> { - receivedMessages.incrementAndGet(); - messagesPending.incrementAndGet(); - ServiceBusReceivedMessage myMessage = context.getMessage(); - LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), - myMessage.getSequenceNumber(), myMessage.getBody()); - if (receivedMessages.get() == 1) { - - //Start a transaction - ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); - context.complete(new CompleteOptions().setTransactionContext(transactionId)); - senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); - senderSyncB.commitTransaction(transactionId); - transactionComplete.set(true); - countdownLatch.countDown(); - logger.info("Transaction committed."); - } - }; - - Consumer processError = context -> { - LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", - context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); - Assertions.fail("Failed processing of message.", context.getException()); - - if (!(context.getException() instanceof ServiceBusException)) { - LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); - } - }; - - final ServiceBusProcessorClient processorA; - // Initialize processor client - if (isSessionEnabled) { - processorA = toClose(builder.sessionProcessor() - .disableAutoComplete() - .topicName(topicA) - .subscriptionName(TestUtils.getSessionSubscriptionBaseName()) - .processMessage(processMessage) - .processError(processError) - .buildProcessorClient()); - } else { - processorA = toClose(builder.processor() - .disableAutoComplete() - .topicName(topicA) - .subscriptionName(TestUtils.getSubscriptionBaseName()) - .processMessage(processMessage) - .processError(processError) - .buildProcessorClient()); - } - - // Send messages - StepVerifier.create(senderAsyncA.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - // Create an instance of the processor through the ServiceBusClientBuilder - - // Act - LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); - processorA.start(); - toClose((AutoCloseable) () -> processorA.stop()); - - // Assert - LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); - if (countdownLatch.await(10, TimeUnit.SECONDS)) { - LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); - Assertions.assertTrue(transactionComplete.get()); - } else { - LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); - Assertions.fail("Failed to process message."); - } - - processorA.close(); - - // Verify that message is received by queue B - if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); - StepVerifier.create(receiver.receiveMessages().take(1)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } - } - - /** - * Use case: Test cross entity transaction using receiver and senders. - * 1. Read messages from entity A. - * 2. complete the messages from entity A and write to entity B. - * 2. commit the transaction. - */ - @ParameterizedTest - @ValueSource(strings = {"true", "false"}) - void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { - - // Arrange - final MessagingEntityType entityType = MessagingEntityType.QUEUE; - final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; - final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; - final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); - final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); - final AtomicBoolean transactionComplete = new AtomicBoolean(); - - final CountDownLatch countdownLatch = new CountDownLatch(1); - - final String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - message.setSessionId(sessionId); - final List messages = Arrays.asList(message); - - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); - - // Initialize sender - final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); - final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); - - // Send messages - StepVerifier.create(senderAsyncA.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - - final ServiceBusReceiverAsyncClient receiverA; - - if (isSessionEnabled) { - receiverA = builder.sessionReceiver().disableAutoComplete().queueName(queueA) - .buildAsyncClient().acceptNextSession().block(); - } else { - receiverA = builder.receiver().disableAutoComplete().queueName(queueA) - .buildAsyncClient(); - } - - Disposable subscription = receiverA.receiveMessages() - .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())) - .flatMap(receivedMessage -> { - //Start a transaction - logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); - ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); - receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); - senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); - senderSyncB.commitTransaction(transactionId); - transactionComplete.set(true); - countdownLatch.countDown(); - logger.info("Transaction committed."); - return Mono.just(receivedMessage); - }).subscribe(); - toClose(subscription); - - // Act - LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); - if (countdownLatch.await(10, TimeUnit.SECONDS)) { - LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); - Assertions.assertTrue(transactionComplete.get()); - } else { - LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); - Assertions.fail("Failed to process message."); - } - - // Assert - // Verify that message is received by entity B - if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); - StepVerifier.create(receiver.receiveMessages() - .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())).take(1)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } - } - - /** - * Use case: Test cross entity transaction using receiver and senders. - * 1. Read messages from entity A. - * 2. complete the messages from entity A and write to entity B. - * 2. commit the transaction. - */ - @ParameterizedTest - @ValueSource(strings = {"true", "false"}) - void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { - - // Arrange - final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; - final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; - final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; - final String topicA = getTopicName(receiveQueueAIndex); - final String topicB = getTopicName(sendQueueBIndex); - final AtomicBoolean transactionComplete = new AtomicBoolean(); - - final CountDownLatch countdownLatch = new CountDownLatch(1); - - final String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - message.setSessionId(sessionId); - final List messages = Arrays.asList(message); - - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); - - // Initialize sender - final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); - final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); - - - // Send messages - StepVerifier.create(senderAsyncA.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - - final ServiceBusReceiverAsyncClient receiverA; - - if (isSessionEnabled) { - receiverA = builder.sessionReceiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSessionSubscriptionBaseName()) - .buildAsyncClient().acceptNextSession().block(); - } else { - receiverA = builder.receiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSubscriptionBaseName()) - .buildAsyncClient(); - } - - Disposable subscription = receiverA.receiveMessages().flatMap(receivedMessage -> { - //Start a transaction - logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); - ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); - receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); - senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); - senderSyncB.commitTransaction(transactionId); - transactionComplete.set(true); - countdownLatch.countDown(); - logger.info("Transaction committed."); - return Mono.just(receivedMessage); - }).subscribe(); - toClose(subscription); - // Act - LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); - if (countdownLatch.await(10, TimeUnit.SECONDS)) { - LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); - Assertions.assertTrue(transactionComplete.get()); - } else { - LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); - Assertions.fail("Failed to process message."); - } - - // Assert - // Verify that message is received by entity B - if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); - StepVerifier.create(receiver.receiveMessages().take(1)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } - } - - /** - * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. - */ - private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { - final boolean isSessionAware = false; - final boolean sharedConnection = true; - - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) - .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .disableAutoComplete() - .buildAsyncClient()); - } } + +// +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.core.util.logging.LogLevel; +//import com.azure.messaging.servicebus.implementation.MessagingEntityType; +//import com.azure.messaging.servicebus.models.CompleteOptions; +//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.ValueSource; +//import reactor.core.Disposable; +//import reactor.core.publisher.Mono; +//import reactor.test.StepVerifier; +// +//import java.time.Duration; +//import java.util.Arrays; +//import java.util.List; +//import java.util.UUID; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.TimeUnit; +//import java.util.concurrent.atomic.AtomicBoolean; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.function.Consumer; +// +///** +// * Test where various clients are involved for example Sender, Receiver and Processor client. +// */ +//public class ServiceBusMixClientIntegrationTest extends IntegrationTestBase { +// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusMixClientIntegrationTest.class); +// +// private ServiceBusSenderAsyncClient sender; +// private ServiceBusReceiverAsyncClient receiver; +// private final AtomicInteger messagesPending = new AtomicInteger(); +// +// ServiceBusMixClientIntegrationTest() { +// super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); +// } +// +// @Override +// protected void beforeTest() { +// sessionId = UUID.randomUUID().toString(); +// } +// +// @Override +// protected void afterTest() { +// dispose(sender); +// +// final int numberOfMessages = messagesPending.get(); +// if (numberOfMessages < 1) { +// dispose(receiver); +// return; +// } +// +// try { +// if (receiver == null) { +// return; +// } +// receiver.receiveMessages() +// .take(numberOfMessages) +// .map(message -> { +// logger.info("Message received: {}", message.getSequenceNumber()); +// return message; +// }) +// .timeout(Duration.ofSeconds(5), Mono.empty()) +// .blockLast(); +// } catch (Exception e) { +// logger.warning("Error occurred when draining queue.", e); +// } finally { +// dispose(receiver); +// } +// } +// +// /** +// * Use case: Test cross entity transaction using processor client and sender. +// * 1. Read messages from entity A. +// * 2. complete the messages from entity A and write to entity B. +// * 2. commit the transaction. +// */ +// @ParameterizedTest +// @ValueSource(strings = {"true", "false"}) +// void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { +// +// // Arrange +// final MessagingEntityType entityType = MessagingEntityType.QUEUE; +// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; +// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; +// final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); +// final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); +// final AtomicBoolean transactionComplete = new AtomicBoolean(); +// final CountDownLatch countdownLatch = new CountDownLatch(1); +// final AtomicInteger receivedMessages = new AtomicInteger(); +// +// final String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// message.setSessionId(sessionId); +// final List messages = Arrays.asList(message); +// +// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); +// +// // Initialize sender +// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); +// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); +// +// Consumer processMessage = (context) -> { +// receivedMessages.incrementAndGet(); +// messagesPending.incrementAndGet(); +// ServiceBusReceivedMessage myMessage = context.getMessage(); +// LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), +// myMessage.getSequenceNumber(), myMessage.getBody()); +// if (receivedMessages.get() == 1) { +// +// //Start a transaction +// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); +// context.complete(new CompleteOptions().setTransactionContext(transactionId)); +// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); +// senderSyncB.commitTransaction(transactionId); +// transactionComplete.set(true); +// countdownLatch.countDown(); +// logger.info("Transaction committed."); +// } +// }; +// +// Consumer processError = context -> { +// LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", +// context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); +// Assertions.fail("Failed processing of message.", context.getException()); +// +// if (!(context.getException() instanceof ServiceBusException)) { +// LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); +// } +// }; +// +// final ServiceBusProcessorClient processorA; +// // Initialize processor client +// if (isSessionEnabled) { +// processorA = toClose(builder.sessionProcessor().disableAutoComplete().queueName(queueA) +// .processMessage(processMessage).processError(processError) +// .buildProcessorClient()); +// } else { +// processorA = toClose(builder.processor().disableAutoComplete().queueName(queueA) +// .processMessage(processMessage).processError(processError) +// .buildProcessorClient()); +// } +// +// // Send messages +// StepVerifier.create(senderAsyncA.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// // Create an instance of the processor through the ServiceBusClientBuilder +// +// // Act +// LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); +// processorA.start(); +// toClose((AutoCloseable) () -> processorA.stop()); +// +// // Assert +// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); +// if (countdownLatch.await(10, TimeUnit.SECONDS)) { +// LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); +// Assertions.assertTrue(transactionComplete.get()); +// } else { +// LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); +// Assertions.fail("Failed to process message."); +// } +// +// processorA.close(); +// +// // Verify that message is received by queue B +// if (!isSessionEnabled) { +// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); +// StepVerifier.create(receiver.receiveMessages().take(1)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// } +// +// /** +// * Use case: Test cross entity transaction using processor client and sender. +// * 1. Read messages from entity A. +// * 2. complete the messages from entity A and write to entity B. +// * 2. commit the transaction. +// */ +// @ParameterizedTest +// @ValueSource(strings = {"true", "false"}) +// void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { +// +// // Arrange +// final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; +// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; +// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; +// final String topicA = getTopicName(receiveQueueAIndex); +// final String topicB = getTopicName(sendQueueBIndex); +// final AtomicBoolean transactionComplete = new AtomicBoolean(); +// +// final CountDownLatch countdownLatch = new CountDownLatch(1); +// final AtomicInteger receivedMessages = new AtomicInteger(); +// +// final String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// message.setSessionId(sessionId); +// final List messages = Arrays.asList(message); +// +// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); +// +// // Initialize sender +// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); +// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); +// +// Consumer processMessage = (context) -> { +// receivedMessages.incrementAndGet(); +// messagesPending.incrementAndGet(); +// ServiceBusReceivedMessage myMessage = context.getMessage(); +// LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), +// myMessage.getSequenceNumber(), myMessage.getBody()); +// if (receivedMessages.get() == 1) { +// +// //Start a transaction +// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); +// context.complete(new CompleteOptions().setTransactionContext(transactionId)); +// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); +// senderSyncB.commitTransaction(transactionId); +// transactionComplete.set(true); +// countdownLatch.countDown(); +// logger.info("Transaction committed."); +// } +// }; +// +// Consumer processError = context -> { +// LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", +// context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); +// Assertions.fail("Failed processing of message.", context.getException()); +// +// if (!(context.getException() instanceof ServiceBusException)) { +// LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); +// } +// }; +// +// final ServiceBusProcessorClient processorA; +// // Initialize processor client +// if (isSessionEnabled) { +// processorA = toClose(builder.sessionProcessor() +// .disableAutoComplete() +// .topicName(topicA) +// .subscriptionName(TestUtils.getSessionSubscriptionBaseName()) +// .processMessage(processMessage) +// .processError(processError) +// .buildProcessorClient()); +// } else { +// processorA = toClose(builder.processor() +// .disableAutoComplete() +// .topicName(topicA) +// .subscriptionName(TestUtils.getSubscriptionBaseName()) +// .processMessage(processMessage) +// .processError(processError) +// .buildProcessorClient()); +// } +// +// // Send messages +// StepVerifier.create(senderAsyncA.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// // Create an instance of the processor through the ServiceBusClientBuilder +// +// // Act +// LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); +// processorA.start(); +// toClose((AutoCloseable) () -> processorA.stop()); +// +// // Assert +// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); +// if (countdownLatch.await(10, TimeUnit.SECONDS)) { +// LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); +// Assertions.assertTrue(transactionComplete.get()); +// } else { +// LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); +// Assertions.fail("Failed to process message."); +// } +// +// processorA.close(); +// +// // Verify that message is received by queue B +// if (!isSessionEnabled) { +// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); +// StepVerifier.create(receiver.receiveMessages().take(1)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// } +// +// /** +// * Use case: Test cross entity transaction using receiver and senders. +// * 1. Read messages from entity A. +// * 2. complete the messages from entity A and write to entity B. +// * 2. commit the transaction. +// */ +// @ParameterizedTest +// @ValueSource(strings = {"true", "false"}) +// void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { +// +// // Arrange +// final MessagingEntityType entityType = MessagingEntityType.QUEUE; +// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; +// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; +// final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); +// final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); +// final AtomicBoolean transactionComplete = new AtomicBoolean(); +// +// final CountDownLatch countdownLatch = new CountDownLatch(1); +// +// final String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// message.setSessionId(sessionId); +// final List messages = Arrays.asList(message); +// +// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); +// +// // Initialize sender +// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); +// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); +// +// // Send messages +// StepVerifier.create(senderAsyncA.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// +// final ServiceBusReceiverAsyncClient receiverA; +// +// if (isSessionEnabled) { +// receiverA = builder.sessionReceiver().disableAutoComplete().queueName(queueA) +// .buildAsyncClient().acceptNextSession().block(); +// } else { +// receiverA = builder.receiver().disableAutoComplete().queueName(queueA) +// .buildAsyncClient(); +// } +// +// Disposable subscription = receiverA.receiveMessages() +// .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())) +// .flatMap(receivedMessage -> { +// //Start a transaction +// logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); +// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); +// receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); +// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); +// senderSyncB.commitTransaction(transactionId); +// transactionComplete.set(true); +// countdownLatch.countDown(); +// logger.info("Transaction committed."); +// return Mono.just(receivedMessage); +// }).subscribe(); +// toClose(subscription); +// +// // Act +// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); +// if (countdownLatch.await(10, TimeUnit.SECONDS)) { +// LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); +// Assertions.assertTrue(transactionComplete.get()); +// } else { +// LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); +// Assertions.fail("Failed to process message."); +// } +// +// // Assert +// // Verify that message is received by entity B +// if (!isSessionEnabled) { +// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); +// StepVerifier.create(receiver.receiveMessages() +// .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())).take(1)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// } +// +// /** +// * Use case: Test cross entity transaction using receiver and senders. +// * 1. Read messages from entity A. +// * 2. complete the messages from entity A and write to entity B. +// * 2. commit the transaction. +// */ +// @ParameterizedTest +// @ValueSource(strings = {"true", "false"}) +// void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { +// +// // Arrange +// final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; +// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; +// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; +// final String topicA = getTopicName(receiveQueueAIndex); +// final String topicB = getTopicName(sendQueueBIndex); +// final AtomicBoolean transactionComplete = new AtomicBoolean(); +// +// final CountDownLatch countdownLatch = new CountDownLatch(1); +// +// final String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// message.setSessionId(sessionId); +// final List messages = Arrays.asList(message); +// +// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); +// +// // Initialize sender +// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); +// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); +// +// +// // Send messages +// StepVerifier.create(senderAsyncA.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// +// final ServiceBusReceiverAsyncClient receiverA; +// +// if (isSessionEnabled) { +// receiverA = builder.sessionReceiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSessionSubscriptionBaseName()) +// .buildAsyncClient().acceptNextSession().block(); +// } else { +// receiverA = builder.receiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSubscriptionBaseName()) +// .buildAsyncClient(); +// } +// +// Disposable subscription = receiverA.receiveMessages().flatMap(receivedMessage -> { +// //Start a transaction +// logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); +// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); +// receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); +// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); +// senderSyncB.commitTransaction(transactionId); +// transactionComplete.set(true); +// countdownLatch.countDown(); +// logger.info("Transaction committed."); +// return Mono.just(receivedMessage); +// }).subscribe(); +// toClose(subscription); +// // Act +// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); +// if (countdownLatch.await(10, TimeUnit.SECONDS)) { +// LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); +// Assertions.assertTrue(transactionComplete.get()); +// } else { +// LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); +// Assertions.fail("Failed to process message."); +// } +// +// // Assert +// // Verify that message is received by entity B +// if (!isSessionEnabled) { +// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); +// StepVerifier.create(receiver.receiveMessages().take(1)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// } +// +// /** +// * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. +// */ +// private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { +// final boolean isSessionAware = false; +// final boolean sharedConnection = true; +// +// this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) +// .buildAsyncClient()); +// this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .disableAutoComplete() +// .buildAsyncClient()); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index cad23138cf20..2e254bc91a50 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -3,208 +3,213 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.AmqpRetryOptions; -import com.azure.core.util.CoreUtils; -import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Scheduler; -import reactor.core.scheduler.Schedulers; +public class ServiceBusProcessorClientIntegrationTest { -import java.time.Duration; -import java.time.OffsetTime; -import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -/** - * Tests for {@link ServiceBusProcessorClient}. - */ - -public class ServiceBusProcessorClientIntegrationTest extends IntegrationTestBase { - private static final ClientLogger LOGGER = new ClientLogger(ServiceBusProcessorClientIntegrationTest.class); - private final AtomicInteger messagesPending = new AtomicInteger(); - private final Scheduler scheduler = Schedulers.parallel(); - - @Override - protected void beforeTest() { - sessionId = CoreUtils.randomUuid().toString(); - } - - @Override - protected void afterTest() { - sharedBuilder = null; - } - - ServiceBusProcessorClientIntegrationTest() { - super(new ClientLogger(ServiceBusProcessorClientIntegrationTest.class)); - } - - /** - * Validate that processor receive the message and {@code MaxAutoLockRenewDuration} is set on the - * {@link ServiceBusReceiverAsyncClient}. The message lock is released by the client and same message received - * again. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { - // Arrange - // The message is locked for this duration at a time. - final int lockTimeoutDurationSeconds = 15; - final int entityIndex = TestUtils.USE_CASE_PROCESSOR_RECEIVE; - final Duration expectedMaxAutoLockRenew = Duration.ofSeconds(35); - - final String messageId = UUID.randomUUID().toString(); - final AtomicReference lastMessageReceivedTime = new AtomicReference<>(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled).setMessageId(messageId); - - // The message should comeback after the client release the lock once because maxAutoLockRenewDuration is set - // by user. - CountDownLatch countDownLatch = new CountDownLatch(2); - - // send the message - ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, isSessionEnabled); - sendMessage(sender, message).block(TIMEOUT); - - ServiceBusProcessorClient processor; - if (isSessionEnabled) { - assertNotNull(sessionId, "'sessionId' should have been set."); - AmqpRetryOptions amqpRetryOptions = new AmqpRetryOptions() - .setTryTimeout(Duration.ofSeconds(2 * lockTimeoutDurationSeconds)); - processor = toClose(getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, amqpRetryOptions) - .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) - .disableAutoComplete() - .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) - .processError(context -> processError(context, countDownLatch)) - .buildProcessorClient()); - - } else { - processor = toClose(getProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false) - .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) - .disableAutoComplete() - .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) - .processError(context -> processError(context, countDownLatch)) - .buildProcessorClient()); - } - - // Assert & Act - processor.start(); - toClose((AutoCloseable) () -> processor.stop()); - - assertTrue(countDownLatch.await(lockTimeoutDurationSeconds * 6, TimeUnit.SECONDS), "Message not arrived, closing processor."); - LOGGER.info("Message lock has been renewed. Now closing processor"); - } - - @ParameterizedTest - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { - final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; - final Duration sessionIdleTimeout = Duration.ofSeconds(3); - - ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); - - ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = - getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, RETRY_OPTIONS) - .sessionIdleTimeout(sessionIdleTimeout) - .disableAutoComplete(); - - rollingSessionTest(sender, processorBuilder); - } - - @ParameterizedTest - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { - final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; - final Duration tryTimeout = Duration.ofSeconds(3); - - ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); - ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = - getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, - new AmqpRetryOptions().setTryTimeout(tryTimeout)) - .disableAutoComplete(); - - rollingSessionTest(sender, processorBuilder); - } - - void rollingSessionTest(ServiceBusSenderAsyncClient sender, ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder) throws InterruptedException { - final String contents = "Some-contents"; - final String randomPrefix = UUID.randomUUID().toString(); - ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); - ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); - - CountDownLatch latch = new CountDownLatch(2); - ServiceBusProcessorClient processor = toClose(processorBuilder - .processMessage(context -> { - ServiceBusReceivedMessage received = context.getMessage(); - context.complete(); - - if (received.getMessageId().startsWith(randomPrefix)) { - latch.countDown(); - if (message0.getMessageId().equals(received.getMessageId())) { - sendMessage(sender, message1).block(); - } - } - }) - .processError(context -> fail(context.getException())) - .buildProcessorClient()); - - processor.start(); - sendMessage(sender, message0).block(); - - toClose((AutoCloseable) () -> processor.stop()); - - assertTrue(latch.await(20, TimeUnit.SECONDS), "Messages did not arrived, closing processor."); - } - - private void processMessage(ServiceBusReceivedMessageContext context, CountDownLatch countDownLatch, - String expectedMessageId, AtomicReference lastMessageReceivedTime, int lockTimeoutDurationSeconds) { - ServiceBusReceivedMessage message = context.getMessage(); - if (message.getMessageId().equals(expectedMessageId)) { - LOGGER.info("Processing message. Session: {}, Sequence #: {}. Contents: {}", message.getMessageId(), - message.getSequenceNumber(), message.getBody()); - if (lastMessageReceivedTime.get() == null) { - lastMessageReceivedTime.set(OffsetTime.now()); - countDownLatch.countDown(); - } else { - long messageReceivedAfterSeconds = Duration.between(lastMessageReceivedTime.get(), OffsetTime.now()).getSeconds(); - LOGGER.info("Processing message again. Session: {}, Sequence #: {}. Contents: {}, message received after {} seconds.", message.getMessageId(), - message.getSequenceNumber(), message.getBody(), messageReceivedAfterSeconds); - // Ensure that the lock is renewed and message is received again after atlest one lock renew - if (messageReceivedAfterSeconds >= 2 * lockTimeoutDurationSeconds) { - countDownLatch.countDown(); - } - } - } else { - LOGGER.info("Received message, message id did not match. Session: %s, Sequence #: %s. Contents: %s%n", message.getMessageId(), - message.getSequenceNumber(), message.getBody()); - } - } - - private void processError(ServiceBusErrorContext context, CountDownLatch countdownLatch) { - LOGGER.info("Error when receiving messages from namespace: {}. Entity: {}}", - context.getFullyQualifiedNamespace(), context.getEntityPath()); - } - - private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { - final boolean shareConnection = false; - return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) - .buildAsyncClient()); - } - - private Mono sendMessage(ServiceBusSenderAsyncClient sender, ServiceBusMessage message) { - return sender.sendMessage(message).doOnSuccess(aVoid -> { - logMessage(message, sender.getEntityPath(), "sent"); - int number = messagesPending.incrementAndGet(); - LOGGER.atInfo().addKeyValue("number", number).log("Number sent"); - }); - } } + +// +//import com.azure.core.amqp.AmqpRetryOptions; +//import com.azure.core.util.CoreUtils; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.messaging.servicebus.implementation.MessagingEntityType; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.core.publisher.Mono; +//import reactor.core.scheduler.Scheduler; +//import reactor.core.scheduler.Schedulers; +// +//import java.time.Duration; +//import java.time.OffsetTime; +//import java.util.UUID; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.TimeUnit; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.concurrent.atomic.AtomicReference; +// +//import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assertions.fail; +// +///** +// * Tests for {@link ServiceBusProcessorClient}. +// */ +// +//public class ServiceBusProcessorClientIntegrationTest extends IntegrationTestBase { +// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusProcessorClientIntegrationTest.class); +// private final AtomicInteger messagesPending = new AtomicInteger(); +// private final Scheduler scheduler = Schedulers.parallel(); +// +// @Override +// protected void beforeTest() { +// sessionId = CoreUtils.randomUuid().toString(); +// } +// +// @Override +// protected void afterTest() { +// sharedBuilder = null; +// } +// +// ServiceBusProcessorClientIntegrationTest() { +// super(new ClientLogger(ServiceBusProcessorClientIntegrationTest.class)); +// } +// +// /** +// * Validate that processor receive the message and {@code MaxAutoLockRenewDuration} is set on the +// * {@link ServiceBusReceiverAsyncClient}. The message lock is released by the client and same message received +// * again. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { +// // Arrange +// // The message is locked for this duration at a time. +// final int lockTimeoutDurationSeconds = 15; +// final int entityIndex = TestUtils.USE_CASE_PROCESSOR_RECEIVE; +// final Duration expectedMaxAutoLockRenew = Duration.ofSeconds(35); +// +// final String messageId = UUID.randomUUID().toString(); +// final AtomicReference lastMessageReceivedTime = new AtomicReference<>(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled).setMessageId(messageId); +// +// // The message should comeback after the client release the lock once because maxAutoLockRenewDuration is set +// // by user. +// CountDownLatch countDownLatch = new CountDownLatch(2); +// +// // send the message +// ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, isSessionEnabled); +// sendMessage(sender, message).block(TIMEOUT); +// +// ServiceBusProcessorClient processor; +// if (isSessionEnabled) { +// assertNotNull(sessionId, "'sessionId' should have been set."); +// AmqpRetryOptions amqpRetryOptions = new AmqpRetryOptions() +// .setTryTimeout(Duration.ofSeconds(2 * lockTimeoutDurationSeconds)); +// processor = toClose(getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, amqpRetryOptions) +// .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) +// .disableAutoComplete() +// .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) +// .processError(context -> processError(context, countDownLatch)) +// .buildProcessorClient()); +// +// } else { +// processor = toClose(getProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false) +// .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) +// .disableAutoComplete() +// .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) +// .processError(context -> processError(context, countDownLatch)) +// .buildProcessorClient()); +// } +// +// // Assert & Act +// processor.start(); +// toClose((AutoCloseable) () -> processor.stop()); +// +// assertTrue(countDownLatch.await(lockTimeoutDurationSeconds * 6, TimeUnit.SECONDS), "Message not arrived, closing processor."); +// LOGGER.info("Message lock has been renewed. Now closing processor"); +// } +// +// @ParameterizedTest +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { +// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; +// final Duration sessionIdleTimeout = Duration.ofSeconds(3); +// +// ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); +// +// ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = +// getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, RETRY_OPTIONS) +// .sessionIdleTimeout(sessionIdleTimeout) +// .disableAutoComplete(); +// +// rollingSessionTest(sender, processorBuilder); +// } +// +// @ParameterizedTest +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { +// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; +// final Duration tryTimeout = Duration.ofSeconds(3); +// +// ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); +// ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = +// getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, +// new AmqpRetryOptions().setTryTimeout(tryTimeout)) +// .disableAutoComplete(); +// +// rollingSessionTest(sender, processorBuilder); +// } +// +// void rollingSessionTest(ServiceBusSenderAsyncClient sender, ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder) throws InterruptedException { +// final String contents = "Some-contents"; +// final String randomPrefix = UUID.randomUUID().toString(); +// ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); +// ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); +// +// CountDownLatch latch = new CountDownLatch(2); +// ServiceBusProcessorClient processor = toClose(processorBuilder +// .processMessage(context -> { +// ServiceBusReceivedMessage received = context.getMessage(); +// context.complete(); +// +// if (received.getMessageId().startsWith(randomPrefix)) { +// latch.countDown(); +// if (message0.getMessageId().equals(received.getMessageId())) { +// sendMessage(sender, message1).block(); +// } +// } +// }) +// .processError(context -> fail(context.getException())) +// .buildProcessorClient()); +// +// processor.start(); +// sendMessage(sender, message0).block(); +// +// toClose((AutoCloseable) () -> processor.stop()); +// +// assertTrue(latch.await(20, TimeUnit.SECONDS), "Messages did not arrived, closing processor."); +// } +// +// private void processMessage(ServiceBusReceivedMessageContext context, CountDownLatch countDownLatch, +// String expectedMessageId, AtomicReference lastMessageReceivedTime, int lockTimeoutDurationSeconds) { +// ServiceBusReceivedMessage message = context.getMessage(); +// if (message.getMessageId().equals(expectedMessageId)) { +// LOGGER.info("Processing message. Session: {}, Sequence #: {}. Contents: {}", message.getMessageId(), +// message.getSequenceNumber(), message.getBody()); +// if (lastMessageReceivedTime.get() == null) { +// lastMessageReceivedTime.set(OffsetTime.now()); +// countDownLatch.countDown(); +// } else { +// long messageReceivedAfterSeconds = Duration.between(lastMessageReceivedTime.get(), OffsetTime.now()).getSeconds(); +// LOGGER.info("Processing message again. Session: {}, Sequence #: {}. Contents: {}, message received after {} seconds.", message.getMessageId(), +// message.getSequenceNumber(), message.getBody(), messageReceivedAfterSeconds); +// // Ensure that the lock is renewed and message is received again after atlest one lock renew +// if (messageReceivedAfterSeconds >= 2 * lockTimeoutDurationSeconds) { +// countDownLatch.countDown(); +// } +// } +// } else { +// LOGGER.info("Received message, message id did not match. Session: %s, Sequence #: %s. Contents: %s%n", message.getMessageId(), +// message.getSequenceNumber(), message.getBody()); +// } +// } +// +// private void processError(ServiceBusErrorContext context, CountDownLatch countdownLatch) { +// LOGGER.info("Error when receiving messages from namespace: {}. Entity: {}}", +// context.getFullyQualifiedNamespace(), context.getEntityPath()); +// } +// +// private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { +// final boolean shareConnection = false; +// return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) +// .buildAsyncClient()); +// } +// +// private Mono sendMessage(ServiceBusSenderAsyncClient sender, ServiceBusMessage message) { +// return sender.sendMessage(message).doOnSuccess(aVoid -> { +// logMessage(message, sender.getEntityPath(), "sent"); +// int number = messagesPending.incrementAndGet(); +// LOGGER.atInfo().addKeyValue("number", number).log("Number sent"); +// }); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index c80c0fbbd7bf..4804a45c7ef6 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -4,69 +4,74 @@ package com.azure.messaging.servicebus; import com.azure.core.amqp.AmqpRetryOptions; -import com.azure.core.amqp.models.AmqpAddress; -import com.azure.core.amqp.models.AmqpAnnotatedMessage; -import com.azure.core.amqp.models.AmqpMessageBody; -import com.azure.core.amqp.models.AmqpMessageBodyType; -import com.azure.core.amqp.models.AmqpMessageHeader; -import com.azure.core.amqp.models.AmqpMessageId; -import com.azure.core.amqp.models.AmqpMessageProperties; -import com.azure.core.util.CoreUtils; +//import com.azure.core.amqp.models.AmqpAddress; +//import com.azure.core.amqp.models.AmqpAnnotatedMessage; +//import com.azure.core.amqp.models.AmqpMessageBody; +//import com.azure.core.amqp.models.AmqpMessageBodyType; +//import com.azure.core.amqp.models.AmqpMessageHeader; +//import com.azure.core.amqp.models.AmqpMessageId; +//import com.azure.core.amqp.models.AmqpMessageProperties; +//import com.azure.core.util.CoreUtils; +import com.azure.core.credential.AccessToken; +import com.azure.core.credential.TokenRequestContext; import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.implementation.DispositionStatus; +//import com.azure.messaging.servicebus.implementation.DispositionStatus; +import com.azure.identity.AzurePowerShellCredential; +import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import com.azure.messaging.servicebus.models.AbandonOptions; -import com.azure.messaging.servicebus.models.CompleteOptions; -import com.azure.messaging.servicebus.models.DeadLetterOptions; -import com.azure.messaging.servicebus.models.DeferOptions; -import com.azure.messaging.servicebus.models.SubQueue; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; +//import com.azure.messaging.servicebus.models.AbandonOptions; +//import com.azure.messaging.servicebus.models.CompleteOptions; +//import com.azure.messaging.servicebus.models.DeadLetterOptions; +//import com.azure.messaging.servicebus.models.DeferOptions; +//import com.azure.messaging.servicebus.models.SubQueue; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.Disabled; +import com.azure.messaging.servicebus.implementation.ServiceBusConstants; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.EnumSource; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.core.Disposable; +//import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +//import reactor.test.StepVerifier; -import java.nio.charset.Charset; +//import java.nio.charset.Charset; import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +//import java.time.OffsetDateTime; +//import java.util.ArrayList; +//import java.util.Collections; +//import java.util.Comparator; +//import java.util.HashMap; +//import java.util.HashSet; +//import java.util.List; +//import java.util.Map; +//import java.util.Set; import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; - -import static com.azure.messaging.servicebus.TestUtils.MESSAGE_POSITION_ID; -import static com.azure.messaging.servicebus.TestUtils.USE_CASE_AUTO_COMPLETE; -import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH_MESSAGES; -import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_MESSAGE; -import static com.azure.messaging.servicebus.TestUtils.USE_CASE_RECEIVE_AND_COMPLETE; -import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessages; -import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; -import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.TimeUnit; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.concurrent.atomic.AtomicLong; +//import java.util.concurrent.atomic.AtomicReference; +//import java.util.function.Function; +// +//import static com.azure.messaging.servicebus.TestUtils.MESSAGE_POSITION_ID; +//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_AUTO_COMPLETE; +//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH_MESSAGES; +//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_MESSAGE; +//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_RECEIVE_AND_COMPLETE; +//import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessages; +//import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; +//import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; +//import static java.nio.charset.StandardCharsets.UTF_8; +//import static org.junit.jupiter.api.Assertions.assertArrayEquals; +//import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assertions.fail; /** * Integration tests for {@link ServiceBusReceiverAsyncClient} from queues or subscriptions. @@ -98,1378 +103,1408 @@ protected void afterTest() { sharedBuilder = null; } - /** + /** * Verifies that we can create multiple transaction using sender and receiver. */ @Test void createMultipleTransactionTest() { - // Arrange - setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); - - // Assert & Act - StepVerifier.create(receiver.createTransaction()) - .assertNext(Assertions::assertNotNull) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(receiver.createTransaction()) - .assertNext(Assertions::assertNotNull) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can create transaction and complete. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Assert & Act - AtomicReference transaction = new AtomicReference<>(); - StepVerifier.create(receiver.createTransaction()) - .assertNext(txn -> { - transaction.set(txn); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(receiver.receiveMessages() - .flatMap(receivedMessage -> { - logMessage(receivedMessage, receiver.getEntityPath(), "received message"); - return receiver.complete(receivedMessage) - .doOnSuccess(m -> logMessage(receivedMessage, receiver.getEntityPath(), "completed message")) - .thenReturn(receivedMessage); - }).take(1)) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(receiver.rollbackTransaction(transaction.get())) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can do following using shared connection and on non session entity. 1. create transaction 2. - * receive and settle with transactionContext. 3. commit Rollback this transaction. - */ - @ParameterizedTest - @EnumSource(DispositionStatus.class) - void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { - - // Arrange - final MessagingEntityType entityType = MessagingEntityType.QUEUE; - setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_TRANSACTION_SENDRECEIVE_AND_COMPLETE, isSessionEnabled); - - final String messageId1 = UUID.randomUUID().toString(); - final ServiceBusMessage message1 = getMessage(messageId1, isSessionEnabled); - final String deadLetterReason = "test reason"; - - sendMessage(message1).block(TIMEOUT); - - // Assert & Act - AtomicReference transaction = new AtomicReference<>(); - StepVerifier.create(receiver.createTransaction()) - .assertNext(txn -> { - transaction.set(txn); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - assertNotNull(transaction.get()); - - // Assert & Act - final ServiceBusReceivedMessage message = receiver.receiveMessages() - .flatMap(receivedMessage -> { - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - final Mono operation; - switch (dispositionStatus) { - case COMPLETED: - operation = receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get())); - logMessage(receivedMessage, receiver.getEntityPath(), "completed messages"); - break; - case ABANDONED: - operation = receiver.abandon(receivedMessage, new AbandonOptions().setTransactionContext(transaction.get())); - logMessage(receivedMessage, receiver.getEntityPath(), "abandoned messages"); - break; - case SUSPENDED: - DeadLetterOptions deadLetterOptions = new DeadLetterOptions().setTransactionContext(transaction.get()) - .setDeadLetterReason(deadLetterReason); - operation = receiver.deadLetter(receivedMessage, deadLetterOptions); - logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered messages"); - break; - case DEFERRED: - operation = receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction.get())); - logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); - break; - case RELEASED: - operation = receiver.release(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "released messages"); - break; - default: - throw LOGGER.logExceptionAsError(new IllegalArgumentException( - "Disposition status not recognized for this test case: " + dispositionStatus)); - } - return operation - .thenReturn(receivedMessage); - }) - .blockFirst(TIMEOUT); - assertNotNull(message); - - StepVerifier.create(receiver.commitTransaction(transaction.get())) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can do following on different clients i.e. sender and receiver. 1. create transaction using - * sender 2. receive and complete with transactionContext. 3. Commit this transaction using sender. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - @Disabled - void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { - // Arrange - final boolean shareConnection = true; - final int entityIndex = 0; - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) - .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) - .buildAsyncClient()); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(TIMEOUT); - - // Assert & Act - AtomicReference transaction = new AtomicReference<>(); - StepVerifier.create(sender.createTransaction()) - .assertNext(txn -> { - transaction.set(txn); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - assertNotNull(transaction.get()); - - // Assert & Act - final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); - assertNotNull(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "received message"); - StepVerifier.create(receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get()))) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(sender.commitTransaction(transaction.get())) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send and receive two messages. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int entityIndex = 0; - final boolean shareConnection = false; - final Duration shortWait = Duration.ofSeconds(3); - - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) - .buildAsyncClient()); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - Mono.when(sendMessage(message), sendMessage(message)).block(); - - // Now create receiver - if (isSessionEnabled) { - assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) - .buildAsyncClient()); - this.receiver = toClose(sessionReceiver.acceptSession(sessionId).block()); - } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) - .buildAsyncClient()); - } - - // Assert & Act - StepVerifier.create(receiver.receiveMessages() - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .thenAwait(shortWait) // Give time for autoComplete to finish - .thenCancel() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send and receive a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int entityIndex = USE_CASE_AUTO_COMPLETE; - final boolean shareConnection = false; - - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) - .buildAsyncClient()); - final String messageId = CoreUtils.randomUuid().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - StepVerifier.create(sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - - // Now create receiver - if (isSessionEnabled) { - assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) - .buildAsyncClient()); - this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); - } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) - .buildAsyncClient()); - } - - // Assert - StepVerifier.create(receiver.receiveMessages() - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) - .assertNext(receivedMessage -> { - logMessage(receivedMessage, receiver.getEntityPath(), "received message"); - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - }) - .expectNoEvent(Duration.ofSeconds(30)) - .thenCancel() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send and peek a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(); - - setReceiver(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); - - Mono peek = receiver.peekMessage() - .filter(m -> messageId.equals(m.getMessageId())) - .repeatWhenEmpty(10, i -> Flux.interval(Duration.ofSeconds(1))); - - // Assert & Act - StepVerifier.create(peek - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked and filtered message"))) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that an empty entity does not error when peeking. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); - - final int fromSequenceNumber = 1; - - // Assert & Act - StepVerifier.create(receiver.peekMessage(fromSequenceNumber) - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can schedule and receive a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); - final Duration shortDelay = Duration.ofSeconds(4); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(2); - - sender.scheduleMessage(message, scheduledEnqueueTime).block(); - - setReceiver(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); - - // Assert & Act - StepVerifier.create(Mono.delay(shortDelay).then(receiver.receiveMessages() - .filter(m -> messageId.equals(m.getMessageId())) - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) - .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).next())) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can cancel a scheduled message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); - final Duration delayDuration = Duration.ofSeconds(3); - - final Long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime).block(TIMEOUT); - logMessage(message, sender.getEntityPath(), "scheduled"); - - assertNotNull(sequenceNumber); - - Mono.delay(delayDuration) - .then(sender.cancelScheduledMessage(sequenceNumber)) - .block(TIMEOUT); - - logMessage(message, sender.getEntityPath(), "cancelled messaged with sequence number " + sequenceNumber); - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Assert & Act - StepVerifier.create(receiver.receiveMessages() - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) - .take(1)) - .thenAwait(Duration.ofSeconds(5)) - .thenCancel() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send and peek a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int entityIndex = 3; - - setSender(entityType, entityIndex, isSessionEnabled); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final CountDownLatch countDownLatch = new CountDownLatch(1); - - sendMessage(message).block(); - - setReceiver(entityType, entityIndex, isSessionEnabled); - - // Message are not always guaranteed, so try many times - final ServiceBusReceivedMessage peekMessage = receiver.peekMessage() - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) - .map(receivedMessage -> { - countDownLatch.countDown(); - return receivedMessage; - }) - .repeat(() -> countDownLatch.getCount() > 0) - .next() - .block(); - assertNotNull(peekMessage); - final long sequenceNumber = peekMessage.getSequenceNumber(); - - // Assert & Act - try { - StepVerifier.create(receiver.peekMessage(sequenceNumber) - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) - .assertNext(m -> { - assertEquals(sequenceNumber, m.getSequenceNumber()); - assertMessageEquals(m, messageId, isSessionEnabled); - }) - .expectComplete() - .verify(TIMEOUT); - } finally { - - // Cleanup - StepVerifier.create(receiver.receiveMessages() - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) - .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) - .expectNextCount(1) - .expectComplete() - .verify(TIMEOUT); - } - } - - /** - * Verifies that we can send and peek a batch of messages and the sequence number is tracked correctly. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - public void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { - // Arrange - setSender(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final List messages = getServiceBusMessages(10, messageId, CONTENTS_BYTES); - final Set receivedPositions = Collections.synchronizedSet(new HashSet<>()); - final List receivedMessages = Collections.synchronizedList(new ArrayList<>()); - - if (isSessionEnabled) { - messages.forEach(m -> m.setSessionId(sessionId)); - } - - StepVerifier.create(sender.sendMessages(messages) - .doOnSuccess(aVoid -> logMessages(messages, sender.getEntityPath(), "sent"))) - .expectComplete() - .verify(TIMEOUT); - - setReceiver(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); - - // Assert & Act - for (int i = 0; i < 5 && receivedPositions.size() < messages.size(); i++) { - peekMessages(messages.size(), messageId, receivedPositions) - .doOnNext(receivedMessage -> receivedMessages.add(receivedMessage)) - .blockLast(); - if (receivedPositions.size() < messages.size()) { - Thread.sleep(1000); - } - } - - assertEquals(receivedMessages.size(), messages.size()); - - final AtomicInteger messageCount = new AtomicInteger(); - - synchronized (receivedMessages) { - receivedMessages.stream() - .forEach(actualMessage -> { - final Object position = actualMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); - assertTrue(position instanceof Integer, "Did not contain correct position number: " + position); - - // messages are received in the same order as they were sent - assertEquals(messageCount.getAndIncrement(), position); - }); - } - } - - private Flux peekMessages(int count, String messageIdFilter, Set receivedPositions) { - return receiver.peekMessages(count) - // maxMessages are not always guaranteed, sometime, we get less than asked for, so we will try many times. - .filter(receivedMessage -> { - logMessage(receivedMessage, receiver.getEntityPath(), "peeked message"); - Integer position = (Integer) receivedMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); - boolean filtered = messageIdFilter.equals(receivedMessage.getMessageId()) && receivedPositions.add(position); - if (filtered) { - logMessage(receivedMessage, receiver.getEntityPath(), "filtered message, a few more to go"); - } - return filtered; - }); - } - - /** - * Verifies that we can send and peek a batch of messages. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void peekMessagesFromSequence(MessagingEntityType entityType) throws InterruptedException { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_MESSAGE_FROM_SEQUENCE, false); - - final AtomicInteger messageId = new AtomicInteger(); - final int maxMessages = 2; - final AtomicLong fromSequenceNumber = new AtomicLong(); - final CountDownLatch countdownLatch = new CountDownLatch(maxMessages); - fromSequenceNumber.set(1); - - final byte[] content = "peek-message-from-sequence".getBytes(Charset.defaultCharset()); - List messageIds = Collections.synchronizedList(new ArrayList<>()); - for (int i = 0; i < maxMessages; ++i) { - ServiceBusMessage message = getMessage(String.valueOf(i), isSessionEnabled, AmqpMessageBody.fromData(content)); - messageIds.add(String.valueOf(i)); - sendMessage(message).block(); - } - - // Assert & Act - - // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times - // https://github.com/Azure/azure-sdk-for-java/issues/21168 - List receivedMessages = Collections.synchronizedList(new ArrayList<>()); - Disposable subscription = receiver.peekMessages(maxMessages, fromSequenceNumber.get()) - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message")) - .filter(receivedMessage -> messageIds.contains(receivedMessage.getMessageId()) - && receivedMessages.parallelStream().noneMatch(mid -> - mid.equals(receivedMessage.getMessageId()))) - .sort(Comparator.comparing(ServiceBusReceivedMessage::getMessageId)) - .flatMap(receivedMessage -> { - Long previousSequenceNumber = fromSequenceNumber.get(); - fromSequenceNumber.set(receivedMessage.getSequenceNumber() + 1); - countdownLatch.countDown(); - receivedMessages.add(receivedMessage.getMessageId()); - assertEquals(String.valueOf(messageId.getAndIncrement()), receivedMessage.getMessageId(), - String.format("Message id did not match. Message payload: [%s], peek from Sequence Number [%s], " - + " received message Sequence Number [%s]", receivedMessage.getBody(), - previousSequenceNumber, receivedMessage.getSequenceNumber())); - return Mono.just(receivedMessage); - }) - .repeat(() -> countdownLatch.getCount() > 0) - .subscribe(); - toClose(subscription); - - assertTrue(countdownLatch.await(20, TimeUnit.SECONDS), "Failed peek messages from sequence."); - - StepVerifier.create(receiver.receiveMessages().take(maxMessages)) - .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) - .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that an empty entity does not error when peeking. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); - - final int maxMessages = 10; - final int fromSequenceNumber = 1; - - // Assert & Act - StepVerifier.create(receiver.peekMessages(maxMessages, fromSequenceNumber)) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can dead-letter a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int entityIndex = 0; - setSender(entityType, entityIndex, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(); - - setReceiver(entityType, entityIndex, isSessionEnabled); - - // Assert & Act - StepVerifier.create(receiver.receiveMessages() - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) - .flatMap(receivedMessage -> receiver.deadLetter(receivedMessage).thenReturn(receivedMessage)).take(1)) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .thenCancel() - .verify(TIMEOUT); - - } - - /** - * Verifies that we can send and receive a message AMQP Sequence andValue object. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; - final boolean shareConnection = false; - final Duration shortWait = Duration.ofSeconds(3); - final Long expectedLongValue = Long.parseLong("6"); - - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) - .buildAsyncClient()); - - // Send value Object - String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromValue(expectedLongValue)); - sendMessage(message).block(TIMEOUT); - - // send SEQUENCE - messageId = UUID.randomUUID().toString(); - - List sequenceData = new ArrayList<>(); - sequenceData.add("A1"); - sequenceData.add(1L); - sequenceData.add(2); - - message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromSequence(sequenceData)); - sendMessage(message).block(TIMEOUT); - - // Now create receiver - if (isSessionEnabled) { - assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) - .buildAsyncClient()); - this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); - } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) - .buildAsyncClient()); - } - - // Assert - StepVerifier.create(receiver.receiveMessages()) - .assertNext(receivedMessage -> { - AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); - AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); - assertEquals(AmqpMessageBodyType.VALUE, type); - Object value = amqpAnnotatedMessage.getBody().getValue(); - assertTrue(value instanceof Long); - assertEquals(expectedLongValue.longValue(), ((Long) value).longValue()); - }) - .assertNext(receivedMessage -> { - AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); - AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); - assertEquals(AmqpMessageBodyType.SEQUENCE, type); - assertArrayEquals(sequenceData.toArray(), amqpAnnotatedMessage.getBody().getSequence().toArray()); - }) - .thenAwait(shortWait) // Give time for autoComplete to finish - .thenCancel() - .verify(TIMEOUT); - - if (!isSessionEnabled) { - StepVerifier.create(receiver.receiveMessages()) - .thenAwait(shortWait) - .thenCancel() - .verify(TIMEOUT); - } - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(TIMEOUT); - - setReceiver(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); - - // Assert & Act - StepVerifier.create(receiver.receiveMessages() - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) - .doOnNext(receivedMessage -> logMessage(receivedMessage, receiver.getEntityPath(), "received and filtered")) - .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can renew message lock on a non-session receiver. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void receiveAndRenewLock(MessagingEntityType entityType) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - - // Blocking here because it is not part of the scenario we want to test. - sendMessage(message).block(TIMEOUT); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); - - final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); - assertNotNull(receivedMessage); - assertNotNull(receivedMessage.getLockedUntil()); - - final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); - LOGGER.info("Received message. Seq: {}. lockedUntil: {}", receivedMessage.getSequenceNumber(), initialLock); - - // Assert & Act - try { - StepVerifier.create(Mono.delay(Duration.ofSeconds(7)) - .then(Mono.defer(() -> receiver.renewMessageLock(receivedMessage)))) - .assertNext(lockedUntil -> assertTrue(lockedUntil.isAfter(initialLock), - String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", - lockedUntil, initialLock))) - .expectComplete() - .verify(TIMEOUT); - } finally { - LOGGER.info("Completing message. Seq: {}.", receivedMessage.getSequenceNumber()); - - receiver.complete(receivedMessage) - .doOnNext(m -> logMessage(receivedMessage, receiver.getEntityPath(), "complete")) - .block(TIMEOUT); - } - } - - /** - * Receiver should receive the messages even if user is not "settling the messages" in PEEK LOCK mode and - * autoComplete is disabled. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int totalMessages = 5; - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Send messages - final String messageId = UUID.randomUUID().toString(); - final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); - if (isSessionEnabled) { - messages.forEach(m -> m.setSessionId(sessionId)); - } - sender.sendMessages(messages).block(TIMEOUT); - logMessages(messages, sender.getEntityPath(), "sent messages"); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Assert & Act - StepVerifier.create(receiver.receiveMessages().take(totalMessages)) - .expectNextCount(totalMessages) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Receiver should receive the messages if processing time larger than message lock duration and - * maxAutoLockRenewDuration is set to a large enough duration so user can complete in end. - * This test takes longer time. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final int totalMessages = 2; - // The lock timeout property set on the queue. - final Duration lockRenewTimeout = Duration.ofSeconds(15); - final ClientCreationOptions clientCreationOptions = new ClientCreationOptions().setMaxAutoLockRenewDuration(Duration.ofMinutes(1)); - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Send messages - final String messageId = UUID.randomUUID().toString(); - final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); - if (isSessionEnabled) { - messages.forEach(m -> m.setSessionId(sessionId)); - } - sender.sendMessages(messages).block(); - logMessages(messages, sender.getEntityPath(), "sent messages"); - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled, clientCreationOptions); - - // Assert & Act - StepVerifier.create(receiver.receiveMessages() - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) - .map(receivedMessage -> Mono.delay(lockRenewTimeout.plusSeconds(2)) - .then(receiver.complete(receivedMessage)).thenReturn(receivedMessage).block()).take(totalMessages)) - .expectNextCount(totalMessages) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that the lock can be automatically renewed. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final AtomicInteger lockRenewCount = new AtomicInteger(); - - setSender(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - // Send the message to verify. - sendMessage(message).block(); - - setReceiver(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); - - // Act & Assert - StepVerifier.create(receiver.receiveMessages().flatMap(received -> { - LOGGER.info("{}: lockToken[{}]. lockedUntil[{}]. now[{}]", received.getSequenceNumber(), - received.getLockToken(), received.getLockedUntil(), OffsetDateTime.now()); - - // Simulate some sort of long processing. - while (lockRenewCount.get() < 4) { - lockRenewCount.incrementAndGet(); - LOGGER.info("Iteration {}: Curren time {}.", lockRenewCount.get(), OffsetDateTime.now()); - try { - TimeUnit.SECONDS.sleep(5); - } catch (InterruptedException error) { - LOGGER.error("Error occurred while sleeping: " + error); - } - } - return receiver.complete(received).thenReturn(received); - })) - .assertNext(received -> assertTrue(lockRenewCount.get() > 0)) - .thenCancel() - .verify(TIMEOUT); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(TIMEOUT); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - StepVerifier.create(receiver.receiveMessages() - .flatMap(receivedMessage -> receiver.abandon(receivedMessage).thenReturn(receivedMessage)).take(1)) - .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) - .expectComplete() - .verify(TIMEOUT); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(TIMEOUT); - - setReceiver(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); - AtomicReference received = new AtomicReference(); - - // Act & Assert - StepVerifier.create(receiver.receiveMessages() - .flatMap(receivedMessage -> receiver.defer(receivedMessage).thenReturn(receivedMessage)).take(1)) - .assertNext(m -> { - received.set(m); - assertMessageEquals(m, messageId, isSessionEnabled); - }) - .expectComplete() - .verify(TIMEOUT); - - // TODO(Hemant): Identify if this is valid scenario (https://github.com/Azure/azure-sdk-for-java/issues/19673) - /*receiver.receiveDeferredMessage(received.get().getSequenceNumber()) - .flatMap(m -> receiver.complete(m)) - .block(TIMEOUT); - messagesPending.decrementAndGet(); - */ - } - - /** - * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") - @ParameterizedTest - void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFERRED_MESSAGE_BY_SEQUENCE_NUMBER, false); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - StepVerifier.create(sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create( - receiver.receiveMessages() - .flatMap(m -> receiver.defer(m).thenReturn(m)) - .flatMap(received -> { - logMessage(received, receiver.getEntityPath(), "received and deferred"); - return receiver - .receiveDeferredMessage(received.getSequenceNumber()) - .flatMap(deferred -> { - logMessage(deferred, receiver.getEntityPath(), "received deferred"); - - assertNotNull(deferred); - assertEquals(received.getSequenceNumber(), deferred.getSequenceNumber()); - - switch (dispositionStatus) { - case ABANDONED: - logMessage(deferred, receiver.getEntityPath(), "abandon"); - return receiver.abandon(deferred).thenReturn(deferred); - case SUSPENDED: - logMessage(deferred, receiver.getEntityPath(), "deadLetter"); - return receiver.deadLetter(deferred).thenReturn(deferred); - case COMPLETED: - logMessage(deferred, receiver.getEntityPath(), "complete"); - return receiver.complete(deferred).thenReturn(deferred); - default: - throw LOGGER.logExceptionAsError(new IllegalArgumentException( - "Disposition status not recognized for this test case: " + dispositionStatus)); - } - }); - }) - .take(1)) - .expectNextCount(1) - .expectComplete() - .verify(TIMEOUT); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) { - // Arrange - final boolean isSessionEnabled = true; - setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); - Map sentProperties = messageToSend.getApplicationProperties(); - sentProperties.put("NullProperty", null); - sentProperties.put("BooleanProperty", true); - sentProperties.put("ByteProperty", (byte) 1); - sentProperties.put("ShortProperty", (short) 2); - sentProperties.put("IntProperty", 3); - sentProperties.put("LongProperty", 4L); - sentProperties.put("FloatProperty", 5.5f); - sentProperties.put("DoubleProperty", 6.6f); - sentProperties.put("CharProperty", 'z'); - sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); - sentProperties.put("StringProperty", "string"); - - sendMessage(messageToSend).block(TIMEOUT); - - setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); - - // Assert & Act - StepVerifier.create(receiver.receiveMessages().flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - - final Map received = receivedMessage.getApplicationProperties(); - - assertEquals(sentProperties.size(), received.size()); - - for (Map.Entry sentEntry : sentProperties.entrySet()) { - if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { - assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) received.get(sentEntry.getKey())); - } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { - final Object expected = sentEntry.getValue(); - final Object actual = received.get(sentEntry.getKey()); - - assertEquals(expected, actual, String.format( - "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, - actual)); - } - } - }) - .thenCancel() - .verify(TIMEOUT); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void setAndGetSessionState(MessagingEntityType entityType) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, true); - - final byte[] sessionState = "Finished".getBytes(UTF_8); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage messageToSend = getMessage(messageId, true); - - sendMessage(messageToSend).block(Duration.ofSeconds(10)); - - // Act - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, true); - - StepVerifier.create(receiver.receiveMessages() - .flatMap(message -> { - LOGGER.info("SessionId: {}. LockToken: {}. LockedUntil: {}. Message received.", - message.getSessionId(), message.getLockToken(), message.getLockedUntil()); - assertMessageEquals(message, messageId, isSessionEnabled); - return receiver.abandon(message) - .then(receiver.setSessionState(sessionState)) - .then(receiver.getSessionState()); - }) - .take(1)) - .assertNext(state -> { - LOGGER.info("State received: {}", new String(state, UTF_8)); - assertArrayEquals(sessionState, state); - }) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can receive a message from dead letter queue. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - final Duration shortWait = Duration.ofSeconds(2); - final int entityIndex = 0; - - if (isSessionEnabled && sessionId == null) { - sessionId = UUID.randomUUID().toString(); - } - - setSender(entityType, entityIndex, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message).block(); - - setReceiver(entityType, entityIndex, isSessionEnabled); - - receiver.receiveMessages() - .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) - .map(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - receiver.deadLetter(receivedMessage).block(); - return receivedMessage; - }).next().block(OPERATION_TIMEOUT); - - final ServiceBusReceiverAsyncClient deadLetterReceiver; - switch (entityType) { - case QUEUE: - final String queueName = isSessionEnabled ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); - assertNotNull(queueName, "'queueName' cannot be null."); - - deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() - .queueName(queueName) - .subQueue(SubQueue.DEAD_LETTER_QUEUE) - .buildAsyncClient()); - break; - case SUBSCRIPTION: - final String topicName = getTopicName(entityIndex); - final String subscriptionName = isSessionEnabled ? getSessionSubscriptionBaseName() : getSubscriptionBaseName(); - assertNotNull(topicName, "'topicName' cannot be null."); - assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - - deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() - .topicName(topicName) - .subscriptionName(subscriptionName) - .subQueue(SubQueue.DEAD_LETTER_QUEUE) - .buildAsyncClient()); - break; - default: - throw LOGGER.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); - } - - // Assert & Act + final AzurePowerShellCredential cred = new AzurePowerShellCredentialBuilder().build(); try { - deadLetterReceiver.receiveMessages() - .filter(serviceBusReceivedMessage -> messageId.equals(serviceBusReceivedMessage.getMessageId())) - .map(serviceBusReceivedMessage -> { - assertMessageEquals(serviceBusReceivedMessage, messageId, isSessionEnabled); - return serviceBusReceivedMessage; - }) - .next() - .block(OPERATION_TIMEOUT); - } finally { - // close dead letter receiver. - deadLetterReceiver.close(); + System.out.println("Using AzurePowerShellCredential"); + AccessToken c = cred.getToken(new TokenRequestContext().addScopes(ServiceBusConstants.AZURE_ACTIVE_DIRECTORY_SCOPE)).block(); + System.out.println("Expire At:" + c.getExpiresAt()); + } catch (Exception e) { + System.out.println("Error:" + e.getMessage()); + e.printStackTrace(); } - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { - testRenewLock(entityType, Duration.ZERO, (m) -> { - toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); - return Mono.empty(); - }); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void autoRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { - testRenewLock(entityType, Duration.ofSeconds(10), (m) -> Mono.empty()); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void autoAndManualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { - testRenewLock(entityType, Duration.ofSeconds(10), (m) -> { - toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); - return Mono.empty(); - }); - } - - private void testRenewLock(MessagingEntityType entityType, Duration lockRenewalDuration, Function> renewMono) throws InterruptedException { - setSender(entityType, TestUtils.USE_CASE_RENEW_LOCK, false); - setReceiver(entityType, TestUtils.USE_CASE_RENEW_LOCK, false, new ClientCreationOptions() - .setMaxAutoLockRenewDuration(lockRenewalDuration)); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - - StepVerifier.create(sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - - AtomicReference lockedUntil = new AtomicReference<>(null); - - CountDownLatch latch = new CountDownLatch(2); - receiver.receiveMessages() - .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) - .filter(m -> messageId.equals(m.getMessageId())) - .flatMap(receivedMessage -> { - latch.countDown(); - logMessage(receivedMessage, receiver.getEntityPath(), "filtered message"); - LOGGER.atInfo() - .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) - .addKeyValue("seqNo", receivedMessage.getSequenceNumber()) - .addKeyValue("deliveryCount", receivedMessage.getDeliveryCount()) - .addKeyValue("lockToken", receivedMessage.getLockToken()) - .addKeyValue("lockedUntil", receivedMessage.getLockedUntil()) - .log("message properties"); - assertNotNull(receivedMessage.getLockedUntil()); - // expect to receive the same message but only after lock renewal completes - if (lockedUntil.compareAndSet(null, receivedMessage.getLockedUntil())) { - return renewMono.apply(receivedMessage); - } else { - // TODO: why not not always bigger than lockeduntil? time skew with service? - assertEquals(OffsetDateTime.now().toEpochSecond(), lockedUntil.get().toEpochSecond(), 10); - return receiver.complete(receivedMessage); - } - }) - .subscribe(i -> { }, ex -> fail(ex)); - - assertTrue(latch.await(2, TimeUnit.MINUTES)); - } - @Test - @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") - void receiveTwice() { - setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - - StepVerifier.create(sendMessage(message)).verifyComplete(); - StepVerifier.create(receiver.receiveMessages().take(1)) - .expectNextCount(1) - .expectComplete() - .verify(OPERATION_TIMEOUT); - - StepVerifier.create(sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - - // cannot subscribe to the same receiver - there was a subscription that is disposed now - StepVerifier.create(receiver.receiveMessages().take(1)) - .expectComplete() - .verify(OPERATION_TIMEOUT); - } - - @Test - @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") - void receiveActiveSubscription() { - setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - - StepVerifier.create(sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - toClose(receiver.receiveMessages().subscribe(m -> { })); - - // cannot subscribe to the same receiver - there is active subscription - StepVerifier.create(receiver.receiveMessages().take(1)) - .expectError() - .verify(OPERATION_TIMEOUT); - } - - /** - * Verifies that we can receive a message which have different section set (i.e header, footer, annotations, - * application properties etc). - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void receiveAndValidateProperties(MessagingEntityType entityType) { - // Arrange - final boolean isSessionEnabled = false; - final int totalMessages = 1; - final String subject = "subject"; - final Map footer = new HashMap<>(); - footer.put("footer-key-1", "footer-value-1"); - footer.put("footer-key-2", "footer-value-2"); - - final Map applicationProperties = new HashMap<>(); - applicationProperties.put("ap-key-1", "ap-value-1"); - applicationProperties.put("ap-key-2", "ap-value-2"); - - final Map deliveryAnnotation = new HashMap<>(); - deliveryAnnotation.put("delivery-annotations-key-1", "delivery-annotations-value-1"); - deliveryAnnotation.put("delivery-annotations-key-2", "delivery-annotations-value-2"); - - final String messageId = UUID.randomUUID().toString(); - final AmqpAnnotatedMessage expectedAmqpProperties = new AmqpAnnotatedMessage( - AmqpMessageBody.fromData(CONTENTS_BYTES)); - expectedAmqpProperties.getProperties().setSubject(subject); - expectedAmqpProperties.getProperties().setReplyToGroupId("r-gid"); - expectedAmqpProperties.getProperties().setReplyTo(new AmqpAddress("reply-to")); - expectedAmqpProperties.getProperties().setContentType("content-type"); - expectedAmqpProperties.getProperties().setCorrelationId(new AmqpMessageId("correlation-id")); - expectedAmqpProperties.getProperties().setTo(new AmqpAddress("to")); - expectedAmqpProperties.getProperties().setAbsoluteExpiryTime(OffsetDateTime.now().plusSeconds(60)); - expectedAmqpProperties.getProperties().setUserId("user-id-1".getBytes()); - expectedAmqpProperties.getProperties().setContentEncoding("string"); - expectedAmqpProperties.getProperties().setGroupSequence(2L); - expectedAmqpProperties.getProperties().setCreationTime(OffsetDateTime.now().plusSeconds(30)); - - expectedAmqpProperties.getHeader().setPriority((short) 2); - expectedAmqpProperties.getHeader().setFirstAcquirer(true); - expectedAmqpProperties.getHeader().setDurable(true); - - expectedAmqpProperties.getFooter().putAll(footer); - expectedAmqpProperties.getDeliveryAnnotations().putAll(deliveryAnnotation); - expectedAmqpProperties.getApplicationProperties().putAll(applicationProperties); - - final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - - final AmqpAnnotatedMessage amqpAnnotatedMessage = message.getRawAmqpMessage(); - amqpAnnotatedMessage.getMessageAnnotations().putAll(expectedAmqpProperties.getMessageAnnotations()); - amqpAnnotatedMessage.getApplicationProperties().putAll(expectedAmqpProperties.getApplicationProperties()); - amqpAnnotatedMessage.getDeliveryAnnotations().putAll(expectedAmqpProperties.getDeliveryAnnotations()); - amqpAnnotatedMessage.getFooter().putAll(expectedAmqpProperties.getFooter()); - - final AmqpMessageHeader header = amqpAnnotatedMessage.getHeader(); - header.setFirstAcquirer(expectedAmqpProperties.getHeader().isFirstAcquirer()); - header.setTimeToLive(expectedAmqpProperties.getHeader().getTimeToLive()); - header.setDurable(expectedAmqpProperties.getHeader().isDurable()); - header.setDeliveryCount(expectedAmqpProperties.getHeader().getDeliveryCount()); - header.setPriority(expectedAmqpProperties.getHeader().getPriority()); - - final AmqpMessageProperties amqpMessageProperties = amqpAnnotatedMessage.getProperties(); - amqpMessageProperties.setReplyTo((expectedAmqpProperties.getProperties().getReplyTo())); - amqpMessageProperties.setContentEncoding((expectedAmqpProperties.getProperties().getContentEncoding())); - amqpMessageProperties.setAbsoluteExpiryTime((expectedAmqpProperties.getProperties().getAbsoluteExpiryTime())); - amqpMessageProperties.setSubject((expectedAmqpProperties.getProperties().getSubject())); - amqpMessageProperties.setContentType(expectedAmqpProperties.getProperties().getContentType()); - amqpMessageProperties.setCorrelationId(expectedAmqpProperties.getProperties().getCorrelationId()); - amqpMessageProperties.setTo(expectedAmqpProperties.getProperties().getTo()); - amqpMessageProperties.setGroupSequence(expectedAmqpProperties.getProperties().getGroupSequence()); - amqpMessageProperties.setUserId(expectedAmqpProperties.getProperties().getUserId()); - amqpMessageProperties.setAbsoluteExpiryTime(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime()); - amqpMessageProperties.setCreationTime(expectedAmqpProperties.getProperties().getCreationTime()); - amqpMessageProperties.setReplyToGroupId(expectedAmqpProperties.getProperties().getReplyToGroupId()); - - setSender(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); - - // Send the message - sendMessage(message).block(TIMEOUT); - - setReceiver(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); - StepVerifier.create(receiver.receiveMessages()/*.take(totalMessages)*/) - .assertNext(received -> { - assertNotNull(received.getLockToken()); - AmqpAnnotatedMessage actual = received.getRawAmqpMessage(); - try { - assertArrayEquals(CONTENTS_BYTES, message.getBody().toBytes()); - assertEquals(expectedAmqpProperties.getHeader().getPriority(), actual.getHeader().getPriority()); - assertEquals(expectedAmqpProperties.getHeader().isFirstAcquirer(), actual.getHeader().isFirstAcquirer()); - assertEquals(expectedAmqpProperties.getHeader().isDurable(), actual.getHeader().isDurable()); - - assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); - assertEquals(expectedAmqpProperties.getProperties().getReplyToGroupId(), actual.getProperties().getReplyToGroupId()); - assertEquals(expectedAmqpProperties.getProperties().getReplyTo(), actual.getProperties().getReplyTo()); - assertEquals(expectedAmqpProperties.getProperties().getContentType(), actual.getProperties().getContentType()); - assertEquals(expectedAmqpProperties.getProperties().getCorrelationId(), actual.getProperties().getCorrelationId()); - assertEquals(expectedAmqpProperties.getProperties().getTo(), actual.getProperties().getTo()); - assertEquals(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime().toEpochSecond(), actual.getProperties().getAbsoluteExpiryTime().toEpochSecond()); - assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); - assertEquals(expectedAmqpProperties.getProperties().getContentEncoding(), actual.getProperties().getContentEncoding()); - assertEquals(expectedAmqpProperties.getProperties().getGroupSequence(), actual.getProperties().getGroupSequence()); - assertEquals(expectedAmqpProperties.getProperties().getCreationTime().toEpochSecond(), actual.getProperties().getCreationTime().toEpochSecond()); - assertArrayEquals(expectedAmqpProperties.getProperties().getUserId(), actual.getProperties().getUserId()); - - assertMapValues(expectedAmqpProperties.getDeliveryAnnotations(), actual.getDeliveryAnnotations()); - assertMapValues(expectedAmqpProperties.getMessageAnnotations(), actual.getMessageAnnotations()); - assertMapValues(expectedAmqpProperties.getApplicationProperties(), actual.getApplicationProperties()); - assertMapValues(expectedAmqpProperties.getFooter(), actual.getFooter()); - } finally { - receiver.complete(received).block(Duration.ofSeconds(15)); - logMessage(received, receiver.getEntityPath(), "completed message"); - } - }) - .thenCancel() - .verify(Duration.ofMinutes(2)); - } - - /** - * Verifies we can autocomplete for a queue. - * - * @param entityType Entity Type. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void autoComplete(MessagingEntityType entityType) { // Arrange - final Duration shortWait = Duration.ofSeconds(2); - final int index = USE_CASE_AUTO_COMPLETE; - setSender(entityType, index, false); - - final int numberOfEvents = 3; - final String messageId = UUID.randomUUID().toString(); - final List messages = getServiceBusMessages(numberOfEvents, messageId); - - setReceiver(entityType, index, false); - - // Send messages. - StepVerifier.create(Flux.fromIterable(messages).flatMap(this::sendMessage)) - .verifyComplete(); - - final ServiceBusReceiverAsyncClient autoCompleteReceiver = - toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, index, false) - .buildAsyncClient()); - - Set sequenceNumbers = new HashSet<>(); - // Act - // Expecting that as we receive these messages, they'll be completed. - StepVerifier.create(autoCompleteReceiver.receiveMessages() - .filter(m -> messageId.equals(m.getMessageId())) - .doOnNext(m -> sequenceNumbers.add(m.getSequenceNumber()))) - .expectNextCount(numberOfEvents) - .thenAwait(shortWait) // Give time for autoComplete to finish - .thenCancel() - .verify(TIMEOUT); - - // Assert messages are completed. - for (Long sequenceNumber : sequenceNumbers) { - StepVerifier.create(autoCompleteReceiver.peekMessage(sequenceNumber)) - .verifyComplete(); - } - } - - /** - * Asserts the length and values with in the map. - */ - private void assertMapValues(Map expectedMap, Map actualMap) { - assertTrue(actualMap.size() >= expectedMap.size()); - for (String key : expectedMap.keySet()) { - assertEquals(expectedMap.get(key), actualMap.get(key), "Value is not equal for Key " + key); - } +// setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.createTransaction()) +// .assertNext(Assertions::assertNotNull) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(receiver.createTransaction()) +// .assertNext(Assertions::assertNotNull) +// .expectComplete() +// .verify(TIMEOUT); } +// /** +// * Verifies that we can create multiple transaction using sender and receiver. +// */ +// @Test +// void createMultipleTransactionTest() { +// // Arrange +// setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.createTransaction()) +// .assertNext(Assertions::assertNotNull) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(receiver.createTransaction()) +// .assertNext(Assertions::assertNotNull) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can create transaction and complete. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Assert & Act +// AtomicReference transaction = new AtomicReference<>(); +// StepVerifier.create(receiver.createTransaction()) +// .assertNext(txn -> { +// transaction.set(txn); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(receiver.receiveMessages() +// .flatMap(receivedMessage -> { +// logMessage(receivedMessage, receiver.getEntityPath(), "received message"); +// return receiver.complete(receivedMessage) +// .doOnSuccess(m -> logMessage(receivedMessage, receiver.getEntityPath(), "completed message")) +// .thenReturn(receivedMessage); +// }).take(1)) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(receiver.rollbackTransaction(transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can do following using shared connection and on non session entity. 1. create transaction 2. +// * receive and settle with transactionContext. 3. commit Rollback this transaction. +// */ +// @ParameterizedTest +// @EnumSource(DispositionStatus.class) +// void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { +// +// // Arrange +// final MessagingEntityType entityType = MessagingEntityType.QUEUE; +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_TRANSACTION_SENDRECEIVE_AND_COMPLETE, isSessionEnabled); +// +// final String messageId1 = UUID.randomUUID().toString(); +// final ServiceBusMessage message1 = getMessage(messageId1, isSessionEnabled); +// final String deadLetterReason = "test reason"; +// +// sendMessage(message1).block(TIMEOUT); +// +// // Assert & Act +// AtomicReference transaction = new AtomicReference<>(); +// StepVerifier.create(receiver.createTransaction()) +// .assertNext(txn -> { +// transaction.set(txn); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// assertNotNull(transaction.get()); +// +// // Assert & Act +// final ServiceBusReceivedMessage message = receiver.receiveMessages() +// .flatMap(receivedMessage -> { +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// final Mono operation; +// switch (dispositionStatus) { +// case COMPLETED: +// operation = receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get())); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed messages"); +// break; +// case ABANDONED: +// operation = receiver.abandon(receivedMessage, new AbandonOptions().setTransactionContext(transaction.get())); +// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned messages"); +// break; +// case SUSPENDED: +// DeadLetterOptions deadLetterOptions = new DeadLetterOptions().setTransactionContext(transaction.get()) +// .setDeadLetterReason(deadLetterReason); +// operation = receiver.deadLetter(receivedMessage, deadLetterOptions); +// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered messages"); +// break; +// case DEFERRED: +// operation = receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction.get())); +// logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); +// break; +// case RELEASED: +// operation = receiver.release(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "released messages"); +// break; +// default: +// throw LOGGER.logExceptionAsError(new IllegalArgumentException( +// "Disposition status not recognized for this test case: " + dispositionStatus)); +// } +// return operation +// .thenReturn(receivedMessage); +// }) +// .blockFirst(TIMEOUT); +// assertNotNull(message); +// +// StepVerifier.create(receiver.commitTransaction(transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can do following on different clients i.e. sender and receiver. 1. create transaction using +// * sender 2. receive and complete with transactionContext. 3. Commit this transaction using sender. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// @Disabled +// void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { +// // Arrange +// final boolean shareConnection = true; +// final int entityIndex = 0; +// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) +// .buildAsyncClient()); +// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) +// .buildAsyncClient()); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(TIMEOUT); +// +// // Assert & Act +// AtomicReference transaction = new AtomicReference<>(); +// StepVerifier.create(sender.createTransaction()) +// .assertNext(txn -> { +// transaction.set(txn); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// assertNotNull(transaction.get()); +// +// // Assert & Act +// final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); +// assertNotNull(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "received message"); +// StepVerifier.create(receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get()))) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(sender.commitTransaction(transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send and receive two messages. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int entityIndex = 0; +// final boolean shareConnection = false; +// final Duration shortWait = Duration.ofSeconds(3); +// +// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) +// .buildAsyncClient()); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// Mono.when(sendMessage(message), sendMessage(message)).block(); +// +// // Now create receiver +// if (isSessionEnabled) { +// assertNotNull(sessionId, "'sessionId' should have been set."); +// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) +// .buildAsyncClient()); +// this.receiver = toClose(sessionReceiver.acceptSession(sessionId).block()); +// } else { +// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) +// .buildAsyncClient()); +// } +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages() +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .thenAwait(shortWait) // Give time for autoComplete to finish +// .thenCancel() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send and receive a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int entityIndex = USE_CASE_AUTO_COMPLETE; +// final boolean shareConnection = false; +// +// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) +// .buildAsyncClient()); +// final String messageId = CoreUtils.randomUuid().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// StepVerifier.create(sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// +// // Now create receiver +// if (isSessionEnabled) { +// assertNotNull(sessionId, "'sessionId' should have been set."); +// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) +// .buildAsyncClient()); +// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); +// } else { +// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) +// .buildAsyncClient()); +// } +// +// // Assert +// StepVerifier.create(receiver.receiveMessages() +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) +// .assertNext(receivedMessage -> { +// logMessage(receivedMessage, receiver.getEntityPath(), "received message"); +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// }) +// .expectNoEvent(Duration.ofSeconds(30)) +// .thenCancel() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send and peek a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(); +// +// setReceiver(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); +// +// Mono peek = receiver.peekMessage() +// .filter(m -> messageId.equals(m.getMessageId())) +// .repeatWhenEmpty(10, i -> Flux.interval(Duration.ofSeconds(1))); +// +// // Assert & Act +// StepVerifier.create(peek +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked and filtered message"))) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that an empty entity does not error when peeking. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); +// +// final int fromSequenceNumber = 1; +// +// // Assert & Act +// StepVerifier.create(receiver.peekMessage(fromSequenceNumber) +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can schedule and receive a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); +// final Duration shortDelay = Duration.ofSeconds(4); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(2); +// +// sender.scheduleMessage(message, scheduledEnqueueTime).block(); +// +// setReceiver(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(Mono.delay(shortDelay).then(receiver.receiveMessages() +// .filter(m -> messageId.equals(m.getMessageId())) +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) +// .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).next())) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can cancel a scheduled message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); +// final Duration delayDuration = Duration.ofSeconds(3); +// +// final Long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime).block(TIMEOUT); +// logMessage(message, sender.getEntityPath(), "scheduled"); +// +// assertNotNull(sequenceNumber); +// +// Mono.delay(delayDuration) +// .then(sender.cancelScheduledMessage(sequenceNumber)) +// .block(TIMEOUT); +// +// logMessage(message, sender.getEntityPath(), "cancelled messaged with sequence number " + sequenceNumber); +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages() +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) +// .take(1)) +// .thenAwait(Duration.ofSeconds(5)) +// .thenCancel() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send and peek a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int entityIndex = 3; +// +// setSender(entityType, entityIndex, isSessionEnabled); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final CountDownLatch countDownLatch = new CountDownLatch(1); +// +// sendMessage(message).block(); +// +// setReceiver(entityType, entityIndex, isSessionEnabled); +// +// // Message are not always guaranteed, so try many times +// final ServiceBusReceivedMessage peekMessage = receiver.peekMessage() +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) +// .map(receivedMessage -> { +// countDownLatch.countDown(); +// return receivedMessage; +// }) +// .repeat(() -> countDownLatch.getCount() > 0) +// .next() +// .block(); +// assertNotNull(peekMessage); +// final long sequenceNumber = peekMessage.getSequenceNumber(); +// +// // Assert & Act +// try { +// StepVerifier.create(receiver.peekMessage(sequenceNumber) +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) +// .assertNext(m -> { +// assertEquals(sequenceNumber, m.getSequenceNumber()); +// assertMessageEquals(m, messageId, isSessionEnabled); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } finally { +// +// // Cleanup +// StepVerifier.create(receiver.receiveMessages() +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) +// .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) +// .expectNextCount(1) +// .expectComplete() +// .verify(TIMEOUT); +// } +// } +// +// /** +// * Verifies that we can send and peek a batch of messages and the sequence number is tracked correctly. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// public void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { +// // Arrange +// setSender(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final List messages = getServiceBusMessages(10, messageId, CONTENTS_BYTES); +// final Set receivedPositions = Collections.synchronizedSet(new HashSet<>()); +// final List receivedMessages = Collections.synchronizedList(new ArrayList<>()); +// +// if (isSessionEnabled) { +// messages.forEach(m -> m.setSessionId(sessionId)); +// } +// +// StepVerifier.create(sender.sendMessages(messages) +// .doOnSuccess(aVoid -> logMessages(messages, sender.getEntityPath(), "sent"))) +// .expectComplete() +// .verify(TIMEOUT); +// +// setReceiver(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); +// +// // Assert & Act +// for (int i = 0; i < 5 && receivedPositions.size() < messages.size(); i++) { +// peekMessages(messages.size(), messageId, receivedPositions) +// .doOnNext(receivedMessage -> receivedMessages.add(receivedMessage)) +// .blockLast(); +// if (receivedPositions.size() < messages.size()) { +// Thread.sleep(1000); +// } +// } +// +// assertEquals(receivedMessages.size(), messages.size()); +// +// final AtomicInteger messageCount = new AtomicInteger(); +// +// synchronized (receivedMessages) { +// receivedMessages.stream() +// .forEach(actualMessage -> { +// final Object position = actualMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); +// assertTrue(position instanceof Integer, "Did not contain correct position number: " + position); +// +// // messages are received in the same order as they were sent +// assertEquals(messageCount.getAndIncrement(), position); +// }); +// } +// } +// +// private Flux peekMessages(int count, String messageIdFilter, Set receivedPositions) { +// return receiver.peekMessages(count) +// // maxMessages are not always guaranteed, sometime, we get less than asked for, so we will try many times. +// .filter(receivedMessage -> { +// logMessage(receivedMessage, receiver.getEntityPath(), "peeked message"); +// Integer position = (Integer) receivedMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); +// boolean filtered = messageIdFilter.equals(receivedMessage.getMessageId()) && receivedPositions.add(position); +// if (filtered) { +// logMessage(receivedMessage, receiver.getEntityPath(), "filtered message, a few more to go"); +// } +// return filtered; +// }); +// } +// +// /** +// * Verifies that we can send and peek a batch of messages. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void peekMessagesFromSequence(MessagingEntityType entityType) throws InterruptedException { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_MESSAGE_FROM_SEQUENCE, false); +// +// final AtomicInteger messageId = new AtomicInteger(); +// final int maxMessages = 2; +// final AtomicLong fromSequenceNumber = new AtomicLong(); +// final CountDownLatch countdownLatch = new CountDownLatch(maxMessages); +// fromSequenceNumber.set(1); +// +// final byte[] content = "peek-message-from-sequence".getBytes(Charset.defaultCharset()); +// List messageIds = Collections.synchronizedList(new ArrayList<>()); +// for (int i = 0; i < maxMessages; ++i) { +// ServiceBusMessage message = getMessage(String.valueOf(i), isSessionEnabled, AmqpMessageBody.fromData(content)); +// messageIds.add(String.valueOf(i)); +// sendMessage(message).block(); +// } +// +// // Assert & Act +// +// // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times +// // https://github.com/Azure/azure-sdk-for-java/issues/21168 +// List receivedMessages = Collections.synchronizedList(new ArrayList<>()); +// Disposable subscription = receiver.peekMessages(maxMessages, fromSequenceNumber.get()) +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message")) +// .filter(receivedMessage -> messageIds.contains(receivedMessage.getMessageId()) +// && receivedMessages.parallelStream().noneMatch(mid -> +// mid.equals(receivedMessage.getMessageId()))) +// .sort(Comparator.comparing(ServiceBusReceivedMessage::getMessageId)) +// .flatMap(receivedMessage -> { +// Long previousSequenceNumber = fromSequenceNumber.get(); +// fromSequenceNumber.set(receivedMessage.getSequenceNumber() + 1); +// countdownLatch.countDown(); +// receivedMessages.add(receivedMessage.getMessageId()); +// assertEquals(String.valueOf(messageId.getAndIncrement()), receivedMessage.getMessageId(), +// String.format("Message id did not match. Message payload: [%s], peek from Sequence Number [%s], " +// + " received message Sequence Number [%s]", receivedMessage.getBody(), +// previousSequenceNumber, receivedMessage.getSequenceNumber())); +// return Mono.just(receivedMessage); +// }) +// .repeat(() -> countdownLatch.getCount() > 0) +// .subscribe(); +// toClose(subscription); +// +// assertTrue(countdownLatch.await(20, TimeUnit.SECONDS), "Failed peek messages from sequence."); +// +// StepVerifier.create(receiver.receiveMessages().take(maxMessages)) +// .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) +// .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that an empty entity does not error when peeking. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); +// +// final int maxMessages = 10; +// final int fromSequenceNumber = 1; +// +// // Assert & Act +// StepVerifier.create(receiver.peekMessages(maxMessages, fromSequenceNumber)) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can dead-letter a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int entityIndex = 0; +// setSender(entityType, entityIndex, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(); +// +// setReceiver(entityType, entityIndex, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages() +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) +// .flatMap(receivedMessage -> receiver.deadLetter(receivedMessage).thenReturn(receivedMessage)).take(1)) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .thenCancel() +// .verify(TIMEOUT); +// +// } +// +// /** +// * Verifies that we can send and receive a message AMQP Sequence andValue object. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; +// final boolean shareConnection = false; +// final Duration shortWait = Duration.ofSeconds(3); +// final Long expectedLongValue = Long.parseLong("6"); +// +// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) +// .buildAsyncClient()); +// +// // Send value Object +// String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromValue(expectedLongValue)); +// sendMessage(message).block(TIMEOUT); +// +// // send SEQUENCE +// messageId = UUID.randomUUID().toString(); +// +// List sequenceData = new ArrayList<>(); +// sequenceData.add("A1"); +// sequenceData.add(1L); +// sequenceData.add(2); +// +// message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromSequence(sequenceData)); +// sendMessage(message).block(TIMEOUT); +// +// // Now create receiver +// if (isSessionEnabled) { +// assertNotNull(sessionId, "'sessionId' should have been set."); +// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) +// .buildAsyncClient()); +// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); +// } else { +// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) +// .buildAsyncClient()); +// } +// +// // Assert +// StepVerifier.create(receiver.receiveMessages()) +// .assertNext(receivedMessage -> { +// AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); +// AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); +// assertEquals(AmqpMessageBodyType.VALUE, type); +// Object value = amqpAnnotatedMessage.getBody().getValue(); +// assertTrue(value instanceof Long); +// assertEquals(expectedLongValue.longValue(), ((Long) value).longValue()); +// }) +// .assertNext(receivedMessage -> { +// AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); +// AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); +// assertEquals(AmqpMessageBodyType.SEQUENCE, type); +// assertArrayEquals(sequenceData.toArray(), amqpAnnotatedMessage.getBody().getSequence().toArray()); +// }) +// .thenAwait(shortWait) // Give time for autoComplete to finish +// .thenCancel() +// .verify(TIMEOUT); +// +// if (!isSessionEnabled) { +// StepVerifier.create(receiver.receiveMessages()) +// .thenAwait(shortWait) +// .thenCancel() +// .verify(TIMEOUT); +// } +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(TIMEOUT); +// +// setReceiver(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages() +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) +// .doOnNext(receivedMessage -> logMessage(receivedMessage, receiver.getEntityPath(), "received and filtered")) +// .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can renew message lock on a non-session receiver. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void receiveAndRenewLock(MessagingEntityType entityType) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// +// // Blocking here because it is not part of the scenario we want to test. +// sendMessage(message).block(TIMEOUT); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); +// +// final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); +// assertNotNull(receivedMessage); +// assertNotNull(receivedMessage.getLockedUntil()); +// +// final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); +// LOGGER.info("Received message. Seq: {}. lockedUntil: {}", receivedMessage.getSequenceNumber(), initialLock); +// +// // Assert & Act +// try { +// StepVerifier.create(Mono.delay(Duration.ofSeconds(7)) +// .then(Mono.defer(() -> receiver.renewMessageLock(receivedMessage)))) +// .assertNext(lockedUntil -> assertTrue(lockedUntil.isAfter(initialLock), +// String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", +// lockedUntil, initialLock))) +// .expectComplete() +// .verify(TIMEOUT); +// } finally { +// LOGGER.info("Completing message. Seq: {}.", receivedMessage.getSequenceNumber()); +// +// receiver.complete(receivedMessage) +// .doOnNext(m -> logMessage(receivedMessage, receiver.getEntityPath(), "complete")) +// .block(TIMEOUT); +// } +// } +// +// /** +// * Receiver should receive the messages even if user is not "settling the messages" in PEEK LOCK mode and +// * autoComplete is disabled. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int totalMessages = 5; +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Send messages +// final String messageId = UUID.randomUUID().toString(); +// final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); +// if (isSessionEnabled) { +// messages.forEach(m -> m.setSessionId(sessionId)); +// } +// sender.sendMessages(messages).block(TIMEOUT); +// logMessages(messages, sender.getEntityPath(), "sent messages"); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages().take(totalMessages)) +// .expectNextCount(totalMessages) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Receiver should receive the messages if processing time larger than message lock duration and +// * maxAutoLockRenewDuration is set to a large enough duration so user can complete in end. +// * This test takes longer time. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final int totalMessages = 2; +// // The lock timeout property set on the queue. +// final Duration lockRenewTimeout = Duration.ofSeconds(15); +// final ClientCreationOptions clientCreationOptions = new ClientCreationOptions().setMaxAutoLockRenewDuration(Duration.ofMinutes(1)); +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Send messages +// final String messageId = UUID.randomUUID().toString(); +// final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); +// if (isSessionEnabled) { +// messages.forEach(m -> m.setSessionId(sessionId)); +// } +// sender.sendMessages(messages).block(); +// logMessages(messages, sender.getEntityPath(), "sent messages"); +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled, clientCreationOptions); +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages() +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) +// .map(receivedMessage -> Mono.delay(lockRenewTimeout.plusSeconds(2)) +// .then(receiver.complete(receivedMessage)).thenReturn(receivedMessage).block()).take(totalMessages)) +// .expectNextCount(totalMessages) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that the lock can be automatically renewed. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final AtomicInteger lockRenewCount = new AtomicInteger(); +// +// setSender(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// // Send the message to verify. +// sendMessage(message).block(); +// +// setReceiver(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); +// +// // Act & Assert +// StepVerifier.create(receiver.receiveMessages().flatMap(received -> { +// LOGGER.info("{}: lockToken[{}]. lockedUntil[{}]. now[{}]", received.getSequenceNumber(), +// received.getLockToken(), received.getLockedUntil(), OffsetDateTime.now()); +// +// // Simulate some sort of long processing. +// while (lockRenewCount.get() < 4) { +// lockRenewCount.incrementAndGet(); +// LOGGER.info("Iteration {}: Curren time {}.", lockRenewCount.get(), OffsetDateTime.now()); +// try { +// TimeUnit.SECONDS.sleep(5); +// } catch (InterruptedException error) { +// LOGGER.error("Error occurred while sleeping: " + error); +// } +// } +// return receiver.complete(received).thenReturn(received); +// })) +// .assertNext(received -> assertTrue(lockRenewCount.get() > 0)) +// .thenCancel() +// .verify(TIMEOUT); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(TIMEOUT); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// StepVerifier.create(receiver.receiveMessages() +// .flatMap(receivedMessage -> receiver.abandon(receivedMessage).thenReturn(receivedMessage)).take(1)) +// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(TIMEOUT); +// +// setReceiver(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); +// AtomicReference received = new AtomicReference(); +// +// // Act & Assert +// StepVerifier.create(receiver.receiveMessages() +// .flatMap(receivedMessage -> receiver.defer(receivedMessage).thenReturn(receivedMessage)).take(1)) +// .assertNext(m -> { +// received.set(m); +// assertMessageEquals(m, messageId, isSessionEnabled); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// // TODO(Hemant): Identify if this is valid scenario (https://github.com/Azure/azure-sdk-for-java/issues/19673) +// /*receiver.receiveDeferredMessage(received.get().getSequenceNumber()) +// .flatMap(m -> receiver.complete(m)) +// .block(TIMEOUT); +// messagesPending.decrementAndGet(); +// */ +// } +// +// /** +// * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") +// @ParameterizedTest +// void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFERRED_MESSAGE_BY_SEQUENCE_NUMBER, false); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// StepVerifier.create(sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create( +// receiver.receiveMessages() +// .flatMap(m -> receiver.defer(m).thenReturn(m)) +// .flatMap(received -> { +// logMessage(received, receiver.getEntityPath(), "received and deferred"); +// return receiver +// .receiveDeferredMessage(received.getSequenceNumber()) +// .flatMap(deferred -> { +// logMessage(deferred, receiver.getEntityPath(), "received deferred"); +// +// assertNotNull(deferred); +// assertEquals(received.getSequenceNumber(), deferred.getSequenceNumber()); +// +// switch (dispositionStatus) { +// case ABANDONED: +// logMessage(deferred, receiver.getEntityPath(), "abandon"); +// return receiver.abandon(deferred).thenReturn(deferred); +// case SUSPENDED: +// logMessage(deferred, receiver.getEntityPath(), "deadLetter"); +// return receiver.deadLetter(deferred).thenReturn(deferred); +// case COMPLETED: +// logMessage(deferred, receiver.getEntityPath(), "complete"); +// return receiver.complete(deferred).thenReturn(deferred); +// default: +// throw LOGGER.logExceptionAsError(new IllegalArgumentException( +// "Disposition status not recognized for this test case: " + dispositionStatus)); +// } +// }); +// }) +// .take(1)) +// .expectNextCount(1) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) { +// // Arrange +// final boolean isSessionEnabled = true; +// setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); +// Map sentProperties = messageToSend.getApplicationProperties(); +// sentProperties.put("NullProperty", null); +// sentProperties.put("BooleanProperty", true); +// sentProperties.put("ByteProperty", (byte) 1); +// sentProperties.put("ShortProperty", (short) 2); +// sentProperties.put("IntProperty", 3); +// sentProperties.put("LongProperty", 4L); +// sentProperties.put("FloatProperty", 5.5f); +// sentProperties.put("DoubleProperty", 6.6f); +// sentProperties.put("CharProperty", 'z'); +// sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); +// sentProperties.put("StringProperty", "string"); +// +// sendMessage(messageToSend).block(TIMEOUT); +// +// setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); +// +// // Assert & Act +// StepVerifier.create(receiver.receiveMessages().flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// +// final Map received = receivedMessage.getApplicationProperties(); +// +// assertEquals(sentProperties.size(), received.size()); +// +// for (Map.Entry sentEntry : sentProperties.entrySet()) { +// if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { +// assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) received.get(sentEntry.getKey())); +// } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { +// final Object expected = sentEntry.getValue(); +// final Object actual = received.get(sentEntry.getKey()); +// +// assertEquals(expected, actual, String.format( +// "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, +// actual)); +// } +// } +// }) +// .thenCancel() +// .verify(TIMEOUT); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void setAndGetSessionState(MessagingEntityType entityType) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, true); +// +// final byte[] sessionState = "Finished".getBytes(UTF_8); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage messageToSend = getMessage(messageId, true); +// +// sendMessage(messageToSend).block(Duration.ofSeconds(10)); +// +// // Act +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, true); +// +// StepVerifier.create(receiver.receiveMessages() +// .flatMap(message -> { +// LOGGER.info("SessionId: {}. LockToken: {}. LockedUntil: {}. Message received.", +// message.getSessionId(), message.getLockToken(), message.getLockedUntil()); +// assertMessageEquals(message, messageId, isSessionEnabled); +// return receiver.abandon(message) +// .then(receiver.setSessionState(sessionState)) +// .then(receiver.getSessionState()); +// }) +// .take(1)) +// .assertNext(state -> { +// LOGGER.info("State received: {}", new String(state, UTF_8)); +// assertArrayEquals(sessionState, state); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can receive a message from dead letter queue. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// final Duration shortWait = Duration.ofSeconds(2); +// final int entityIndex = 0; +// +// if (isSessionEnabled && sessionId == null) { +// sessionId = UUID.randomUUID().toString(); +// } +// +// setSender(entityType, entityIndex, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message).block(); +// +// setReceiver(entityType, entityIndex, isSessionEnabled); +// +// receiver.receiveMessages() +// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) +// .map(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// receiver.deadLetter(receivedMessage).block(); +// return receivedMessage; +// }).next().block(OPERATION_TIMEOUT); +// +// final ServiceBusReceiverAsyncClient deadLetterReceiver; +// switch (entityType) { +// case QUEUE: +// final String queueName = isSessionEnabled ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); +// assertNotNull(queueName, "'queueName' cannot be null."); +// +// deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() +// .queueName(queueName) +// .subQueue(SubQueue.DEAD_LETTER_QUEUE) +// .buildAsyncClient()); +// break; +// case SUBSCRIPTION: +// final String topicName = getTopicName(entityIndex); +// final String subscriptionName = isSessionEnabled ? getSessionSubscriptionBaseName() : getSubscriptionBaseName(); +// assertNotNull(topicName, "'topicName' cannot be null."); +// assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); +// +// deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() +// .topicName(topicName) +// .subscriptionName(subscriptionName) +// .subQueue(SubQueue.DEAD_LETTER_QUEUE) +// .buildAsyncClient()); +// break; +// default: +// throw LOGGER.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); +// } +// +// // Assert & Act +// try { +// deadLetterReceiver.receiveMessages() +// .filter(serviceBusReceivedMessage -> messageId.equals(serviceBusReceivedMessage.getMessageId())) +// .map(serviceBusReceivedMessage -> { +// assertMessageEquals(serviceBusReceivedMessage, messageId, isSessionEnabled); +// return serviceBusReceivedMessage; +// }) +// .next() +// .block(OPERATION_TIMEOUT); +// } finally { +// // close dead letter receiver. +// deadLetterReceiver.close(); +// } +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { +// testRenewLock(entityType, Duration.ZERO, (m) -> { +// toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); +// return Mono.empty(); +// }); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void autoRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { +// testRenewLock(entityType, Duration.ofSeconds(10), (m) -> Mono.empty()); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void autoAndManualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { +// testRenewLock(entityType, Duration.ofSeconds(10), (m) -> { +// toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); +// return Mono.empty(); +// }); +// } +// +// private void testRenewLock(MessagingEntityType entityType, Duration lockRenewalDuration, Function> renewMono) throws InterruptedException { +// setSender(entityType, TestUtils.USE_CASE_RENEW_LOCK, false); +// setReceiver(entityType, TestUtils.USE_CASE_RENEW_LOCK, false, new ClientCreationOptions() +// .setMaxAutoLockRenewDuration(lockRenewalDuration)); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// +// StepVerifier.create(sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// +// AtomicReference lockedUntil = new AtomicReference<>(null); +// +// CountDownLatch latch = new CountDownLatch(2); +// receiver.receiveMessages() +// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) +// .filter(m -> messageId.equals(m.getMessageId())) +// .flatMap(receivedMessage -> { +// latch.countDown(); +// logMessage(receivedMessage, receiver.getEntityPath(), "filtered message"); +// LOGGER.atInfo() +// .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) +// .addKeyValue("seqNo", receivedMessage.getSequenceNumber()) +// .addKeyValue("deliveryCount", receivedMessage.getDeliveryCount()) +// .addKeyValue("lockToken", receivedMessage.getLockToken()) +// .addKeyValue("lockedUntil", receivedMessage.getLockedUntil()) +// .log("message properties"); +// assertNotNull(receivedMessage.getLockedUntil()); +// // expect to receive the same message but only after lock renewal completes +// if (lockedUntil.compareAndSet(null, receivedMessage.getLockedUntil())) { +// return renewMono.apply(receivedMessage); +// } else { +// // TODO: why not not always bigger than lockeduntil? time skew with service? +// assertEquals(OffsetDateTime.now().toEpochSecond(), lockedUntil.get().toEpochSecond(), 10); +// return receiver.complete(receivedMessage); +// } +// }) +// .subscribe(i -> { }, ex -> fail(ex)); +// +// assertTrue(latch.await(2, TimeUnit.MINUTES)); +// } +// +// @Test +// @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") +// void receiveTwice() { +// setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// +// StepVerifier.create(sendMessage(message)).verifyComplete(); +// StepVerifier.create(receiver.receiveMessages().take(1)) +// .expectNextCount(1) +// .expectComplete() +// .verify(OPERATION_TIMEOUT); +// +// StepVerifier.create(sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// +// // cannot subscribe to the same receiver - there was a subscription that is disposed now +// StepVerifier.create(receiver.receiveMessages().take(1)) +// .expectComplete() +// .verify(OPERATION_TIMEOUT); +// } +// +// @Test +// @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") +// void receiveActiveSubscription() { +// setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// +// StepVerifier.create(sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// toClose(receiver.receiveMessages().subscribe(m -> { })); +// +// // cannot subscribe to the same receiver - there is active subscription +// StepVerifier.create(receiver.receiveMessages().take(1)) +// .expectError() +// .verify(OPERATION_TIMEOUT); +// } +// +// /** +// * Verifies that we can receive a message which have different section set (i.e header, footer, annotations, +// * application properties etc). +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void receiveAndValidateProperties(MessagingEntityType entityType) { +// // Arrange +// final boolean isSessionEnabled = false; +// final int totalMessages = 1; +// final String subject = "subject"; +// final Map footer = new HashMap<>(); +// footer.put("footer-key-1", "footer-value-1"); +// footer.put("footer-key-2", "footer-value-2"); +// +// final Map applicationProperties = new HashMap<>(); +// applicationProperties.put("ap-key-1", "ap-value-1"); +// applicationProperties.put("ap-key-2", "ap-value-2"); +// +// final Map deliveryAnnotation = new HashMap<>(); +// deliveryAnnotation.put("delivery-annotations-key-1", "delivery-annotations-value-1"); +// deliveryAnnotation.put("delivery-annotations-key-2", "delivery-annotations-value-2"); +// +// final String messageId = UUID.randomUUID().toString(); +// final AmqpAnnotatedMessage expectedAmqpProperties = new AmqpAnnotatedMessage( +// AmqpMessageBody.fromData(CONTENTS_BYTES)); +// expectedAmqpProperties.getProperties().setSubject(subject); +// expectedAmqpProperties.getProperties().setReplyToGroupId("r-gid"); +// expectedAmqpProperties.getProperties().setReplyTo(new AmqpAddress("reply-to")); +// expectedAmqpProperties.getProperties().setContentType("content-type"); +// expectedAmqpProperties.getProperties().setCorrelationId(new AmqpMessageId("correlation-id")); +// expectedAmqpProperties.getProperties().setTo(new AmqpAddress("to")); +// expectedAmqpProperties.getProperties().setAbsoluteExpiryTime(OffsetDateTime.now().plusSeconds(60)); +// expectedAmqpProperties.getProperties().setUserId("user-id-1".getBytes()); +// expectedAmqpProperties.getProperties().setContentEncoding("string"); +// expectedAmqpProperties.getProperties().setGroupSequence(2L); +// expectedAmqpProperties.getProperties().setCreationTime(OffsetDateTime.now().plusSeconds(30)); +// +// expectedAmqpProperties.getHeader().setPriority((short) 2); +// expectedAmqpProperties.getHeader().setFirstAcquirer(true); +// expectedAmqpProperties.getHeader().setDurable(true); +// +// expectedAmqpProperties.getFooter().putAll(footer); +// expectedAmqpProperties.getDeliveryAnnotations().putAll(deliveryAnnotation); +// expectedAmqpProperties.getApplicationProperties().putAll(applicationProperties); +// +// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// +// final AmqpAnnotatedMessage amqpAnnotatedMessage = message.getRawAmqpMessage(); +// amqpAnnotatedMessage.getMessageAnnotations().putAll(expectedAmqpProperties.getMessageAnnotations()); +// amqpAnnotatedMessage.getApplicationProperties().putAll(expectedAmqpProperties.getApplicationProperties()); +// amqpAnnotatedMessage.getDeliveryAnnotations().putAll(expectedAmqpProperties.getDeliveryAnnotations()); +// amqpAnnotatedMessage.getFooter().putAll(expectedAmqpProperties.getFooter()); +// +// final AmqpMessageHeader header = amqpAnnotatedMessage.getHeader(); +// header.setFirstAcquirer(expectedAmqpProperties.getHeader().isFirstAcquirer()); +// header.setTimeToLive(expectedAmqpProperties.getHeader().getTimeToLive()); +// header.setDurable(expectedAmqpProperties.getHeader().isDurable()); +// header.setDeliveryCount(expectedAmqpProperties.getHeader().getDeliveryCount()); +// header.setPriority(expectedAmqpProperties.getHeader().getPriority()); +// +// final AmqpMessageProperties amqpMessageProperties = amqpAnnotatedMessage.getProperties(); +// amqpMessageProperties.setReplyTo((expectedAmqpProperties.getProperties().getReplyTo())); +// amqpMessageProperties.setContentEncoding((expectedAmqpProperties.getProperties().getContentEncoding())); +// amqpMessageProperties.setAbsoluteExpiryTime((expectedAmqpProperties.getProperties().getAbsoluteExpiryTime())); +// amqpMessageProperties.setSubject((expectedAmqpProperties.getProperties().getSubject())); +// amqpMessageProperties.setContentType(expectedAmqpProperties.getProperties().getContentType()); +// amqpMessageProperties.setCorrelationId(expectedAmqpProperties.getProperties().getCorrelationId()); +// amqpMessageProperties.setTo(expectedAmqpProperties.getProperties().getTo()); +// amqpMessageProperties.setGroupSequence(expectedAmqpProperties.getProperties().getGroupSequence()); +// amqpMessageProperties.setUserId(expectedAmqpProperties.getProperties().getUserId()); +// amqpMessageProperties.setAbsoluteExpiryTime(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime()); +// amqpMessageProperties.setCreationTime(expectedAmqpProperties.getProperties().getCreationTime()); +// amqpMessageProperties.setReplyToGroupId(expectedAmqpProperties.getProperties().getReplyToGroupId()); +// +// setSender(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); +// +// // Send the message +// sendMessage(message).block(TIMEOUT); +// +// setReceiver(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); +// StepVerifier.create(receiver.receiveMessages()/*.take(totalMessages)*/) +// .assertNext(received -> { +// assertNotNull(received.getLockToken()); +// AmqpAnnotatedMessage actual = received.getRawAmqpMessage(); +// try { +// assertArrayEquals(CONTENTS_BYTES, message.getBody().toBytes()); +// assertEquals(expectedAmqpProperties.getHeader().getPriority(), actual.getHeader().getPriority()); +// assertEquals(expectedAmqpProperties.getHeader().isFirstAcquirer(), actual.getHeader().isFirstAcquirer()); +// assertEquals(expectedAmqpProperties.getHeader().isDurable(), actual.getHeader().isDurable()); +// +// assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); +// assertEquals(expectedAmqpProperties.getProperties().getReplyToGroupId(), actual.getProperties().getReplyToGroupId()); +// assertEquals(expectedAmqpProperties.getProperties().getReplyTo(), actual.getProperties().getReplyTo()); +// assertEquals(expectedAmqpProperties.getProperties().getContentType(), actual.getProperties().getContentType()); +// assertEquals(expectedAmqpProperties.getProperties().getCorrelationId(), actual.getProperties().getCorrelationId()); +// assertEquals(expectedAmqpProperties.getProperties().getTo(), actual.getProperties().getTo()); +// assertEquals(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime().toEpochSecond(), actual.getProperties().getAbsoluteExpiryTime().toEpochSecond()); +// assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); +// assertEquals(expectedAmqpProperties.getProperties().getContentEncoding(), actual.getProperties().getContentEncoding()); +// assertEquals(expectedAmqpProperties.getProperties().getGroupSequence(), actual.getProperties().getGroupSequence()); +// assertEquals(expectedAmqpProperties.getProperties().getCreationTime().toEpochSecond(), actual.getProperties().getCreationTime().toEpochSecond()); +// assertArrayEquals(expectedAmqpProperties.getProperties().getUserId(), actual.getProperties().getUserId()); +// +// assertMapValues(expectedAmqpProperties.getDeliveryAnnotations(), actual.getDeliveryAnnotations()); +// assertMapValues(expectedAmqpProperties.getMessageAnnotations(), actual.getMessageAnnotations()); +// assertMapValues(expectedAmqpProperties.getApplicationProperties(), actual.getApplicationProperties()); +// assertMapValues(expectedAmqpProperties.getFooter(), actual.getFooter()); +// } finally { +// receiver.complete(received).block(Duration.ofSeconds(15)); +// logMessage(received, receiver.getEntityPath(), "completed message"); +// } +// }) +// .thenCancel() +// .verify(Duration.ofMinutes(2)); +// } +// +// /** +// * Verifies we can autocomplete for a queue. +// * +// * @param entityType Entity Type. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void autoComplete(MessagingEntityType entityType) { +// // Arrange +// final Duration shortWait = Duration.ofSeconds(2); +// final int index = USE_CASE_AUTO_COMPLETE; +// setSender(entityType, index, false); +// +// final int numberOfEvents = 3; +// final String messageId = UUID.randomUUID().toString(); +// final List messages = getServiceBusMessages(numberOfEvents, messageId); +// +// setReceiver(entityType, index, false); +// +// // Send messages. +// StepVerifier.create(Flux.fromIterable(messages).flatMap(this::sendMessage)) +// .verifyComplete(); +// +// final ServiceBusReceiverAsyncClient autoCompleteReceiver = +// toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, index, false) +// .buildAsyncClient()); +// +// Set sequenceNumbers = new HashSet<>(); +// // Act +// // Expecting that as we receive these messages, they'll be completed. +// StepVerifier.create(autoCompleteReceiver.receiveMessages() +// .filter(m -> messageId.equals(m.getMessageId())) +// .doOnNext(m -> sequenceNumbers.add(m.getSequenceNumber()))) +// .expectNextCount(numberOfEvents) +// .thenAwait(shortWait) // Give time for autoComplete to finish +// .thenCancel() +// .verify(TIMEOUT); +// +// // Assert messages are completed. +// for (Long sequenceNumber : sequenceNumbers) { +// StepVerifier.create(autoCompleteReceiver.peekMessage(sequenceNumber)) +// .verifyComplete(); +// } +// } +// +// /** +// * Asserts the length and values with in the map. +// */ +// private void assertMapValues(Map expectedMap, Map actualMap) { +// assertTrue(actualMap.size() >= expectedMap.size()); +// for (String key : expectedMap.keySet()) { +// assertEquals(expectedMap.get(key), actualMap.get(key), "Value is not equal for Key " + key); +// } +// } +// /** * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. */ @@ -1517,7 +1552,7 @@ private Mono sendMessage(ServiceBusMessage message) { logMessage(message, sender.getEntityPath(), "sent"); }); } - +// /** * Class represents various options while creating receiver/sender client. */ diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index f6da6d0d638b..79a4e51da4f7 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -3,896 +3,900 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.models.AmqpMessageBody; -import com.azure.core.util.IterableStream; -import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.implementation.DispositionStatus; -import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import com.azure.messaging.servicebus.models.AbandonOptions; -import com.azure.messaging.servicebus.models.CompleteOptions; -import com.azure.messaging.servicebus.models.DeadLetterOptions; -import com.azure.messaging.servicebus.models.DeferOptions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; -import org.junit.jupiter.params.provider.MethodSource; +class ServiceBusReceiverClientIntegrationTest { -import java.nio.charset.Charset; -import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -/** - * Integration tests for {@link com.azure.messaging.servicebus.ServiceBusReceiverClient} from queues or subscriptions. - */ -@Tag("integration") -@Execution(ExecutionMode.SAME_THREAD) -class ServiceBusReceiverClientIntegrationTest extends IntegrationTestBase { - private static final ClientLogger LOGGER = new ClientLogger(ServiceBusReceiverClientIntegrationTest.class); - - private final AtomicInteger messagesPending = new AtomicInteger(); - private final AtomicReference> messagesDeferred = new AtomicReference<>(new ArrayList<>()); - - private ServiceBusReceiverClient receiver; - private ServiceBusSenderClient sender; - private ServiceBusSessionReceiverClient sessionReceiver; - - protected ServiceBusReceiverClientIntegrationTest() { - super(new ClientLogger(ServiceBusReceiverClientIntegrationTest.class)); - } - - @Override - protected void beforeTest() { - sessionId = UUID.randomUUID().toString(); - } - - @Override - protected void afterTest() { - dispose(receiver, sender, sessionReceiver); - } - - /** - * Verifies that we can only call receive() multiple times and with one of the receive does timeout. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); - final int maxMessages = 2; - final int totalReceive = 2; - final Duration shortTimeOut = Duration.ofSeconds(7); - int receivedMessageCount; - int totalReceivedCount = 0; - - final String messageId = UUID.randomUUID().toString(); - List messageList = new ArrayList<>(); - for (int i = 0; i < totalReceive * maxMessages; ++i) { - messageList.add(getMessage(messageId, isSessionEnabled)); - } - sendMessages(messageList); - - setReceiver(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); - - List messages; - // Act & Assert - for (int i = 0; i < totalReceive; ++i) { - IterableStream received = receiver.receiveMessages(maxMessages, shortTimeOut); - messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - receivedMessageCount = 0; - for (ServiceBusReceivedMessage receivedMessage : messages) { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - ++receivedMessageCount; - } - assertEquals(maxMessages, receivedMessageCount); - totalReceivedCount += receivedMessageCount; - } - - assertEquals(totalReceive * maxMessages, totalReceivedCount); - } - - /** - * Verifies that we can only call receive() multiple times. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - final int maxMessagesEachReceive = 3; - final int totalReceiver = 7; - final Duration shortTimeOut = Duration.ofSeconds(8); - - final String messageId = UUID.randomUUID().toString(); - final List messageList = new ArrayList<>(); - for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { - messageList.add(getMessage(messageId, isSessionEnabled)); - } - - sendMessages(messageList); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Act & Assert - List messages; - - int receivedMessageCount; - int totalReceivedCount = 0; - for (int i = 0; i < totalReceiver; ++i) { - IterableStream received = receiver.receiveMessages(maxMessagesEachReceive, shortTimeOut); - messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - receivedMessageCount = 0; - for (ServiceBusReceivedMessage receivedMessage : messages) { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - ++receivedMessageCount; - } - assertEquals(maxMessagesEachReceive, receivedMessageCount); - totalReceivedCount += receivedMessageCount; - } - - assertEquals(totalReceiver * maxMessagesEachReceive, totalReceivedCount); - } - - /** - * Verifies that we can only call receive() multiple times. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - final int maxMessagesEachReceive = 3; - final int totalReceiver = 3; - final Duration shortTimeOut = Duration.ofSeconds(4); - - final String messageId = UUID.randomUUID().toString(); - final List messageList = new ArrayList<>(); - for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { - messageList.add(getMessage(messageId, isSessionEnabled)); - } - - sendMessages(messageList); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Act & Assert - AtomicInteger totalReceivedMessages = new AtomicInteger(); - List receiverThreads = new ArrayList<>(); - for (int i = 0; i < totalReceiver; ++i) { - Thread thread = new Thread(() -> { - IterableStream received = receiver. - receiveMessages(maxMessagesEachReceive, shortTimeOut); - List messages1 = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - int receivedMessageCount = 0; - long lastSequenceReceiver = 0; - for (ServiceBusReceivedMessage receivedMessage : messages1) { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - assertTrue(receivedMessage.getSequenceNumber() > lastSequenceReceiver); - lastSequenceReceiver = receivedMessage.getSequenceNumber(); - messagesPending.decrementAndGet(); - ++receivedMessageCount; - } - totalReceivedMessages.addAndGet(receivedMessageCount); - assertTrue(receivedMessageCount >= 1); - }); - receiverThreads.add(thread); - } - - receiverThreads.forEach(Thread::start); - - receiverThreads.forEach(t -> { - try { - t.join(TIMEOUT.toMillis()); - } catch (InterruptedException e) { - fail("Error in receiving messages: " + e.getMessage()); - } - }); - assertTrue(totalReceivedMessages.get() >= totalReceiver); - } - - /** - * Verifies that we can send and receive two messages. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); - int maxMessages = 4; - int messagesToSend = 4; - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message); - sendMessage(message); - sendMessage(message); - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); - - // Act - IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); - List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - - // Assert - int receivedMessageCount = 0; - final long startTime = System.currentTimeMillis(); - for (ServiceBusReceivedMessage receivedMessage : messages) { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - ++receivedMessageCount; - } - final long endTime = System.currentTimeMillis(); - assertEquals(messagesToSend, receivedMessageCount); - assertTrue(TIMEOUT.toMillis() > (endTime - startTime)); - } - - /** - * Verifies that we do not receive any message in given timeout. - */ - @Test - void receiveNoMessage() { - // Arrange - boolean isSessionEnabled = false; - setReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_RECEIVE_NO_MESSAGES, isSessionEnabled); - int howManyMessage = 2; - long noMessages = 0; - - // Act - final IterableStream received = receiver.receiveMessages(howManyMessage, - Duration.ofSeconds(15)); - List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - // Assert - assertEquals(noMessages, messages.size()); - } - - /** - * Verifies that we can send, receive one message and settle on non session entity. - */ - @ParameterizedTest - @EnumSource(DispositionStatus.class) - void transactionMessageAndSettle(DispositionStatus dispositionStatus) { - // Arrange - final boolean isSessionEnabled = false; - final MessagingEntityType entityType = MessagingEntityType.QUEUE; - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - int maxMessages = 1; - final String deadLetterReason = "testing"; - - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message); - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Act & Assert - final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); - List messageList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - - final ServiceBusTransactionContext transaction = receiver.createTransaction(); - - assertEquals(maxMessages, messageList.size()); - - ServiceBusReceivedMessage receivedMessage = messageList.get(0); - - switch (dispositionStatus) { - case COMPLETED: - receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction)); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - break; - case ABANDONED: - receiver.abandon(receivedMessage, new AbandonOptions() - .setTransactionContext(transaction)); - logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); - break; - case SUSPENDED: - DeadLetterOptions deadLetterOptions = new DeadLetterOptions() - .setDeadLetterReason(deadLetterReason) - .setTransactionContext(transaction); - receiver.deadLetter(receivedMessage, deadLetterOptions); - logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); - break; - case DEFERRED: - receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction)); - logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); - break; - case RELEASED: - break; - default: - throw LOGGER.logExceptionAsWarning(new IllegalArgumentException( - "Disposition status not recognized for this test case: " + dispositionStatus)); - } - - receiver.commitTransaction(transaction); - } - - /** - * Verifies that we can send and receive one messages. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - int maxMessages = 1; - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message); - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Act - final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); - List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - // Assert - final AtomicInteger receivedMessageCount = new AtomicInteger(); - messages.forEach(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - receivedMessageCount.incrementAndGet(); - }); - - assertEquals(maxMessages, receivedMessageCount.get()); - } - - /** - * Verifies that we can send and peek a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - // Act - ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); - logMessage(receivedMessage, receiver.getEntityPath(), "peeked messages"); - - // Assert - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - } - - /** - * Verifies that an empty entity does not error when peeked. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); - - // Act - final ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); - - // Assert - assertNull(receivedMessage); - } - - /** - * Verifies that we can send and peek a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final int maxMessages = 1; - - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(received); - - List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - assertEquals(maxMessages, messages.size()); - final ServiceBusReceivedMessage receivedMessage = messages.get(0); - assertNotNull(receivedMessage); - - // Act - final ServiceBusReceivedMessage receivedPeekMessage = receiver.peekMessage(receivedMessage.getSequenceNumber()); - logMessage(receivedPeekMessage, receiver.getEntityPath(), "peeked message"); - - // Assert - assertEquals(receivedMessage.getSequenceNumber(), receivedPeekMessage.getSequenceNumber()); - assertMessageEquals(receivedPeekMessage, messageId, isSessionEnabled); - - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - } - - /** - * Verifies that we can send and peek a batch of messages. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { - // Arrange - setSender(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); - final byte[] payload = "peek-message".getBytes(Charset.defaultCharset()); - final int maxMessages = 4; - - List messagesToSend = IntStream.range(0, maxMessages) - .mapToObj(i -> getMessage(String.format("%s-%s-%s", entityType, isSessionEnabled, i), - isSessionEnabled, AmqpMessageBody.fromData(payload))) - .collect(Collectors.toList()); - Set messageIds = messagesToSend.stream().map(ServiceBusMessage::getMessageId).collect(Collectors.toSet()); - - setReceiver(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); - List filtered = new ArrayList<>(); - AtomicInteger iterations = new AtomicInteger(0); - - // Act - Thread peekMessages = new Thread(() -> { - // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times - // https://github.com/Azure/azure-sdk-for-java/issues/21168 - while (iterations.getAndIncrement() < 10 && filtered.size() < maxMessages) { - receiver.peekMessages(maxMessages) - .forEach(m -> { - logMessage(m, receiver.getEntityPath(), "peeked messages"); - if (messageIds.contains(m.getMessageId())) { - filtered.add(m); - } - }); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - fail(); - } - } - }); - - peekMessages.start(); - toClose((AutoCloseable) () -> peekMessages.interrupt()); - - messagesToSend.forEach(message -> sendMessage(message)); - peekMessages.join(TIMEOUT.toMillis()); - - LOGGER.atInfo() - .addKeyValue("received", filtered.size()) - .addKeyValue("iterations", iterations.get()) - .addKeyValue("isSessionEnabled", isSessionEnabled) - .log("done receiving"); - - // Assert - assertEquals(maxMessages, filtered.size()); - } - - /** - * Verifies that an empty entity does not error when a batch is peeked. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); - final int maxMessages = 10; - - // Act - final IterableStream received = receiver.peekMessages(maxMessages); - // Assert - assertNotNull(received); - - List messages = logReceivedMessages(received, receiver.getEntityPath(), "peeked messages"); - final Optional anyMessages = messages.stream().findAny(); - assertFalse(anyMessages.isPresent()); - } - - /** - * Verifies that we can send and peek a batch of messages. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void peekMessagesFromSequence(MessagingEntityType entityType) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - final int maxMessages = 2; - final int fromSequenceNumber = 1; - - sendMessage(message); - sendMessage(message); - - setReceiver(entityType, 0, false); - - // Act - IterableStream iterableMessages = receiver.peekMessages(maxMessages, fromSequenceNumber); - - // Assert - final List asList = logReceivedMessages(iterableMessages, receiver.getEntityPath(), "peeked messages"); - assertEquals(maxMessages, asList.size()); - - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - assertTrue(receivedMessage.getSequenceNumber() >= fromSequenceNumber); - } - - /** - * Verifies that we can dead-letter a message. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final int maxMessages = 1; - - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(context); - - final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - - // Assert & Act - receiver.deadLetter(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); - messagesPending.decrementAndGet(); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final int maxMessages = 1; - - sendMessage(message); - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(context); - - final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); - - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - - // Assert & Act - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - } - - /** - * Verifies that we can renew message lock. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedException { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - final int maxMessages = 1; - - // Blocking here because it is not part of the scenario we want to test. - sendMessage(message); - - setReceiver(entityType, 0, false); - - final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(context); - - final List asList = context.stream().collect(Collectors.toList()); - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - assertNotNull(receivedMessage.getLockedUntil()); - - final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); - logMessage(receivedMessage, receiver.getEntityPath(), "received message, locked until " + initialLock); - - // Assert & Act - try { - TimeUnit.SECONDS.sleep(5); // Let some lock duration expire. - OffsetDateTime lockedUntil = receiver.renewMessageLock(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "renewed lock"); - assertTrue(lockedUntil.isAfter(initialLock), - String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", - lockedUntil, initialLock)); - } finally { - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.decrementAndGet(); - } - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final int maxMessages = 1; - - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(context); - - final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); - - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - - // Assert & Act - receiver.abandon(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); - // Cleanup - int messagesCompleted = completeMessages(receiver, maxMessages); - messagesPending.addAndGet(-messagesCompleted); - } - - /** - * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") - @ParameterizedTest - void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, false); - final int maxMessages = 1; - - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); - - final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(context); - - final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - - receiver.defer(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); - final ServiceBusReceivedMessage receivedDeferredMessage = receiver - .receiveDeferredMessage(receivedMessage.getSequenceNumber()); - - assertNotNull(receivedDeferredMessage); - assertEquals(receivedMessage.getSequenceNumber(), receivedDeferredMessage.getSequenceNumber()); - - // Assert & Act - switch (dispositionStatus) { - case ABANDONED: - receiver.abandon(receivedDeferredMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); - messagesDeferred.get().add(receivedMessage.getSequenceNumber()); - break; - case SUSPENDED: - receiver.deadLetter(receivedDeferredMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); - break; - case COMPLETED: - receiver.complete(receivedDeferredMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - break; - default: - throw LOGGER.logExceptionAsError(new IllegalArgumentException( - "Disposition status not recognized for this test case: " + dispositionStatus)); - } - - if (dispositionStatus == DispositionStatus.SUSPENDED || dispositionStatus == DispositionStatus.COMPLETED) { - messagesPending.decrementAndGet(); - } - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - final int maxMessages = 1; - sendMessage(message); - - setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); - final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(context); - - final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - - // Act & Assert - receiver.defer(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); - - // cleanup - final ServiceBusReceivedMessage deferred; - deferred = receiver.receiveDeferredMessage(receivedMessage.getSequenceNumber()); - logMessage(deferred, receiver.getEntityPath(), "received deffered messages"); - receiver.complete(deferred); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - messagesPending.addAndGet(-maxMessages); - } - - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest - void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType, boolean isSessionEnabled) { - // Arrange - setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); - final int maxMessages = 1; - - Map sentProperties = messageToSend.getApplicationProperties(); - sentProperties.put("NullProperty", null); - sentProperties.put("BooleanProperty", true); - sentProperties.put("ByteProperty", (byte) 1); - sentProperties.put("ShortProperty", (short) 2); - sentProperties.put("IntProperty", 3); - sentProperties.put("LongProperty", 4L); - sentProperties.put("FloatProperty", 5.5f); - sentProperties.put("DoubleProperty", 6.6f); - sentProperties.put("CharProperty", 'z'); - sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); - sentProperties.put("StringProperty", "string"); - - sendMessage(messageToSend); - - setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); - - // Assert & Act - final IterableStream received = - receiver.receiveMessages(maxMessages, TIMEOUT); - assertNotNull(received); - - final List asList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); - - assertEquals(maxMessages, asList.size()); - final ServiceBusReceivedMessage receivedMessage = asList.get(0); - assertNotNull(receivedMessage); - - messagesPending.decrementAndGet(); - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - - final Map receivedProps = receivedMessage.getApplicationProperties(); - - assertEquals(sentProperties.size(), receivedProps.size()); - - for (Map.Entry sentEntry : sentProperties.entrySet()) { - if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { - assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) receivedProps.get(sentEntry.getKey())); - } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { - final Object expected = sentEntry.getValue(); - final Object actual = receivedProps.get(sentEntry.getKey()); - - assertEquals(expected, actual, String.format( - "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, - actual)); - } - } - receiver.complete(receivedMessage); - logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); - } - - private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { - setReceiver(entityType, entityIndex, isSessionEnabled, false); - } - - private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { - setSender(entityType, entityIndex, isSessionEnabled, false); - } - - private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); - } - - private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { - - if (isSessionEnabled) { - assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection, null) - .buildClient()); - this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId)); - } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection) - .buildClient()); - } - } - - private void sendMessages(List messageList) { - sender.sendMessages(messageList); - int number = messagesPending.getAndSet(messageList.size()); - logMessages(messageList, sender.getEntityPath(), "sendMessages"); - LOGGER.atInfo().addKeyValue("number", number).log("message sent"); - } - - private void sendMessage(ServiceBusMessage message) { - sender.sendMessage(message); - logMessage(message, sender.getEntityPath(), "sent"); - LOGGER.atInfo() - .addKeyValue("number", messagesPending.incrementAndGet()) - .log("message sent"); - } - - private int completeMessages(ServiceBusReceiverClient client, int totalMessages) { - final IterableStream contextStream = client.receiveMessages(totalMessages, TIMEOUT); - final List asList = contextStream.stream().collect(Collectors.toList()); - for (ServiceBusReceivedMessage message : asList) { - receiver.complete(message); - logMessage(message, receiver.getEntityPath(), "received and completed"); - } - return asList.size(); - } } +// +//import com.azure.core.amqp.models.AmqpMessageBody; +//import com.azure.core.util.IterableStream; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.messaging.servicebus.implementation.DispositionStatus; +//import com.azure.messaging.servicebus.implementation.MessagingEntityType; +//import com.azure.messaging.servicebus.models.AbandonOptions; +//import com.azure.messaging.servicebus.models.CompleteOptions; +//import com.azure.messaging.servicebus.models.DeadLetterOptions; +//import com.azure.messaging.servicebus.models.DeferOptions; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.api.parallel.Execution; +//import org.junit.jupiter.api.parallel.ExecutionMode; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.EnumSource; +//import org.junit.jupiter.params.provider.MethodSource; +// +//import java.nio.charset.Charset; +//import java.time.Duration; +//import java.time.OffsetDateTime; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Map; +//import java.util.Optional; +//import java.util.Set; +//import java.util.UUID; +//import java.util.concurrent.TimeUnit; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.concurrent.atomic.AtomicReference; +//import java.util.stream.Collectors; +//import java.util.stream.IntStream; +// +//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH; +//import static org.junit.jupiter.api.Assertions.assertArrayEquals; +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertFalse; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertNull; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assertions.fail; +// +///** +// * Integration tests for {@link com.azure.messaging.servicebus.ServiceBusReceiverClient} from queues or subscriptions. +// */ +//@Tag("integration") +//@Execution(ExecutionMode.SAME_THREAD) +//class ServiceBusReceiverClientIntegrationTest extends IntegrationTestBase { +// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusReceiverClientIntegrationTest.class); +// +// private final AtomicInteger messagesPending = new AtomicInteger(); +// private final AtomicReference> messagesDeferred = new AtomicReference<>(new ArrayList<>()); +// +// private ServiceBusReceiverClient receiver; +// private ServiceBusSenderClient sender; +// private ServiceBusSessionReceiverClient sessionReceiver; +// +// protected ServiceBusReceiverClientIntegrationTest() { +// super(new ClientLogger(ServiceBusReceiverClientIntegrationTest.class)); +// } +// +// @Override +// protected void beforeTest() { +// sessionId = UUID.randomUUID().toString(); +// } +// +// @Override +// protected void afterTest() { +// dispose(receiver, sender, sessionReceiver); +// } +// +// /** +// * Verifies that we can only call receive() multiple times and with one of the receive does timeout. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); +// final int maxMessages = 2; +// final int totalReceive = 2; +// final Duration shortTimeOut = Duration.ofSeconds(7); +// int receivedMessageCount; +// int totalReceivedCount = 0; +// +// final String messageId = UUID.randomUUID().toString(); +// List messageList = new ArrayList<>(); +// for (int i = 0; i < totalReceive * maxMessages; ++i) { +// messageList.add(getMessage(messageId, isSessionEnabled)); +// } +// sendMessages(messageList); +// +// setReceiver(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); +// +// List messages; +// // Act & Assert +// for (int i = 0; i < totalReceive; ++i) { +// IterableStream received = receiver.receiveMessages(maxMessages, shortTimeOut); +// messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// receivedMessageCount = 0; +// for (ServiceBusReceivedMessage receivedMessage : messages) { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// ++receivedMessageCount; +// } +// assertEquals(maxMessages, receivedMessageCount); +// totalReceivedCount += receivedMessageCount; +// } +// +// assertEquals(totalReceive * maxMessages, totalReceivedCount); +// } +// +// /** +// * Verifies that we can only call receive() multiple times. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// final int maxMessagesEachReceive = 3; +// final int totalReceiver = 7; +// final Duration shortTimeOut = Duration.ofSeconds(8); +// +// final String messageId = UUID.randomUUID().toString(); +// final List messageList = new ArrayList<>(); +// for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { +// messageList.add(getMessage(messageId, isSessionEnabled)); +// } +// +// sendMessages(messageList); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Act & Assert +// List messages; +// +// int receivedMessageCount; +// int totalReceivedCount = 0; +// for (int i = 0; i < totalReceiver; ++i) { +// IterableStream received = receiver.receiveMessages(maxMessagesEachReceive, shortTimeOut); +// messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// receivedMessageCount = 0; +// for (ServiceBusReceivedMessage receivedMessage : messages) { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// ++receivedMessageCount; +// } +// assertEquals(maxMessagesEachReceive, receivedMessageCount); +// totalReceivedCount += receivedMessageCount; +// } +// +// assertEquals(totalReceiver * maxMessagesEachReceive, totalReceivedCount); +// } +// +// /** +// * Verifies that we can only call receive() multiple times. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// final int maxMessagesEachReceive = 3; +// final int totalReceiver = 3; +// final Duration shortTimeOut = Duration.ofSeconds(4); +// +// final String messageId = UUID.randomUUID().toString(); +// final List messageList = new ArrayList<>(); +// for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { +// messageList.add(getMessage(messageId, isSessionEnabled)); +// } +// +// sendMessages(messageList); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Act & Assert +// AtomicInteger totalReceivedMessages = new AtomicInteger(); +// List receiverThreads = new ArrayList<>(); +// for (int i = 0; i < totalReceiver; ++i) { +// Thread thread = new Thread(() -> { +// IterableStream received = receiver. +// receiveMessages(maxMessagesEachReceive, shortTimeOut); +// List messages1 = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// int receivedMessageCount = 0; +// long lastSequenceReceiver = 0; +// for (ServiceBusReceivedMessage receivedMessage : messages1) { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// assertTrue(receivedMessage.getSequenceNumber() > lastSequenceReceiver); +// lastSequenceReceiver = receivedMessage.getSequenceNumber(); +// messagesPending.decrementAndGet(); +// ++receivedMessageCount; +// } +// totalReceivedMessages.addAndGet(receivedMessageCount); +// assertTrue(receivedMessageCount >= 1); +// }); +// receiverThreads.add(thread); +// } +// +// receiverThreads.forEach(Thread::start); +// +// receiverThreads.forEach(t -> { +// try { +// t.join(TIMEOUT.toMillis()); +// } catch (InterruptedException e) { +// fail("Error in receiving messages: " + e.getMessage()); +// } +// }); +// assertTrue(totalReceivedMessages.get() >= totalReceiver); +// } +// +// /** +// * Verifies that we can send and receive two messages. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); +// int maxMessages = 4; +// int messagesToSend = 4; +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message); +// sendMessage(message); +// sendMessage(message); +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); +// +// // Act +// IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); +// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// +// // Assert +// int receivedMessageCount = 0; +// final long startTime = System.currentTimeMillis(); +// for (ServiceBusReceivedMessage receivedMessage : messages) { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// ++receivedMessageCount; +// } +// final long endTime = System.currentTimeMillis(); +// assertEquals(messagesToSend, receivedMessageCount); +// assertTrue(TIMEOUT.toMillis() > (endTime - startTime)); +// } +// +// /** +// * Verifies that we do not receive any message in given timeout. +// */ +// @Test +// void receiveNoMessage() { +// // Arrange +// boolean isSessionEnabled = false; +// setReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_RECEIVE_NO_MESSAGES, isSessionEnabled); +// int howManyMessage = 2; +// long noMessages = 0; +// +// // Act +// final IterableStream received = receiver.receiveMessages(howManyMessage, +// Duration.ofSeconds(15)); +// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// // Assert +// assertEquals(noMessages, messages.size()); +// } +// +// /** +// * Verifies that we can send, receive one message and settle on non session entity. +// */ +// @ParameterizedTest +// @EnumSource(DispositionStatus.class) +// void transactionMessageAndSettle(DispositionStatus dispositionStatus) { +// // Arrange +// final boolean isSessionEnabled = false; +// final MessagingEntityType entityType = MessagingEntityType.QUEUE; +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// int maxMessages = 1; +// final String deadLetterReason = "testing"; +// +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message); +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Act & Assert +// final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); +// List messageList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// +// final ServiceBusTransactionContext transaction = receiver.createTransaction(); +// +// assertEquals(maxMessages, messageList.size()); +// +// ServiceBusReceivedMessage receivedMessage = messageList.get(0); +// +// switch (dispositionStatus) { +// case COMPLETED: +// receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction)); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// break; +// case ABANDONED: +// receiver.abandon(receivedMessage, new AbandonOptions() +// .setTransactionContext(transaction)); +// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); +// break; +// case SUSPENDED: +// DeadLetterOptions deadLetterOptions = new DeadLetterOptions() +// .setDeadLetterReason(deadLetterReason) +// .setTransactionContext(transaction); +// receiver.deadLetter(receivedMessage, deadLetterOptions); +// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); +// break; +// case DEFERRED: +// receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction)); +// logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); +// break; +// case RELEASED: +// break; +// default: +// throw LOGGER.logExceptionAsWarning(new IllegalArgumentException( +// "Disposition status not recognized for this test case: " + dispositionStatus)); +// } +// +// receiver.commitTransaction(transaction); +// } +// +// /** +// * Verifies that we can send and receive one messages. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// int maxMessages = 1; +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message); +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Act +// final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); +// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// // Assert +// final AtomicInteger receivedMessageCount = new AtomicInteger(); +// messages.forEach(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// receivedMessageCount.incrementAndGet(); +// }); +// +// assertEquals(maxMessages, receivedMessageCount.get()); +// } +// +// /** +// * Verifies that we can send and peek a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// // Act +// ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); +// logMessage(receivedMessage, receiver.getEntityPath(), "peeked messages"); +// +// // Assert +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// } +// +// /** +// * Verifies that an empty entity does not error when peeked. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); +// +// // Act +// final ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); +// +// // Assert +// assertNull(receivedMessage); +// } +// +// /** +// * Verifies that we can send and peek a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final int maxMessages = 1; +// +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(received); +// +// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// assertEquals(maxMessages, messages.size()); +// final ServiceBusReceivedMessage receivedMessage = messages.get(0); +// assertNotNull(receivedMessage); +// +// // Act +// final ServiceBusReceivedMessage receivedPeekMessage = receiver.peekMessage(receivedMessage.getSequenceNumber()); +// logMessage(receivedPeekMessage, receiver.getEntityPath(), "peeked message"); +// +// // Assert +// assertEquals(receivedMessage.getSequenceNumber(), receivedPeekMessage.getSequenceNumber()); +// assertMessageEquals(receivedPeekMessage, messageId, isSessionEnabled); +// +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// } +// +// /** +// * Verifies that we can send and peek a batch of messages. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { +// // Arrange +// setSender(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); +// final byte[] payload = "peek-message".getBytes(Charset.defaultCharset()); +// final int maxMessages = 4; +// +// List messagesToSend = IntStream.range(0, maxMessages) +// .mapToObj(i -> getMessage(String.format("%s-%s-%s", entityType, isSessionEnabled, i), +// isSessionEnabled, AmqpMessageBody.fromData(payload))) +// .collect(Collectors.toList()); +// Set messageIds = messagesToSend.stream().map(ServiceBusMessage::getMessageId).collect(Collectors.toSet()); +// +// setReceiver(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); +// List filtered = new ArrayList<>(); +// AtomicInteger iterations = new AtomicInteger(0); +// +// // Act +// Thread peekMessages = new Thread(() -> { +// // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times +// // https://github.com/Azure/azure-sdk-for-java/issues/21168 +// while (iterations.getAndIncrement() < 10 && filtered.size() < maxMessages) { +// receiver.peekMessages(maxMessages) +// .forEach(m -> { +// logMessage(m, receiver.getEntityPath(), "peeked messages"); +// if (messageIds.contains(m.getMessageId())) { +// filtered.add(m); +// } +// }); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// fail(); +// } +// } +// }); +// +// peekMessages.start(); +// toClose((AutoCloseable) () -> peekMessages.interrupt()); +// +// messagesToSend.forEach(message -> sendMessage(message)); +// peekMessages.join(TIMEOUT.toMillis()); +// +// LOGGER.atInfo() +// .addKeyValue("received", filtered.size()) +// .addKeyValue("iterations", iterations.get()) +// .addKeyValue("isSessionEnabled", isSessionEnabled) +// .log("done receiving"); +// +// // Assert +// assertEquals(maxMessages, filtered.size()); +// } +// +// /** +// * Verifies that an empty entity does not error when a batch is peeked. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); +// final int maxMessages = 10; +// +// // Act +// final IterableStream received = receiver.peekMessages(maxMessages); +// // Assert +// assertNotNull(received); +// +// List messages = logReceivedMessages(received, receiver.getEntityPath(), "peeked messages"); +// final Optional anyMessages = messages.stream().findAny(); +// assertFalse(anyMessages.isPresent()); +// } +// +// /** +// * Verifies that we can send and peek a batch of messages. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void peekMessagesFromSequence(MessagingEntityType entityType) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// final int maxMessages = 2; +// final int fromSequenceNumber = 1; +// +// sendMessage(message); +// sendMessage(message); +// +// setReceiver(entityType, 0, false); +// +// // Act +// IterableStream iterableMessages = receiver.peekMessages(maxMessages, fromSequenceNumber); +// +// // Assert +// final List asList = logReceivedMessages(iterableMessages, receiver.getEntityPath(), "peeked messages"); +// assertEquals(maxMessages, asList.size()); +// +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// assertTrue(receivedMessage.getSequenceNumber() >= fromSequenceNumber); +// } +// +// /** +// * Verifies that we can dead-letter a message. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final int maxMessages = 1; +// +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(context); +// +// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// +// // Assert & Act +// receiver.deadLetter(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); +// messagesPending.decrementAndGet(); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final int maxMessages = 1; +// +// sendMessage(message); +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(context); +// +// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); +// +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// +// // Assert & Act +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// } +// +// /** +// * Verifies that we can renew message lock. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedException { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// final int maxMessages = 1; +// +// // Blocking here because it is not part of the scenario we want to test. +// sendMessage(message); +// +// setReceiver(entityType, 0, false); +// +// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(context); +// +// final List asList = context.stream().collect(Collectors.toList()); +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// assertNotNull(receivedMessage.getLockedUntil()); +// +// final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); +// logMessage(receivedMessage, receiver.getEntityPath(), "received message, locked until " + initialLock); +// +// // Assert & Act +// try { +// TimeUnit.SECONDS.sleep(5); // Let some lock duration expire. +// OffsetDateTime lockedUntil = receiver.renewMessageLock(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "renewed lock"); +// assertTrue(lockedUntil.isAfter(initialLock), +// String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", +// lockedUntil, initialLock)); +// } finally { +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.decrementAndGet(); +// } +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final int maxMessages = 1; +// +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(context); +// +// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); +// +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// +// // Assert & Act +// receiver.abandon(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); +// // Cleanup +// int messagesCompleted = completeMessages(receiver, maxMessages); +// messagesPending.addAndGet(-messagesCompleted); +// } +// +// /** +// * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") +// @ParameterizedTest +// void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, false); +// final int maxMessages = 1; +// +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); +// +// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(context); +// +// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// +// receiver.defer(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); +// final ServiceBusReceivedMessage receivedDeferredMessage = receiver +// .receiveDeferredMessage(receivedMessage.getSequenceNumber()); +// +// assertNotNull(receivedDeferredMessage); +// assertEquals(receivedMessage.getSequenceNumber(), receivedDeferredMessage.getSequenceNumber()); +// +// // Assert & Act +// switch (dispositionStatus) { +// case ABANDONED: +// receiver.abandon(receivedDeferredMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); +// messagesDeferred.get().add(receivedMessage.getSequenceNumber()); +// break; +// case SUSPENDED: +// receiver.deadLetter(receivedDeferredMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); +// break; +// case COMPLETED: +// receiver.complete(receivedDeferredMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// break; +// default: +// throw LOGGER.logExceptionAsError(new IllegalArgumentException( +// "Disposition status not recognized for this test case: " + dispositionStatus)); +// } +// +// if (dispositionStatus == DispositionStatus.SUSPENDED || dispositionStatus == DispositionStatus.COMPLETED) { +// messagesPending.decrementAndGet(); +// } +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// final int maxMessages = 1; +// sendMessage(message); +// +// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); +// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(context); +// +// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// +// // Act & Assert +// receiver.defer(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); +// +// // cleanup +// final ServiceBusReceivedMessage deferred; +// deferred = receiver.receiveDeferredMessage(receivedMessage.getSequenceNumber()); +// logMessage(deferred, receiver.getEntityPath(), "received deffered messages"); +// receiver.complete(deferred); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// messagesPending.addAndGet(-maxMessages); +// } +// +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") +// @ParameterizedTest +// void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType, boolean isSessionEnabled) { +// // Arrange +// setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); +// final int maxMessages = 1; +// +// Map sentProperties = messageToSend.getApplicationProperties(); +// sentProperties.put("NullProperty", null); +// sentProperties.put("BooleanProperty", true); +// sentProperties.put("ByteProperty", (byte) 1); +// sentProperties.put("ShortProperty", (short) 2); +// sentProperties.put("IntProperty", 3); +// sentProperties.put("LongProperty", 4L); +// sentProperties.put("FloatProperty", 5.5f); +// sentProperties.put("DoubleProperty", 6.6f); +// sentProperties.put("CharProperty", 'z'); +// sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); +// sentProperties.put("StringProperty", "string"); +// +// sendMessage(messageToSend); +// +// setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); +// +// // Assert & Act +// final IterableStream received = +// receiver.receiveMessages(maxMessages, TIMEOUT); +// assertNotNull(received); +// +// final List asList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); +// +// assertEquals(maxMessages, asList.size()); +// final ServiceBusReceivedMessage receivedMessage = asList.get(0); +// assertNotNull(receivedMessage); +// +// messagesPending.decrementAndGet(); +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// +// final Map receivedProps = receivedMessage.getApplicationProperties(); +// +// assertEquals(sentProperties.size(), receivedProps.size()); +// +// for (Map.Entry sentEntry : sentProperties.entrySet()) { +// if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { +// assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) receivedProps.get(sentEntry.getKey())); +// } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { +// final Object expected = sentEntry.getValue(); +// final Object actual = receivedProps.get(sentEntry.getKey()); +// +// assertEquals(expected, actual, String.format( +// "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, +// actual)); +// } +// } +// receiver.complete(receivedMessage); +// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); +// } +// +// private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { +// setReceiver(entityType, entityIndex, isSessionEnabled, false); +// } +// +// private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { +// setSender(entityType, entityIndex, isSessionEnabled, false); +// } +// +// private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { +// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); +// } +// +// private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { +// +// if (isSessionEnabled) { +// assertNotNull(sessionId, "'sessionId' should have been set."); +// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection, null) +// .buildClient()); +// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId)); +// } else { +// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection) +// .buildClient()); +// } +// } +// +// private void sendMessages(List messageList) { +// sender.sendMessages(messageList); +// int number = messagesPending.getAndSet(messageList.size()); +// logMessages(messageList, sender.getEntityPath(), "sendMessages"); +// LOGGER.atInfo().addKeyValue("number", number).log("message sent"); +// } +// +// private void sendMessage(ServiceBusMessage message) { +// sender.sendMessage(message); +// logMessage(message, sender.getEntityPath(), "sent"); +// LOGGER.atInfo() +// .addKeyValue("number", messagesPending.incrementAndGet()) +// .log("message sent"); +// } +// +// private int completeMessages(ServiceBusReceiverClient client, int totalMessages) { +// final IterableStream contextStream = client.receiveMessages(totalMessages, TIMEOUT); +// final List asList = contextStream.stream().collect(Collectors.toList()); +// for (ServiceBusReceivedMessage message : asList) { +// receiver.complete(message); +// logMessage(message, receiver.getEntityPath(), "received and completed"); +// } +// return asList.size(); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index 06d2170dc48b..b8a405473fa1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -3,554 +3,558 @@ package com.azure.messaging.servicebus; -import com.azure.core.util.logging.ClientLogger; -import com.azure.core.util.logging.LogLevel; -import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; -import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +class ServiceBusSenderAsyncClientIntegrationTest { -import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Integration tests for {@link ServiceBusSenderAsyncClient} from queues or subscriptions. - */ -@Tag("integration") -class ServiceBusSenderAsyncClientIntegrationTest extends IntegrationTestBase { - private static final ClientLogger LOGGER = new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class); - - private ServiceBusSenderAsyncClient sender; - private ServiceBusReceiverAsyncClient receiver; - private final AtomicInteger messagesPending = new AtomicInteger(); - - ServiceBusSenderAsyncClientIntegrationTest() { - super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); - } - - @Override - protected void beforeTest() { - sessionId = UUID.randomUUID().toString(); - } - - @Override - protected void afterTest() { - dispose(sender); - - final int numberOfMessages = messagesPending.get(); - if (numberOfMessages < 1) { - dispose(receiver); - return; - } - - try { - receiver.receiveMessages() - .take(numberOfMessages) - .map(message -> { - logger.info("Message received: {}", message.getSequenceNumber()); - return message; - }) - .timeout(Duration.ofSeconds(5), Mono.empty()) - .blockLast(); - } catch (Exception e) { - logger.warning("Error occurred when draining queue.", e); - } finally { - dispose(receiver); - } - } - - static Stream transactionMessageSendAndCompleteTransaction() { - return Stream.of( - Arguments.of(MessagingEntityType.QUEUE, true), - Arguments.of(MessagingEntityType.SUBSCRIPTION, true), - Arguments.of(MessagingEntityType.QUEUE, false), - Arguments.of(MessagingEntityType.SUBSCRIPTION, false) - ); - } - - /** - * Verifies that we can send a message to a non-session queue. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void nonSessionQueueSendMessage(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - - // Assert & Act - StepVerifier.create(sender.sendMessage(message).doOnSuccess(aVoid -> messagesPending.incrementAndGet())) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send a list of messages to a non-session entity. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void nonSessionEntitySendMessageList(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); - int count = 4; - - final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); - - // Assert & Act - StepVerifier.create(sender.sendMessages(messages) - .doOnSuccess(aVoid -> messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()))) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void nonSessionMessageBatch(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); - - final String messageId = UUID.randomUUID().toString(); - final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); - final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); - - // Assert & Act - StepVerifier.create(sender.createMessageBatch(options) - .flatMap(batch -> { - for (ServiceBusMessage message : messages) { - Assertions.assertTrue(batch.tryAddMessage(message)); - } - - return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); - })) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can send message to final destination using via-queue. - */ - @Disabled("The send via functionality is removing for first GA release, later we will come back to it.") - @Test - void viaQueueMessageSendTest() { - // Arrange - final Duration shortTimeout = Duration.ofSeconds(15); - final int viaIntermediateEntity = TestUtils.USE_CASE_TXN_1; - final int destinationEntity = TestUtils.USE_CASE_TXN_2; - final boolean shareConnection = true; - final MessagingEntityType entityType = MessagingEntityType.QUEUE; - final boolean isSessionEnabled = false; - final String messageId = UUID.randomUUID().toString(); - final int total = 1; - final int totalToDestination = 2; - final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); - final String viaQueueName = getQueueName(viaIntermediateEntity); - - setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); - - final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, - destinationEntity, false, shareConnection) - //.viaQueueName(viaQueueName) - .buildAsyncClient()); - final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, - destinationEntity, shareConnection) - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .disableAutoComplete() - .buildAsyncClient()); - - final AtomicReference transaction = new AtomicReference<>(); - - // Act - try { - StepVerifier.create(destination1ViaSender.createTransaction()) - .assertNext(transactionContext -> { - transaction.set(transactionContext); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - assertNotNull(transaction.get()); - - StepVerifier.create(sender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()) - .delaySubscription(Duration.ofSeconds(1))) - .expectComplete() - .verify(TIMEOUT); - - // Assert - // Verify message is received by final destination Entity - StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - - // Verify, intermediate-via queue has it delivered to intermediate Entity. - StepVerifier.create(receiver.receiveMessages().take(total).timeout(shortTimeout)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } finally { - destination1Receiver.close(); - destination1ViaSender.close(); - } - } - - - /** - * Verifies that we can send message to final destination using via-topic. - */ - @Disabled("The send via functionality is removed for first GA release, later we will come back to it.") - @Test - void viaTopicMessageSendTest() { - // Arrange - final Duration shortTimeout = Duration.ofSeconds(15); - final int viaIntermediateEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_1; - final int destinationEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_2; - final boolean shareConnection = true; - final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; - final boolean isSessionEnabled = false; - final String messageId = UUID.randomUUID().toString(); - final int total = 1; - final int totalToDestination = 2; - final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); - final String viaTopicName = getTopicName(viaIntermediateEntity); - - setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); - final ServiceBusReceiverAsyncClient intermediateReceiver = receiver; - final ServiceBusSenderAsyncClient intermediateSender = sender; - - final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, - destinationEntity, false, shareConnection) - //.viaTopicName(viaTopicName) - .buildAsyncClient()); - - final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, - destinationEntity, shareConnection) - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .disableAutoComplete() - .buildAsyncClient()); - - final AtomicReference transaction = new AtomicReference<>(); - - // Act - StepVerifier.create(destination1ViaSender.createTransaction()) - .assertNext(transactionContext -> { - transaction.set(transactionContext); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - assertNotNull(transaction.get()); - - StepVerifier.create(intermediateSender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) - .expectComplete() - .verify(TIMEOUT); - - // Assert - // Verify message is received by final destination Entity - StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - - // Verify, intermediate-via topic has it delivered to intermediate Entity. - StepVerifier.create(intermediateReceiver.receiveMessages().take(total).timeout(shortTimeout)) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can do following - * 1. create transaction - * 2. send message with transactionContext - * 3. Rollback/commit this transaction. - */ - @MethodSource - @ParameterizedTest - void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { - // Arrange - Duration shortTimeout = Duration.ofSeconds(15); - setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, USE_CREDENTIALS); - final boolean isSessionEnabled = false; - final String messageId = UUID.randomUUID().toString(); - final int total = 3; - final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); - - // Assert & Act - AtomicReference transaction = new AtomicReference<>(); - StepVerifier.create(sender.createTransaction()) - .assertNext(transactionContext -> { - transaction.set(transactionContext); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - assertNotNull(transaction.get()); - - // Assert & Act - StepVerifier.create(sender.sendMessages(messages, transaction.get())) - .expectComplete() - .verify(TIMEOUT); - if (isCommit) { - StepVerifier.create(sender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(receiver.receiveMessages().take(total)) - .assertNext(receivedMessage -> { - LOGGER.log(LogLevel.VERBOSE, () -> "1"); - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .assertNext(receivedMessage -> { - LOGGER.log(LogLevel.VERBOSE, () -> "2"); - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .assertNext(receivedMessage -> { - LOGGER.log(LogLevel.VERBOSE, () -> "3"); - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(shortTimeout); - } else { - StepVerifier.create(sender.rollbackTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(receiver.receiveMessages().take(total)) - .verifyTimeout(shortTimeout); - } - } - - /** - * Verifies that we can send using credentials. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void sendWithCredentials(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); - - final String messageId = UUID.randomUUID().toString(); - final List messages = TestUtils.getServiceBusMessages(5, messageId, CONTENTS_BYTES); - - // Act & Assert - StepVerifier.create(sender.createMessageBatch() - .flatMap(batch -> { - messages.forEach(m -> Assertions.assertTrue(batch.tryAddMessage(m))); - - return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); - })) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can create transaction, scheduleMessage and commit. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void transactionScheduleAndCommitTest(MessagingEntityType entityType) { - - // Arrange - boolean isSessionEnabled = false; - setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); - final Duration scheduleDuration = Duration.ofSeconds(3); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); - - // Assert & Act - AtomicReference transaction = new AtomicReference<>(); - StepVerifier.create(sender.createTransaction()) - .assertNext(transactionContext -> { - transaction.set(transactionContext); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(5), transaction.get())) - .assertNext(sequenceNumber -> { - assertNotNull(sequenceNumber); - assertTrue(sequenceNumber.intValue() > 0); - }) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(sender.commitTransaction(transaction.get())) - .expectComplete() - .verify(TIMEOUT); - StepVerifier.create(Mono.delay(scheduleDuration).then(receiver.receiveMessages().next())) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .expectComplete() - .verify(TIMEOUT); - } - - /** - * Verifies that we can create transaction, scheduleMessages and commit. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void transactionScheduleMessagesTest(MessagingEntityType entityType) { - - // Arrange - final boolean isSessionEnabled = false; - final int total = 2; - final Duration shortWait = Duration.ofSeconds(3); - - setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, USE_CREDENTIALS); - - final Duration scheduleDuration = Duration.ofSeconds(5); - final String messageId = UUID.randomUUID().toString(); - final List messages = new ArrayList<>(); - for (int i = 0; i < total; ++i) { - messages.add(getMessage(messageId, isSessionEnabled)); - } - - // Assert & Act - AtomicReference transaction = new AtomicReference<>(); - StepVerifier.create(sender.createTransaction()) - .assertNext(transactionContext -> { - transaction.set(transactionContext); - assertNotNull(transaction); - }) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration), transaction.get()).collectList()) - .assertNext(longs -> { - assertEquals(total, longs.size()); - }) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(sender.commitTransaction(transaction.get())) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(Mono.delay(scheduleDuration).thenMany(receiver.receiveMessages().take(total))) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .assertNext(receivedMessage -> { - assertMessageEquals(receivedMessage, messageId, isSessionEnabled); - messagesPending.decrementAndGet(); - }) - .thenAwait(shortWait) - .thenCancel() - .verify(TIMEOUT); - } - - /** - * Verifies that we can schedule messages and cancel them. - */ - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest - void cancelScheduledMessagesTest(MessagingEntityType entityType) { - - // Arrange - final boolean isSessionEnabled = false; - final Duration shortWaitTime = Duration.ofSeconds(5); - final int total = 2; - setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, USE_CREDENTIALS); - final Duration scheduleDuration = Duration.ofSeconds(15); - final String messageId = UUID.randomUUID().toString(); - final List messages = new ArrayList<>(); - for (int i = 0; i < total; ++i) { - messages.add(getMessage(messageId, isSessionEnabled)); - } - List seqNumbers = sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration)).collectList().block(shortWaitTime); - - // Assert & Act - Assertions.assertNotNull(seqNumbers); - Assertions.assertEquals(total, seqNumbers.size()); - - StepVerifier.create(sender.cancelScheduledMessages(seqNumbers)) - .expectComplete() - .verify(TIMEOUT); - - // The messages should have been cancelled and we should not find any messages. - StepVerifier.create(receiver.receiveMessages().take(total)) - .verifyTimeout(shortWaitTime); - } - - /** - * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. - */ - private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { - final boolean isSessionAware = false; - final boolean sharedConnection = true; - - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) - .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .disableAutoComplete() - .buildAsyncClient()); - } } +// +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.core.util.logging.LogLevel; +//import com.azure.messaging.servicebus.implementation.MessagingEntityType; +//import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; +//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.Disabled; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.Arguments; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.core.publisher.Mono; +//import reactor.test.StepVerifier; +// +//import java.time.Duration; +//import java.time.OffsetDateTime; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.UUID; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.concurrent.atomic.AtomicReference; +//import java.util.stream.Stream; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertTrue; +// +///** +// * Integration tests for {@link ServiceBusSenderAsyncClient} from queues or subscriptions. +// */ +//@Tag("integration") +//class ServiceBusSenderAsyncClientIntegrationTest extends IntegrationTestBase { +// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class); +// +// private ServiceBusSenderAsyncClient sender; +// private ServiceBusReceiverAsyncClient receiver; +// private final AtomicInteger messagesPending = new AtomicInteger(); +// +// ServiceBusSenderAsyncClientIntegrationTest() { +// super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); +// } +// +// @Override +// protected void beforeTest() { +// sessionId = UUID.randomUUID().toString(); +// } +// +// @Override +// protected void afterTest() { +// dispose(sender); +// +// final int numberOfMessages = messagesPending.get(); +// if (numberOfMessages < 1) { +// dispose(receiver); +// return; +// } +// +// try { +// receiver.receiveMessages() +// .take(numberOfMessages) +// .map(message -> { +// logger.info("Message received: {}", message.getSequenceNumber()); +// return message; +// }) +// .timeout(Duration.ofSeconds(5), Mono.empty()) +// .blockLast(); +// } catch (Exception e) { +// logger.warning("Error occurred when draining queue.", e); +// } finally { +// dispose(receiver); +// } +// } +// +// static Stream transactionMessageSendAndCompleteTransaction() { +// return Stream.of( +// Arguments.of(MessagingEntityType.QUEUE, true), +// Arguments.of(MessagingEntityType.SUBSCRIPTION, true), +// Arguments.of(MessagingEntityType.QUEUE, false), +// Arguments.of(MessagingEntityType.SUBSCRIPTION, false) +// ); +// } +// +// /** +// * Verifies that we can send a message to a non-session queue. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void nonSessionQueueSendMessage(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// +// // Assert & Act +// StepVerifier.create(sender.sendMessage(message).doOnSuccess(aVoid -> messagesPending.incrementAndGet())) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send a list of messages to a non-session entity. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void nonSessionEntitySendMessageList(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); +// int count = 4; +// +// final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); +// +// // Assert & Act +// StepVerifier.create(sender.sendMessages(messages) +// .doOnSuccess(aVoid -> messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()))) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void nonSessionMessageBatch(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); +// +// final String messageId = UUID.randomUUID().toString(); +// final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); +// final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); +// +// // Assert & Act +// StepVerifier.create(sender.createMessageBatch(options) +// .flatMap(batch -> { +// for (ServiceBusMessage message : messages) { +// Assertions.assertTrue(batch.tryAddMessage(message)); +// } +// +// return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); +// })) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can send message to final destination using via-queue. +// */ +// @Disabled("The send via functionality is removing for first GA release, later we will come back to it.") +// @Test +// void viaQueueMessageSendTest() { +// // Arrange +// final Duration shortTimeout = Duration.ofSeconds(15); +// final int viaIntermediateEntity = TestUtils.USE_CASE_TXN_1; +// final int destinationEntity = TestUtils.USE_CASE_TXN_2; +// final boolean shareConnection = true; +// final MessagingEntityType entityType = MessagingEntityType.QUEUE; +// final boolean isSessionEnabled = false; +// final String messageId = UUID.randomUUID().toString(); +// final int total = 1; +// final int totalToDestination = 2; +// final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); +// final String viaQueueName = getQueueName(viaIntermediateEntity); +// +// setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); +// +// final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, +// destinationEntity, false, shareConnection) +// //.viaQueueName(viaQueueName) +// .buildAsyncClient()); +// final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, +// destinationEntity, shareConnection) +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .disableAutoComplete() +// .buildAsyncClient()); +// +// final AtomicReference transaction = new AtomicReference<>(); +// +// // Act +// try { +// StepVerifier.create(destination1ViaSender.createTransaction()) +// .assertNext(transactionContext -> { +// transaction.set(transactionContext); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// assertNotNull(transaction.get()); +// +// StepVerifier.create(sender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()) +// .delaySubscription(Duration.ofSeconds(1))) +// .expectComplete() +// .verify(TIMEOUT); +// +// // Assert +// // Verify message is received by final destination Entity +// StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// // Verify, intermediate-via queue has it delivered to intermediate Entity. +// StepVerifier.create(receiver.receiveMessages().take(total).timeout(shortTimeout)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } finally { +// destination1Receiver.close(); +// destination1ViaSender.close(); +// } +// } +// +// +// /** +// * Verifies that we can send message to final destination using via-topic. +// */ +// @Disabled("The send via functionality is removed for first GA release, later we will come back to it.") +// @Test +// void viaTopicMessageSendTest() { +// // Arrange +// final Duration shortTimeout = Duration.ofSeconds(15); +// final int viaIntermediateEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_1; +// final int destinationEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_2; +// final boolean shareConnection = true; +// final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; +// final boolean isSessionEnabled = false; +// final String messageId = UUID.randomUUID().toString(); +// final int total = 1; +// final int totalToDestination = 2; +// final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); +// final String viaTopicName = getTopicName(viaIntermediateEntity); +// +// setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); +// final ServiceBusReceiverAsyncClient intermediateReceiver = receiver; +// final ServiceBusSenderAsyncClient intermediateSender = sender; +// +// final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, +// destinationEntity, false, shareConnection) +// //.viaTopicName(viaTopicName) +// .buildAsyncClient()); +// +// final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, +// destinationEntity, shareConnection) +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .disableAutoComplete() +// .buildAsyncClient()); +// +// final AtomicReference transaction = new AtomicReference<>(); +// +// // Act +// StepVerifier.create(destination1ViaSender.createTransaction()) +// .assertNext(transactionContext -> { +// transaction.set(transactionContext); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// assertNotNull(transaction.get()); +// +// StepVerifier.create(intermediateSender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) +// .expectComplete() +// .verify(TIMEOUT); +// +// // Assert +// // Verify message is received by final destination Entity +// StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// // Verify, intermediate-via topic has it delivered to intermediate Entity. +// StepVerifier.create(intermediateReceiver.receiveMessages().take(total).timeout(shortTimeout)) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can do following +// * 1. create transaction +// * 2. send message with transactionContext +// * 3. Rollback/commit this transaction. +// */ +// @MethodSource +// @ParameterizedTest +// void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { +// // Arrange +// Duration shortTimeout = Duration.ofSeconds(15); +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, USE_CREDENTIALS); +// final boolean isSessionEnabled = false; +// final String messageId = UUID.randomUUID().toString(); +// final int total = 3; +// final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); +// +// // Assert & Act +// AtomicReference transaction = new AtomicReference<>(); +// StepVerifier.create(sender.createTransaction()) +// .assertNext(transactionContext -> { +// transaction.set(transactionContext); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// assertNotNull(transaction.get()); +// +// // Assert & Act +// StepVerifier.create(sender.sendMessages(messages, transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// if (isCommit) { +// StepVerifier.create(sender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(receiver.receiveMessages().take(total)) +// .assertNext(receivedMessage -> { +// LOGGER.log(LogLevel.VERBOSE, () -> "1"); +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .assertNext(receivedMessage -> { +// LOGGER.log(LogLevel.VERBOSE, () -> "2"); +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .assertNext(receivedMessage -> { +// LOGGER.log(LogLevel.VERBOSE, () -> "3"); +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(shortTimeout); +// } else { +// StepVerifier.create(sender.rollbackTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(receiver.receiveMessages().take(total)) +// .verifyTimeout(shortTimeout); +// } +// } +// +// /** +// * Verifies that we can send using credentials. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void sendWithCredentials(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); +// +// final String messageId = UUID.randomUUID().toString(); +// final List messages = TestUtils.getServiceBusMessages(5, messageId, CONTENTS_BYTES); +// +// // Act & Assert +// StepVerifier.create(sender.createMessageBatch() +// .flatMap(batch -> { +// messages.forEach(m -> Assertions.assertTrue(batch.tryAddMessage(m))); +// +// return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); +// })) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can create transaction, scheduleMessage and commit. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void transactionScheduleAndCommitTest(MessagingEntityType entityType) { +// +// // Arrange +// boolean isSessionEnabled = false; +// setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); +// final Duration scheduleDuration = Duration.ofSeconds(3); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); +// +// // Assert & Act +// AtomicReference transaction = new AtomicReference<>(); +// StepVerifier.create(sender.createTransaction()) +// .assertNext(transactionContext -> { +// transaction.set(transactionContext); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(5), transaction.get())) +// .assertNext(sequenceNumber -> { +// assertNotNull(sequenceNumber); +// assertTrue(sequenceNumber.intValue() > 0); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(sender.commitTransaction(transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// StepVerifier.create(Mono.delay(scheduleDuration).then(receiver.receiveMessages().next())) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can create transaction, scheduleMessages and commit. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void transactionScheduleMessagesTest(MessagingEntityType entityType) { +// +// // Arrange +// final boolean isSessionEnabled = false; +// final int total = 2; +// final Duration shortWait = Duration.ofSeconds(3); +// +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, USE_CREDENTIALS); +// +// final Duration scheduleDuration = Duration.ofSeconds(5); +// final String messageId = UUID.randomUUID().toString(); +// final List messages = new ArrayList<>(); +// for (int i = 0; i < total; ++i) { +// messages.add(getMessage(messageId, isSessionEnabled)); +// } +// +// // Assert & Act +// AtomicReference transaction = new AtomicReference<>(); +// StepVerifier.create(sender.createTransaction()) +// .assertNext(transactionContext -> { +// transaction.set(transactionContext); +// assertNotNull(transaction); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration), transaction.get()).collectList()) +// .assertNext(longs -> { +// assertEquals(total, longs.size()); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(sender.commitTransaction(transaction.get())) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(Mono.delay(scheduleDuration).thenMany(receiver.receiveMessages().take(total))) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .assertNext(receivedMessage -> { +// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); +// messagesPending.decrementAndGet(); +// }) +// .thenAwait(shortWait) +// .thenCancel() +// .verify(TIMEOUT); +// } +// +// /** +// * Verifies that we can schedule messages and cancel them. +// */ +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// @ParameterizedTest +// void cancelScheduledMessagesTest(MessagingEntityType entityType) { +// +// // Arrange +// final boolean isSessionEnabled = false; +// final Duration shortWaitTime = Duration.ofSeconds(5); +// final int total = 2; +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, USE_CREDENTIALS); +// final Duration scheduleDuration = Duration.ofSeconds(15); +// final String messageId = UUID.randomUUID().toString(); +// final List messages = new ArrayList<>(); +// for (int i = 0; i < total; ++i) { +// messages.add(getMessage(messageId, isSessionEnabled)); +// } +// List seqNumbers = sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration)).collectList().block(shortWaitTime); +// +// // Assert & Act +// Assertions.assertNotNull(seqNumbers); +// Assertions.assertEquals(total, seqNumbers.size()); +// +// StepVerifier.create(sender.cancelScheduledMessages(seqNumbers)) +// .expectComplete() +// .verify(TIMEOUT); +// +// // The messages should have been cancelled and we should not find any messages. +// StepVerifier.create(receiver.receiveMessages().take(total)) +// .verifyTimeout(shortWaitTime); +// } +// +// /** +// * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. +// */ +// private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { +// final boolean isSessionAware = false; +// final boolean sharedConnection = true; +// +// this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) +// .buildAsyncClient()); +// this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .disableAutoComplete() +// .buildAsyncClient()); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java index 640681837bb9..be71318f9694 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java @@ -3,207 +3,211 @@ package com.azure.messaging.servicebus; -import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; -import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.publisher.Mono; +class ServiceBusSenderClientIntegrationTest { -import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - -/** - * Integration tests for the {@link ServiceBusSenderClient}. - */ -@Tag("integration") -class ServiceBusSenderClientIntegrationTest extends IntegrationTestBase { - private ServiceBusSenderClient sender; - private ServiceBusReceiverAsyncClient receiver; - private final AtomicInteger messagesPending = new AtomicInteger(); - - ServiceBusSenderClientIntegrationTest() { - super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); - } - - @Override - protected void afterTest() { - dispose(sender); - - final int numberOfMessages = messagesPending.get(); - if (numberOfMessages < 1) { - dispose(receiver); - return; - } - try { - receiver.receiveMessages() - .take(messagesPending.get()) - .map(message -> { - logger.info("Message received: {}", message.getSequenceNumber()); - return message; - }) - .timeout(Duration.ofSeconds(5), Mono.empty()) - .blockLast(); - } catch (Exception e) { - logger.warning("Error occurred when draining queue.", e); - } finally { - dispose(receiver); - } - } - - static Stream receiverTypesProvider() { - return Stream.of( - Arguments.of(MessagingEntityType.QUEUE), - Arguments.of(MessagingEntityType.SUBSCRIPTION) - ); - } - - /** - * Verifies that we can send a message to a non-session queue. - */ - @MethodSource("receiverTypesProvider") - @ParameterizedTest - void nonSessionQueueSendMessage(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); - - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - - // Assert & Act - sender.sendMessage(message); - - messagesPending.incrementAndGet(); - } - - /** - * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. - */ - @MethodSource("receiverTypesProvider") - @ParameterizedTest - void nonSessionMessageBatch(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); - - final String messageId = UUID.randomUUID().toString(); - final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); - final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); - - // Assert & Act - ServiceBusMessageBatch batch = sender.createMessageBatch(options); - for (ServiceBusMessage message : messages) { - Assertions.assertTrue(batch.tryAddMessage(message)); - } - - sender.sendMessages(batch); - - for (int i = 0; i < messages.size(); i++) { - messagesPending.incrementAndGet(); - } - } - - /** - * Verifies that we can send a list of messages to a non-session entity. - */ - @MethodSource("receiverTypesProvider") - @ParameterizedTest - void nonSessionEntitySendMessageList(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); - int count = 3; - final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); - - // Assert & Act - sender.sendMessages(messages); - - messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()); - } - - /** - * Verifies that we can schedule a message to a non-session entity. - */ - @MethodSource("receiverTypesProvider") - @ParameterizedTest - void nonSessionScheduleMessage(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); - - final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - - // Act - long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); - - // Assert - Assertions.assertTrue(sequenceNumber >= 0); - - messagesPending.incrementAndGet(); - } - - /** - * Verifies that we can cancel a scheduled a message to a non-session entity. - */ - @MethodSource("receiverTypesProvider") - @ParameterizedTest - void nonSessionCancelScheduleMessage(MessagingEntityType entityType) { - // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); - - final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(20); - final String messageId = UUID.randomUUID().toString(); - final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); - - // Assert & Act - long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); - Assertions.assertTrue(sequenceNumber >= 0); - - sender.cancelScheduledMessage(sequenceNumber); - - messagesPending.incrementAndGet(); - } - - void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex) { - switch (entityType) { - case QUEUE: - final String queueName = getQueueName(entityIndex); - - Assertions.assertNotNull(queueName, "'queueName' cannot be null."); - - sender = toClose(getBuilder().sender() - .queueName(queueName) - .buildClient()); - receiver = toClose(getBuilder().receiver() - .queueName(queueName) - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .buildAsyncClient()); - break; - case SUBSCRIPTION: - final String topicName = getTopicName(entityIndex); - final String subscriptionName = TestUtils.getSubscriptionBaseName(); - - Assertions.assertNotNull(topicName, "'topicName' cannot be null."); - Assertions.assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - - sender = toClose(getBuilder().sender() - .topicName(topicName) - .buildClient()); - receiver = toClose(getBuilder().receiver() - .topicName(topicName) - .subscriptionName(subscriptionName) - .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) - .buildAsyncClient()); - break; - default: - throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); - } - } } +// +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.messaging.servicebus.implementation.MessagingEntityType; +//import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; +//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +//import org.junit.jupiter.api.Assertions; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.Arguments; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.core.publisher.Mono; +// +//import java.time.Duration; +//import java.time.OffsetDateTime; +//import java.util.List; +//import java.util.UUID; +//import java.util.concurrent.atomic.AtomicInteger; +//import java.util.stream.Stream; +// +///** +// * Integration tests for the {@link ServiceBusSenderClient}. +// */ +//@Tag("integration") +//class ServiceBusSenderClientIntegrationTest extends IntegrationTestBase { +// private ServiceBusSenderClient sender; +// private ServiceBusReceiverAsyncClient receiver; +// private final AtomicInteger messagesPending = new AtomicInteger(); +// +// ServiceBusSenderClientIntegrationTest() { +// super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); +// } +// +// @Override +// protected void afterTest() { +// dispose(sender); +// +// final int numberOfMessages = messagesPending.get(); +// if (numberOfMessages < 1) { +// dispose(receiver); +// return; +// } +// try { +// receiver.receiveMessages() +// .take(messagesPending.get()) +// .map(message -> { +// logger.info("Message received: {}", message.getSequenceNumber()); +// return message; +// }) +// .timeout(Duration.ofSeconds(5), Mono.empty()) +// .blockLast(); +// } catch (Exception e) { +// logger.warning("Error occurred when draining queue.", e); +// } finally { +// dispose(receiver); +// } +// } +// +// static Stream receiverTypesProvider() { +// return Stream.of( +// Arguments.of(MessagingEntityType.QUEUE), +// Arguments.of(MessagingEntityType.SUBSCRIPTION) +// ); +// } +// +// /** +// * Verifies that we can send a message to a non-session queue. +// */ +// @MethodSource("receiverTypesProvider") +// @ParameterizedTest +// void nonSessionQueueSendMessage(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); +// +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// +// // Assert & Act +// sender.sendMessage(message); +// +// messagesPending.incrementAndGet(); +// } +// +// /** +// * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. +// */ +// @MethodSource("receiverTypesProvider") +// @ParameterizedTest +// void nonSessionMessageBatch(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); +// +// final String messageId = UUID.randomUUID().toString(); +// final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); +// final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); +// +// // Assert & Act +// ServiceBusMessageBatch batch = sender.createMessageBatch(options); +// for (ServiceBusMessage message : messages) { +// Assertions.assertTrue(batch.tryAddMessage(message)); +// } +// +// sender.sendMessages(batch); +// +// for (int i = 0; i < messages.size(); i++) { +// messagesPending.incrementAndGet(); +// } +// } +// +// /** +// * Verifies that we can send a list of messages to a non-session entity. +// */ +// @MethodSource("receiverTypesProvider") +// @ParameterizedTest +// void nonSessionEntitySendMessageList(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); +// int count = 3; +// final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); +// +// // Assert & Act +// sender.sendMessages(messages); +// +// messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()); +// } +// +// /** +// * Verifies that we can schedule a message to a non-session entity. +// */ +// @MethodSource("receiverTypesProvider") +// @ParameterizedTest +// void nonSessionScheduleMessage(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); +// +// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// +// // Act +// long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); +// +// // Assert +// Assertions.assertTrue(sequenceNumber >= 0); +// +// messagesPending.incrementAndGet(); +// } +// +// /** +// * Verifies that we can cancel a scheduled a message to a non-session entity. +// */ +// @MethodSource("receiverTypesProvider") +// @ParameterizedTest +// void nonSessionCancelScheduleMessage(MessagingEntityType entityType) { +// // Arrange +// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); +// +// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(20); +// final String messageId = UUID.randomUUID().toString(); +// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); +// +// // Assert & Act +// long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); +// Assertions.assertTrue(sequenceNumber >= 0); +// +// sender.cancelScheduledMessage(sequenceNumber); +// +// messagesPending.incrementAndGet(); +// } +// +// void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex) { +// switch (entityType) { +// case QUEUE: +// final String queueName = getQueueName(entityIndex); +// +// Assertions.assertNotNull(queueName, "'queueName' cannot be null."); +// +// sender = toClose(getBuilder().sender() +// .queueName(queueName) +// .buildClient()); +// receiver = toClose(getBuilder().receiver() +// .queueName(queueName) +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .buildAsyncClient()); +// break; +// case SUBSCRIPTION: +// final String topicName = getTopicName(entityIndex); +// final String subscriptionName = TestUtils.getSubscriptionBaseName(); +// +// Assertions.assertNotNull(topicName, "'topicName' cannot be null."); +// Assertions.assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); +// +// sender = toClose(getBuilder().sender() +// .topicName(topicName) +// .buildClient()); +// receiver = toClose(getBuilder().receiver() +// .topicName(topicName) +// .subscriptionName(subscriptionName) +// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) +// .buildAsyncClient()); +// break; +// default: +// throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); +// } +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index f6e525483d21..443a4ce6b906 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -3,215 +3,219 @@ package com.azure.messaging.servicebus; -import com.azure.core.amqp.AmqpRetryOptions; -import com.azure.core.util.CoreUtils; -import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; -import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +class ServiceBusSessionManagerIntegrationTest { -import java.time.Duration; -import java.util.UUID; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Function; - -import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -/** - * Integration tests for {@link ServiceBusSessionManager}. - */ -@Tag("integration") -class ServiceBusSessionManagerIntegrationTest extends IntegrationTestBase { - private static final AmqpRetryOptions DEFAULT_RETRY_OPTIONS = null; - private ServiceBusReceiverAsyncClient receiver; - private ServiceBusSenderAsyncClient sender; - private ServiceBusSessionReceiverAsyncClient sessionReceiver; - - ServiceBusSessionManagerIntegrationTest() { - super(new ClientLogger(ServiceBusSessionManagerIntegrationTest.class)); - } - - @Override - protected void beforeTest() { - sessionId = UUID.randomUUID().toString(); - } - - @Override - protected void afterTest() { - try { - dispose(receiver, sender, sessionReceiver); - } catch (Exception e) { - logger.warning("Error occurred when draining queue.", e); - } - } - - @ParameterizedTest - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - void singleUnnamedSession(MessagingEntityType entityType) { - // Arrange - final int entityIndex = TestUtils.USE_CASE_SINGLE_SESSION; - final String messageId = "singleUnnamedSession"; - final String contents = "Some-contents"; - final int numberToSend = 5; - - setSender(entityType, entityIndex); - final Disposable subscription = Flux.interval(Duration.ofMillis(500)) - .take(numberToSend) - .flatMap(index -> { - final ServiceBusMessage message = getServiceBusMessage(contents, messageId) - .setSessionId(sessionId); - return sender.sendMessage(message).thenReturn(index); - }) - .subscribe( - number -> logger.info("sessionId[{}] sent[{}] Message sent.", sessionId, number), - error -> logger.error("sessionId[{}] Error encountered.", sessionId, error), - () -> logger.info("sessionId[{}] Finished sending.", sessionId)); - toClose(subscription); - setReceiver(entityType, entityIndex, Function.identity()); - - // Act & Assert - StepVerifier.create(receiver.receiveMessages().concatMap( - receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage) - )) - .assertNext(serviceBusReceivedMessage -> - assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) - .assertNext(serviceBusReceivedMessage -> - assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) - .assertNext(serviceBusReceivedMessage -> - assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) - .assertNext(serviceBusReceivedMessage -> - assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) - .assertNext(serviceBusReceivedMessage -> - assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) - .thenCancel() - .verify(Duration.ofMinutes(2)); - } - - @ParameterizedTest - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { - final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; - final Duration sessionIdleTimeout = Duration.ofSeconds(3); - setSender(entityType, entityIndex); - - this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) - .disableAutoComplete() - .maxConcurrentSessions(1) - .sessionIdleTimeout(sessionIdleTimeout) - .buildAsyncClientForProcessor()); - - rollingSessionTest(); - } - - @ParameterizedTest - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { - final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS3; - final Duration tryTimeout = Duration.ofSeconds(3); - final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); - setSender(entityType, entityIndex); - - this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, retryOptions) - .disableAutoComplete() - .maxConcurrentSessions(1) - .buildAsyncClientForProcessor()); - - rollingSessionTest(); - } - - private void rollingSessionTest() throws InterruptedException { - final String contents = "Some-contents"; - final String randomPrefix = UUID.randomUUID().toString(); - ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); - ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); - - CountDownLatch latch = new CountDownLatch(2); - toClose(sender.sendMessage(message0) - .thenMany(receiver.receiveMessages()) - .flatMap(m -> receiver.complete(m).thenReturn(m)) - .filter(m -> m.getMessageId().startsWith(randomPrefix)) - .flatMap(m -> - (message0.getMessageId().equals(m.getMessageId())) - ? sender.sendMessage(message1).thenReturn(m) : Mono.just(m) - ) - .subscribe(m -> latch.countDown(), ex -> fail(ex))); - - assertTrue(latch.await(20, TimeUnit.SECONDS)); - } - @ParameterizedTest - @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { - final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS2; - final String contents = "Some-contents"; - final Duration sessionIdleTimeout = Duration.ofSeconds(3); - final Duration tryTimeout = Duration.ofSeconds(10); - setSender(entityType, entityIndex); - final String randomPrefix = UUID.randomUUID().toString(); - ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); - ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); - - AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); - this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, retryOptions) - .disableAutoComplete() - .sessionIdleTimeout(sessionIdleTimeout) - .buildAsyncClientForProcessor()); - - AtomicReference sessionId = new AtomicReference<>(); - StepVerifier.create( - sender.sendMessage(message0) - .thenMany(receiver.receiveMessages()) - .flatMap(m -> receiver.complete(m).thenReturn(m)) - .flatMap(m -> { - if (!sessionId.compareAndSet(null, m.getSessionId())) { - assertEquals(sessionId.get(), m.getSessionId(), "session rolling should not happen"); - } - return sender.sendMessage(message1).thenReturn(m); - }) - ) - .expectNextCount(1) - .verifyTimeout(tryTimeout.plusSeconds(20)); - } - - /** - * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. - */ - private void setSender(MessagingEntityType entityType, int entityIndex) { - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, true, false) - .buildAsyncClient()); - } - - private void setReceiver(MessagingEntityType entityType, int entityIndex, - Function onBuild) { - ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); - - this.sessionReceiver = toClose(onBuild.apply(sessionBuilder).buildAsyncClient()); - this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); - } - - private static void assertMessageEquals(String sessionId, String messageId, String contents, ServiceBusReceivedMessage message) { - assertNotNull(message, "'message' should not be null."); - - if (!CoreUtils.isNullOrEmpty(sessionId)) { - assertEquals(sessionId, message.getSessionId()); - } - - assertEquals(messageId, message.getMessageId()); - assertEquals(contents, message.getBody().toString()); - } } +// +//import com.azure.core.amqp.AmqpRetryOptions; +//import com.azure.core.util.CoreUtils; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; +//import com.azure.messaging.servicebus.implementation.MessagingEntityType; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.core.Disposable; +//import reactor.core.publisher.Flux; +//import reactor.core.publisher.Mono; +//import reactor.test.StepVerifier; +// +//import java.time.Duration; +//import java.util.UUID; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.TimeUnit; +//import java.util.concurrent.atomic.AtomicReference; +//import java.util.function.Function; +// +//import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assertions.fail; +// +///** +// * Integration tests for {@link ServiceBusSessionManager}. +// */ +//@Tag("integration") +//class ServiceBusSessionManagerIntegrationTest extends IntegrationTestBase { +// private static final AmqpRetryOptions DEFAULT_RETRY_OPTIONS = null; +// private ServiceBusReceiverAsyncClient receiver; +// private ServiceBusSenderAsyncClient sender; +// private ServiceBusSessionReceiverAsyncClient sessionReceiver; +// +// ServiceBusSessionManagerIntegrationTest() { +// super(new ClientLogger(ServiceBusSessionManagerIntegrationTest.class)); +// } +// +// @Override +// protected void beforeTest() { +// sessionId = UUID.randomUUID().toString(); +// } +// +// @Override +// protected void afterTest() { +// try { +// dispose(receiver, sender, sessionReceiver); +// } catch (Exception e) { +// logger.warning("Error occurred when draining queue.", e); +// } +// } +// +// @ParameterizedTest +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// void singleUnnamedSession(MessagingEntityType entityType) { +// // Arrange +// final int entityIndex = TestUtils.USE_CASE_SINGLE_SESSION; +// final String messageId = "singleUnnamedSession"; +// final String contents = "Some-contents"; +// final int numberToSend = 5; +// +// setSender(entityType, entityIndex); +// final Disposable subscription = Flux.interval(Duration.ofMillis(500)) +// .take(numberToSend) +// .flatMap(index -> { +// final ServiceBusMessage message = getServiceBusMessage(contents, messageId) +// .setSessionId(sessionId); +// return sender.sendMessage(message).thenReturn(index); +// }) +// .subscribe( +// number -> logger.info("sessionId[{}] sent[{}] Message sent.", sessionId, number), +// error -> logger.error("sessionId[{}] Error encountered.", sessionId, error), +// () -> logger.info("sessionId[{}] Finished sending.", sessionId)); +// toClose(subscription); +// setReceiver(entityType, entityIndex, Function.identity()); +// +// // Act & Assert +// StepVerifier.create(receiver.receiveMessages().concatMap( +// receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage) +// )) +// .assertNext(serviceBusReceivedMessage -> +// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) +// .assertNext(serviceBusReceivedMessage -> +// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) +// .assertNext(serviceBusReceivedMessage -> +// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) +// .assertNext(serviceBusReceivedMessage -> +// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) +// .assertNext(serviceBusReceivedMessage -> +// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) +// .thenCancel() +// .verify(Duration.ofMinutes(2)); +// } +// +// @ParameterizedTest +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { +// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; +// final Duration sessionIdleTimeout = Duration.ofSeconds(3); +// setSender(entityType, entityIndex); +// +// this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, +// entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) +// .disableAutoComplete() +// .maxConcurrentSessions(1) +// .sessionIdleTimeout(sessionIdleTimeout) +// .buildAsyncClientForProcessor()); +// +// rollingSessionTest(); +// } +// +// @ParameterizedTest +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { +// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS3; +// final Duration tryTimeout = Duration.ofSeconds(3); +// final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); +// setSender(entityType, entityIndex); +// +// this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, +// entityType, entityIndex, false, retryOptions) +// .disableAutoComplete() +// .maxConcurrentSessions(1) +// .buildAsyncClientForProcessor()); +// +// rollingSessionTest(); +// } +// +// private void rollingSessionTest() throws InterruptedException { +// final String contents = "Some-contents"; +// final String randomPrefix = UUID.randomUUID().toString(); +// ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); +// ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); +// +// CountDownLatch latch = new CountDownLatch(2); +// toClose(sender.sendMessage(message0) +// .thenMany(receiver.receiveMessages()) +// .flatMap(m -> receiver.complete(m).thenReturn(m)) +// .filter(m -> m.getMessageId().startsWith(randomPrefix)) +// .flatMap(m -> +// (message0.getMessageId().equals(m.getMessageId())) +// ? sender.sendMessage(message1).thenReturn(m) : Mono.just(m) +// ) +// .subscribe(m -> latch.countDown(), ex -> fail(ex))); +// +// assertTrue(latch.await(20, TimeUnit.SECONDS)); +// } +// @ParameterizedTest +// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") +// void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { +// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS2; +// final String contents = "Some-contents"; +// final Duration sessionIdleTimeout = Duration.ofSeconds(3); +// final Duration tryTimeout = Duration.ofSeconds(10); +// setSender(entityType, entityIndex); +// final String randomPrefix = UUID.randomUUID().toString(); +// ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); +// ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); +// +// AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); +// this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, +// entityType, entityIndex, false, retryOptions) +// .disableAutoComplete() +// .sessionIdleTimeout(sessionIdleTimeout) +// .buildAsyncClientForProcessor()); +// +// AtomicReference sessionId = new AtomicReference<>(); +// StepVerifier.create( +// sender.sendMessage(message0) +// .thenMany(receiver.receiveMessages()) +// .flatMap(m -> receiver.complete(m).thenReturn(m)) +// .flatMap(m -> { +// if (!sessionId.compareAndSet(null, m.getSessionId())) { +// assertEquals(sessionId.get(), m.getSessionId(), "session rolling should not happen"); +// } +// return sender.sendMessage(message1).thenReturn(m); +// }) +// ) +// .expectNextCount(1) +// .verifyTimeout(tryTimeout.plusSeconds(20)); +// } +// +// /** +// * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. +// */ +// private void setSender(MessagingEntityType entityType, int entityIndex) { +// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, true, false) +// .buildAsyncClient()); +// } +// +// private void setReceiver(MessagingEntityType entityType, int entityIndex, +// Function onBuild) { +// ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(USE_CREDENTIALS, +// entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); +// +// this.sessionReceiver = toClose(onBuild.apply(sessionBuilder).buildAsyncClient()); +// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); +// } +// +// private static void assertMessageEquals(String sessionId, String messageId, String contents, ServiceBusReceivedMessage message) { +// assertNotNull(message, "'message' should not be null."); +// +// if (!CoreUtils.isNullOrEmpty(sessionId)) { +// assertEquals(sessionId, message.getSessionId()); +// } +// +// assertEquals(messageId, message.getMessageId()); +// assertEquals(contents, message.getBody().toString()); +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java index 248566011864..f86e6b8c8971 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java @@ -3,990 +3,993 @@ package com.azure.messaging.servicebus; -import com.azure.core.tracing.opentelemetry.OpenTelemetryTracingOptions; -import com.azure.core.util.ClientOptions; -import com.azure.core.util.IterableStream; -import com.azure.core.util.logging.ClientLogger; -import com.azure.messaging.servicebus.implementation.instrumentation.ServiceBusTracer; -import com.azure.messaging.servicebus.models.DeferOptions; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.trace.IdGenerator; -import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.SpanProcessor; -import io.opentelemetry.sdk.trace.data.LinkData; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import reactor.core.Disposable; -import reactor.core.scheduler.Schedulers; -import reactor.test.StepVerifier; +public class TracingIntegrationTests { -import java.time.Duration; -import java.time.OffsetDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -@Execution(ExecutionMode.SAME_THREAD) -public class TracingIntegrationTests extends IntegrationTestBase { - private ClientOptions clientOptions; - private TestSpanProcessor spanProcessor; - private ServiceBusSenderAsyncClient sender; - private ServiceBusReceiverAsyncClient receiver; - private ServiceBusReceiverClient receiverSync; - private ServiceBusProcessorClient processor; - - public TracingIntegrationTests() { - super(new ClientLogger(TracingIntegrationTests.class)); - } - - @Override - protected void beforeTest() { - spanProcessor = new TestSpanProcessor(getFullyQualifiedDomainName(), getQueueName(0)); - OpenTelemetryTracingOptions tracingOptions = new OpenTelemetryTracingOptions() - .setOpenTelemetry(OpenTelemetrySdk.builder() - .setTracerProvider( - SdkTracerProvider.builder() - .addSpanProcessor(spanProcessor) - .build()) - .build()); - clientOptions = new ClientOptions().setTracingOptions(tracingOptions); - - final ServiceBusClientBuilder senderBuilder = getBuilder(); - sender = toClose(senderBuilder - .clientOptions(clientOptions) - .sender() - .queueName(getQueueName(0)) - .buildAsyncClient()); - - final ServiceBusClientBuilder receiverBuilder = getBuilder(); - receiver = toClose(receiverBuilder - .clientOptions(clientOptions) - .receiver() - .maxAutoLockRenewDuration(Duration.ZERO) - .queueName(getQueueName(0)) - .disableAutoComplete() - .buildAsyncClient()); - - final ServiceBusClientBuilder receiverSyncBuilder = getBuilder(); - receiverSync = toClose(receiverSyncBuilder - .clientOptions(clientOptions) - .receiver() - .queueName(getQueueName(0)) - .buildClient()); - } - - @Override - protected void afterTest() { - GlobalOpenTelemetry.resetForTest(); - sharedBuilder = null; - } - - @Test - public void sendAndReceive() throws InterruptedException { - ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); - ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); - List messages = Arrays.asList(message1, message2); - StepVerifier.create(sender.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(2); - spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); - - List received = new ArrayList<>(); - Disposable subscription = receiver.receiveMessages() - .take(2) - .doOnNext(msg -> { - received.add(msg); - String traceparent = (String) msg.getApplicationProperties().get("traceparent"); - String traceId = Span.current().getSpanContext().getTraceId(); - - // context created for the message and current are the same - assertTrue(traceparent.startsWith("00-" + traceId)); - assertFalse(((ReadableSpan) Span.current()).hasEnded()); - receiver.complete(msg).block(); - }) - .subscribe(); - toClose(subscription); - assertTrue(processedFound.await(20, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - - List messageSpans = findSpans(spans, "ServiceBus.message"); - assertMessageSpan(messageSpans.get(0), message1); - assertMessageSpan(messageSpans.get(1), message2); - - List send = findSpans(spans, "ServiceBus.send"); - assertClientProducerSpan(send.get(0), messages, "ServiceBus.send", "publish"); - - List processed = findSpans(spans, "ServiceBus.process"); - assertConsumerSpan(processed.get(0), received.get(0), "ServiceBus.process"); - assertConsumerSpan(processed.get(1), received.get(1), "ServiceBus.process"); - - List completed = findSpans(spans, "ServiceBus.complete"); - assertClientSpan(completed.get(0), Collections.singletonList(received.get(0)), "ServiceBus.complete", "settle"); - assertClientSpan(completed.get(1), Collections.singletonList(received.get(1)), "ServiceBus.complete", "settle"); - assertSettledVsProcessed(completed, processed, messages.size()); - } - - @Test - public void receiveAndRenewLockWithDuration() throws InterruptedException { - ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); - StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(2); - spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewMessageLock")); - - AtomicReference received = new AtomicReference<>(); - StepVerifier.create(receiver.receiveMessages() - .next() - .flatMap(msg -> receiver.renewMessageLock(msg, Duration.ofSeconds(2)) - .thenReturn(msg))) - .assertNext(msg -> received.compareAndSet(null, msg)) - .expectComplete() - .verify(TIMEOUT); - assertTrue(processedFound.await(30, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - - List processed = findSpans(spans, "ServiceBus.process"); - assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); - - List renewLock = findSpans(spans, "ServiceBus.renewMessageLock"); - assertClientSpan(renewLock.get(0), Collections.singletonList(received.get()), "ServiceBus.renewMessageLock", null); - } - - @Test - public void receiveAndRenewSessionLockWithDuration() throws InterruptedException { - String sessionId = "10"; - ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) - .setSessionId(sessionId); - - OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), getSessionQueueName(0)); - final ServiceBusClientBuilder senderBuilder = getBuilder(); - sender = toClose(senderBuilder - .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) - .sender() - .queueName(getSessionQueueName(0)) - .buildAsyncClient()); - - final ServiceBusClientBuilder receiverBuilder = getBuilder(); - ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(receiverBuilder - .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) - .sessionReceiver() - .disableAutoComplete() - .queueName(getSessionQueueName(0)) - .buildAsyncClient()); - - StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(2); - spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewSessionLock")); - - AtomicReference received = new AtomicReference<>(); - StepVerifier.create( - sessionReceiver - .acceptSession(sessionId) - .flatMapMany(rec -> rec - .renewSessionLock() - .then(rec.receiveMessages().next()))) - .assertNext(msg -> { - received.set(msg); - logger.atInfo() - .addKeyValue("lockedUntil", msg.getLockedUntil()) - .addKeyValue("sessionId", msg.getSessionId()) - .log("message received"); - }) - .expectComplete() - .verify(TIMEOUT); - - assertTrue(processedFound.await(30, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - - List processed = findSpans(spans, "ServiceBus.process"); - assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); - - List acceptSession = findSpans(spans, "ServiceBus.acceptSession"); - assertClientSpan(acceptSession.get(0), Collections.emptyList(), "ServiceBus.acceptSession", null); - - List renewLock = findSpans(spans, "ServiceBus.renewSessionLock"); - assertClientSpan(renewLock.get(0), Collections.emptyList(), "ServiceBus.renewSessionLock", null); - } - - @Test - public void receiveCheckSubscribe() throws InterruptedException { - ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); - ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); - List messages = Arrays.asList(message1, message2); - StepVerifier.create(sender.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(2); - spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); - - Disposable subscription = receiver.receiveMessages() - .take(messages.size()) - .subscribe(msg -> { - String traceparent = (String) msg.getApplicationProperties().get("traceparent"); - String traceId = Span.current().getSpanContext().getTraceId(); - - // context created for the message and current are the same - assertTrue(traceparent.startsWith("00-" + traceId)); - assertFalse(((ReadableSpan) Span.current()).hasEnded()); - receiver.complete(msg).block(); - }); - toClose(subscription); - assertTrue(processedFound.await(20, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messages.size()); - } - - @Test - public void sendAndReceiveParallelNoAutoCompleteAndLockRenewal() throws InterruptedException { - int messageCount = 5; - StepVerifier.create(sender.createMessageBatch() - .doOnNext(batch -> { - for (int i = 0; i < messageCount; i++) { - batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); - } - }) - .flatMap(batch -> sender.sendMessages(batch))) - .expectComplete() - .verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(messageCount); - spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - - final ServiceBusClientBuilder receiverBuilder = getBuilder(); - ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(receiverBuilder - .clientOptions(clientOptions) - .receiver() - .queueName(getQueueName(0)) - .disableAutoComplete() - .buildAsyncClient()); - - StepVerifier.create( - receiverWithLockRenewal.receiveMessages() - .take(messageCount) - .doOnNext(msg -> { - if (Span.current().getSpanContext().isValid()) { - String traceparent = (String) msg.getApplicationProperties().get("traceparent"); - String traceId = Span.current().getSpanContext().getTraceId(); - - // context created for the message and current are the same - assertTrue(traceparent.startsWith("00-" + traceId)); - assertFalse(((ReadableSpan) Span.current()).hasEnded()); - } - receiver.complete(msg).block(); - }) - .parallel(messageCount, 1) - .runOn(Schedulers.boundedElastic(), 1)) - .expectNextCount(messageCount) - .expectComplete() - .verify(TIMEOUT); - - assertTrue(processedFound.await(20, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - - // all completed spans should have a parent, but complete call may start after the parent span has ended - // the last part heavily depends on how above code is written wrt parallelization. - // in the current form (receive -> doonnext (complete) -> parallel) - // complete is happens synchronously from the receive perspective - // so complete will finish before processing is completed. - // - // if complete call is done differently (e.g. receive -> parallel -> runon -> doonnext (complete)) - // then doonnext callbacks become async and may happen after receiver call has completed - // then complete will be a child of process, but will last longer than processing - // TODO (limolkova): this is another good reason to rename receiver's span to delivery instead of processing. - assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); - } - - @Test - public void sendAndReceiveParallelAutoComplete() throws InterruptedException { - int messageCount = 5; - StepVerifier.create(sender.createMessageBatch() - .doOnNext(batch -> { - for (int i = 0; i < messageCount; i++) { - batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); - } - }) - .flatMap(batch -> sender.sendMessages(batch))) - .expectComplete() - .verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(messageCount); - spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - - final ServiceBusClientBuilder receiverBuilder = getBuilder(); - ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(receiverBuilder - .clientOptions(clientOptions) - .receiver() - .queueName(getQueueName(0)) - .buildAsyncClient()); - - StepVerifier.create( - receiverAutoComplete.receiveMessages() - .take(messageCount) - .doOnNext(msg -> { - if (Span.current().getSpanContext().isValid()) { - String traceparent = (String) msg.getApplicationProperties().get("traceparent"); - String traceId = Span.current().getSpanContext().getTraceId(); - - // context created for the message and current are the same - assertTrue(traceparent.startsWith("00-" + traceId)); - assertFalse(((ReadableSpan) Span.current()).hasEnded()); - } - }) - .parallel(messageCount, 1) - .runOn(Schedulers.boundedElastic(), 1)) - .expectNextCount(messageCount) - .expectComplete() - .verify(TIMEOUT); - assertTrue(processedFound.await(20, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); - } - - @Test - public void sendReceiveRenewLockAndDefer() throws InterruptedException { - String traceId = IdGenerator.random().generateTraceId(); - String traceparent = "00-" + traceId + "-" + IdGenerator.random().generateSpanId() + "-01"; - ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); - AtomicReference receivedMessage = new AtomicReference<>(); - message.getApplicationProperties().put("traceparent", traceparent); - - StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); - - CountDownLatch latch = new CountDownLatch(1); - spanProcessor.notifyIfCondition(latch, s -> s.getName().equals("ServiceBus.receiveDeferredMessage")); - toClose(receiver.receiveMessages() - .filter(m -> traceparent.equals(m.getApplicationProperties().get("traceparent"))) - .flatMap(m -> receiver.renewMessageLock(m).thenReturn(m)) - .flatMap(m -> receiver.defer(m, new DeferOptions()).thenReturn(m)) - .flatMap(m -> receiver.receiveDeferredMessage(m.getSequenceNumber()).thenReturn(m)) - .subscribe(m -> { - receivedMessage.compareAndSet(null, m); - })); - assertTrue(latch.await(120, TimeUnit.SECONDS)); - - List spans = spanProcessor.getEndedSpans(); - - assertEquals(0, findSpans(spans, "ServiceBus.message").size()); - - List send = findSpans(spans, "ServiceBus.send"); - assertClientProducerSpan(send.get(0), Collections.singletonList(message), "ServiceBus.send", "publish"); - - List process = findSpans(spans, "ServiceBus.process", traceId); - assertConsumerSpan(process.get(0), receivedMessage.get(), "ServiceBus.process"); - - List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock", traceId); - assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.renewMessageLock", null); - assertParent(renewMessageLock.get(0), process.get(0)); - - // for correlation to work after first async call, we need to enable otel rector instrumentations, - // so no correlation beyond this point - List defer = findSpans(spans, "ServiceBus.defer"); - assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.defer", "settle"); - - List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); - assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.receiveDeferredMessage", "receive"); - } - - @Test - public void sendReceiveRenewLockAndDeferSync() { - StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) - .expectComplete() - .verify(TIMEOUT); - - ServiceBusReceivedMessage receivedMessage = null; - while (receivedMessage == null) { - IterableStream messages = receiverSync.receiveMessages(1, Duration.ofSeconds(10)); - if (messages.iterator().hasNext()) { - receivedMessage = messages.iterator().next(); - } - } - - receiverSync.renewMessageLock(receivedMessage); - receiverSync.defer(receivedMessage, new DeferOptions()); - receiverSync.receiveDeferredMessage(receivedMessage.getSequenceNumber()); - - List spans = spanProcessor.getEndedSpans(); - - List received = findSpans(spans, "ServiceBus.receiveMessages"); - assertClientSpan(received.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveMessages", "receive"); - - List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock"); - assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage), "ServiceBus.renewMessageLock", null); - - List defer = findSpans(spans, "ServiceBus.defer"); - assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage), "ServiceBus.defer", "settle"); - - List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); - assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveDeferredMessage", "receive"); - } - - @Test - public void syncReceive() { - List messages = new ArrayList<>(); - messages.add(new ServiceBusMessage(CONTENTS_BYTES)); - messages.add(new ServiceBusMessage(CONTENTS_BYTES)); - - StepVerifier.create(sender.sendMessages(messages)) - .expectComplete() - .verify(TIMEOUT); - - List receivedMessages = receiverSync.receiveMessages(2, Duration.ofSeconds(10)) - .stream().collect(Collectors.toList()); - receivedMessages.forEach(receiverSync::complete); - - List spans = spanProcessor.getEndedSpans(); - - List received = findSpans(spans, "ServiceBus.receiveMessages"); - assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); - - assertEquals(0, findSpans(spans, "ServiceBus.process").size()); - - List completed = findSpans(spans, "ServiceBus.complete"); - assertClientSpan(completed.get(0), Collections.singletonList(receivedMessages.get(0)), "ServiceBus.complete", "settle"); - assertClientSpan(completed.get(1), Collections.singletonList(receivedMessages.get(1)), "ServiceBus.complete", "settle"); - } - - @Test - public void syncReceiveTimeout() { - List receivedMessages = receiverSync.receiveMessages(100, Duration.ofMillis(1)) - .stream().collect(Collectors.toList()); - - List spans = spanProcessor.getEndedSpans(); - - List received = findSpans(spans, "ServiceBus.receiveMessages"); - assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); - assertEquals(StatusCode.UNSET, received.get(0).toSpanData().getStatus().getStatusCode()); - - assertEquals(0, findSpans(spans, "ServiceBus.process").size()); - } - - @Test - public void peekMessage() { - StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) - .expectComplete() - .verify(TIMEOUT); - - StepVerifier.create(receiver.peekMessage()) - .assertNext(receivedMessage -> { - ReadableSpan received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage").get(0); - if (receivedMessage.getApplicationProperties().containsKey("traceparent")) { - logger.atInfo() - .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) - .log("span should have link"); - assertClientSpan(received, Collections.singletonList(receivedMessage), "ServiceBus.peekMessage", "receive"); - } else { - assertEquals("ServiceBus.peekMessage", received.getName()); - assertEquals(SpanKind.CLIENT, received.getKind()); - assertEquals(0, received.toSpanData().getLinks().size()); - assertEquals("receive", received.getAttribute(AttributeKey.stringKey("messaging.operation"))); - } - }) - .expectComplete() - .verify(TIMEOUT); - } - - @Test - public void peekNonExistingMessage() { - StepVerifier.create(receiver.peekMessage(Long.MAX_VALUE - 1)) - .expectComplete() - .verify(TIMEOUT); - - List received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage"); - assertClientSpan(received.get(0), Collections.emptyList(), "ServiceBus.peekMessage", "receive"); - } - - @Test - public void sendAndProcessNoAutoComplete() throws InterruptedException { - String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) - .setMessageId(messageId); - - StepVerifier.create(sender.sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - - String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); - CountDownLatch processFound = new CountDownLatch(1); - spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") && span.getParentSpanContext().getSpanId().equals(message1SpanId)); - - AtomicReference currentInProcess = new AtomicReference<>(); - AtomicReference receivedMessage = new AtomicReference<>(); - final ServiceBusClientBuilder processorBuilder = getBuilder(); - processor = toClose(processorBuilder - .clientOptions(clientOptions) - .processor() - .queueName(getQueueName(0)) - .processMessage(mc -> { - if (mc.getMessage().getMessageId().equals(messageId)) { - currentInProcess.compareAndSet(null, Span.current()); - receivedMessage.compareAndSet(null, mc.getMessage()); - } - mc.complete(); - }) - .processError(e -> fail("unexpected error", e.getException())) - .buildProcessorClient()); - - toClose((AutoCloseable) () -> processor.stop()); - processor.start(); - assertTrue(processFound.await(20, TimeUnit.SECONDS)); - processor.stop(); - - assertTrue(currentInProcess.get().getSpanContext().isValid()); - List spans = spanProcessor.getEndedSpans(); - - assertMessageSpan(spans.get(0), message); - assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.send", "publish"); - - assertEquals(0, findSpans(spans, "ServiceBus.consume").size()); - List processed = findSpans(spans, "ServiceBus.process") - .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); - assertEquals(1, processed.size()); - assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); - - List completed = findSpans(spans, "ServiceBus.complete").stream() - .filter(c -> { - List links = c.toSpanData().getLinks(); - return !links.isEmpty() && links.get(0).getSpanContext().getSpanId().equals(message1SpanId); - }) - .collect(Collectors.toList()); - assertEquals(1, completed.size()); - assertClientProducerSpan(completed.get(0), Collections.singletonList(message), "ServiceBus.complete", "settle"); - - assertSettledVsProcessed(completed, processed, 1); - } - - @Test - public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { - String sessionQueueName = getSessionQueueName(0); - String sessionId = UUID.randomUUID().toString(); - ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES).setSessionId(sessionId); - - OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), sessionQueueName); - clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); - final ServiceBusClientBuilder senderBuilder = getBuilder(); - sender = toClose(senderBuilder - .clientOptions(clientOptions) - .sender() - .queueName(sessionQueueName) - .buildAsyncClient()); - - StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); - - CountDownLatch processFound = new CountDownLatch(2); - spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); - - AtomicReference currentInProcess = new AtomicReference<>(); - AtomicReference receivedMessage = new AtomicReference<>(); - final ServiceBusClientBuilder processorBuilder = getBuilder(); - processor = toClose(processorBuilder - .clientOptions(clientOptions) - .sessionProcessor() - .maxConcurrentSessions(1) - .queueName(sessionQueueName) - .disableAutoComplete() - .processMessage(mc -> { - currentInProcess.compareAndSet(null, Span.current()); - receivedMessage.compareAndSet(null, mc.getMessage()); - mc.complete(); - }) - .processError(e -> fail("unexpected error", e.getException())) - .buildProcessorClient()); - - toClose((AutoCloseable) () -> processor.stop()); - processor.start(); - assertTrue(processFound.await(20, TimeUnit.SECONDS)); - processor.stop(); - - assertTrue(currentInProcess.get().getSpanContext().isValid()); - List spans = spanProcessor.getEndedSpans(); - - List processed = findSpans(spans, "ServiceBus.process") - .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); - assertEquals(1, processed.size()); - assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); - - List completed = findSpans(spans, "ServiceBus.complete"); - assertEquals(1, completed.size()); - assertClientSpan(completed.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.complete", "settle"); - assertSettledVsProcessed(completed, processed, 1); - } - - @Test - public void sendAndProcessParallel() throws InterruptedException { - int messageCount = 10; - StepVerifier.create(sender.createMessageBatch() - .doOnNext(batch -> { - for (int i = 0; i < messageCount; i++) { - batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES) - .setMessageId(UUID.randomUUID().toString())); - } - }) - .flatMap(batch -> { - logMessages(batch.getMessages(), sender.getEntityPath(), "sending"); - return sender.sendMessages(batch); - })) - .expectComplete() - .verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(messageCount * 2); - spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); - - final ServiceBusClientBuilder processorBuilder = getBuilder(); - processor = toClose(processorBuilder - .clientOptions(clientOptions) - .processor() - .queueName(getQueueName(0)) - .maxConcurrentCalls(messageCount) - .processMessage(mc -> { - logMessage(mc.getMessage(), processor.getQueueName(), "processing"); - String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); - String traceId = Span.current().getSpanContext().getTraceId(); - - // context created for the message and current are the same - assertTrue(traceparent.startsWith("00-" + traceId)); - assertFalse(((ReadableSpan) Span.current()).hasEnded()); - }) - .processError(e -> fail("unexpected error", e.getException())) - .buildProcessorClient()); - toClose((AutoCloseable) () -> processor.stop()); - processor.start(); - assertTrue(processedFound.await(30, TimeUnit.SECONDS)); - processor.stop(); - - List spans = spanProcessor.getEndedSpans(); - assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); - } - - @Test - public void sendAndProcessParallelNoAutoComplete() throws InterruptedException { - int messageCount = 5; - StepVerifier.create(sender.createMessageBatch() - .doOnNext(batch -> { - for (int i = 0; i < messageCount; i++) { - batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); - } - }) - .flatMap(batch -> sender.sendMessages(batch))) - .expectComplete() - .verify(TIMEOUT); - - CountDownLatch processedFound = new CountDownLatch(messageCount); - spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - - final ServiceBusClientBuilder processorBuilder = getBuilder(); - processor = toClose(processorBuilder - .clientOptions(clientOptions) - .processor() - .queueName(getQueueName(0)) - .maxConcurrentCalls(messageCount) - .disableAutoComplete() - .processMessage(mc -> { - String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); - String traceId = Span.current().getSpanContext().getTraceId(); - - // context created for the message and current are the same - assertTrue(traceparent.startsWith("00-" + traceId)); - mc.complete(); - }) - .processError(e -> fail("unexpected error", e.getException())) - .buildProcessorClient()); - toClose((AutoCloseable) () -> processor.stop()); - processor.start(); - assertTrue(processedFound.await(20, TimeUnit.SECONDS)); - processor.stop(); - - List spans = spanProcessor.getEndedSpans(); - assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); - } - - @Test - public void sendProcessAndFail() throws InterruptedException { - String messageId = UUID.randomUUID().toString(); - ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) - .setMessageId(messageId); - - StepVerifier.create(sender.sendMessage(message)) - .expectComplete() - .verify(TIMEOUT); - - String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); - - CountDownLatch messageProcessed = new CountDownLatch(1); - spanProcessor.notifyIfCondition(messageProcessed, span -> - "ServiceBus.process".equals(span.getName()) && span.getParentSpanContext().getSpanId().equals(message1SpanId)); - - AtomicReference receivedMessage = new AtomicReference<>(); - final ServiceBusClientBuilder processorBuilder = getBuilder(); - processor = toClose(processorBuilder - .clientOptions(clientOptions) - .processor() - .queueName(getQueueName(0)) - .processMessage(mc -> { - if (mc.getMessage().getMessageId().equals(messageId)) { - receivedMessage.compareAndSet(null, mc.getMessage()); - throw new RuntimeException("foo"); - } - }) - .processError(e -> { }) - .buildProcessorClient()); - toClose((AutoCloseable) () -> processor.stop()); - processor.start(); - assertTrue(messageProcessed.await(30, TimeUnit.SECONDS)); - processor.stop(); - - List spans = spanProcessor.getEndedSpans(); - List processed = findSpans(spans, "ServiceBus.process") - .stream().filter(p -> p.getParentSpanContext().isValid()) - .filter(p -> p.toSpanData().getStatus().getStatusCode() == StatusCode.ERROR) - .collect(Collectors.toList()); - assertEquals(1, processed.size()); - assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); - - List abandoned = findSpans(spans, "ServiceBus.abandon").stream() - .filter(c -> c.toSpanData().getLinks().get(0).getSpanContext().getSpanId().equals(message1SpanId)) - .collect(Collectors.toList()); - assertEquals(1, abandoned.size()); - assertClientProducerSpan(abandoned.get(0), Collections.singletonList(message), "ServiceBus.abandon", "settle"); - assertSettledVsProcessed(abandoned, processed, 1); - } - - @Test - public void scheduleAndCancelMessage() { - ServiceBusMessage message = new ServiceBusMessage("m"); - StepVerifier.create( - sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(100)) - .flatMap(l -> sender.cancelScheduledMessage(l))) - .expectComplete() - .verify(TIMEOUT); - - List spans = spanProcessor.getEndedSpans(); - assertMessageSpan(spans.get(0), message); - assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.scheduleMessage", "publish"); - assertClientProducerSpan(spans.get(2), Collections.emptyList(), "ServiceBus.cancelScheduledMessage", null); - } - - private void assertMessageSpan(ReadableSpan actual, ServiceBusMessage message) { - assertEquals("ServiceBus.message", actual.getName()); - assertEquals(SpanKind.PRODUCER, actual.getKind()); - assertNull(actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); - String traceparent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getSpanContext().getSpanId() + "-01"; - assertEquals(message.getApplicationProperties().get("Diagnostic-Id"), traceparent); - assertEquals(message.getApplicationProperties().get("traceparent"), traceparent); - } - - private void assertClientProducerSpan(ReadableSpan actual, List messages, String spanName, String operationName) { - assertEquals(spanName, actual.getName()); - assertEquals(SpanKind.CLIENT, actual.getKind()); - List links = actual.toSpanData().getLinks(); - assertEquals(messages.size(), links.size()); - assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); - if (messages.size() > 1) { - assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); - } - - for (int i = 0; i < links.size(); i++) { - String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); - SpanContext linkContext = links.get(i).getSpanContext(); - String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; - assertEquals(messageTraceparent, linkTraceparent); - } - } - - private void assertClientSpan(ReadableSpan actual, List messages, String spanName, String operationName) { - assertEquals(spanName, actual.getName()); - assertEquals(SpanKind.CLIENT, actual.getKind()); - List links = actual.toSpanData().getLinks(); - assertEquals(messages.size(), links.size()); - assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); - if (messages.size() > 1) { - assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); - } - for (int i = 0; i < links.size(); i++) { - String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); - SpanContext linkContext = links.get(i).getSpanContext(); - String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; - assertEquals(messageTraceparent, linkTraceparent); - assertNotNull(links.get(i).getAttributes().get(AttributeKey.longKey(ServiceBusTracer.MESSAGE_ENQUEUED_TIME_ATTRIBUTE_NAME))); - } - } - - private void assertConsumerSpan(ReadableSpan actual, ServiceBusReceivedMessage message, String spanName) { - assertEquals(spanName, actual.getName()); - assertEquals(SpanKind.CONSUMER, actual.getKind()); - assertEquals(0, actual.toSpanData().getLinks().size()); - assertEquals("process", actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); - String messageTraceparent = (String) message.getApplicationProperties().get("traceparent"); - String parent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getParentSpanContext().getSpanId() + "-01"; - assertEquals(messageTraceparent, parent); - } - - private void assertParent(ReadableSpan child, ReadableSpan parent) { - assertEquals(child.getParentSpanContext().getTraceId(), parent.getSpanContext().getTraceId()); - assertEquals(child.getParentSpanContext().getSpanId(), parent.getSpanContext().getSpanId()); - } - - private void assertSettledVsProcessed(List settled, List processed, int expectedCount) { - assertTrue(settled.size() >= expectedCount, - String.format("Expected at least %d completed spans, but found %d", expectedCount, settled.size())); - assertTrue(processed.size() >= expectedCount, - String.format("Expected at least %d processed spans, but found %d", expectedCount, processed.size())); - - // there could be more completed spans than processed because completion happens before processing, and we can have more messages in the queue than we expected. - assertTrue(settled.size() >= processed.size(), - String.format("Expected at least as many completed spans as processed spans, but found %d completed and %d processed", settled.size(), processed.size())); - - int processedFound = 0; - for (ReadableSpan readableSpan : settled) { - ReadableSpan parent = findParent(readableSpan, processed); - if (parent != null) { - processedFound++; - assertTrue(readableSpan.getLatencyNanos() <= parent.getLatencyNanos(), () -> - String.format("Expected settled span to have less latency than processed span, but found %d vs %d", - readableSpan.getLatencyNanos(), parent.getLatencyNanos())); - } - } - - assertEquals(expectedCount, processedFound); - } - - private ReadableSpan findParent(ReadableSpan child, List possibleParents) { - String traceId = child.getParentSpanContext().getTraceId(); - String parentId = child.getParentSpanContext().getSpanId(); - for (ReadableSpan p : possibleParents) { - if (traceId.equals(p.getSpanContext().getTraceId()) - && parentId.equals(p.getSpanContext().getSpanId())) { - return p; - } - } - - return null; - } - - private List findSpans(List spans, String spanName) { - return spans.stream() - .filter(s -> s.getName().equals(spanName)) - .collect(Collectors.toList()); - } - - private List findSpans(List spans, String spanName, String traceId) { - return spans.stream() - .filter(s -> s.getName().equals(spanName)) - .filter(s -> s.getSpanContext().getTraceId().equals(traceId)) - .collect(Collectors.toList()); - } - - private OpenTelemetry configureOTel(String namespace, String entityName) { - GlobalOpenTelemetry.resetForTest(); - spanProcessor = new TestSpanProcessor(namespace, entityName); - return OpenTelemetrySdk.builder().setTracerProvider( - SdkTracerProvider.builder() - .addSpanProcessor(spanProcessor) - .build()).build(); - } - - static class TestSpanProcessor implements SpanProcessor { - private static final ClientLogger LOGGER = new ClientLogger(TestSpanProcessor.class); - private static final AttributeKey AZ_NAMESPACE = AttributeKey.stringKey("az.namespace"); - private static final AttributeKey MESSAGING_SYSTEM = AttributeKey.stringKey("messaging.system"); - private static final AttributeKey MESSAGING_DESTINATION_NAME - = AttributeKey.stringKey("messaging.destination.name"); - private static final AttributeKey NET_PEER_NAME = AttributeKey.stringKey("net.peer.name"); - private static final AttributeKey SERVER_ADDRESS = AttributeKey.stringKey("server.address"); - - private final ConcurrentLinkedDeque spans = new ConcurrentLinkedDeque<>(); - private final String entityName; - private final String namespace; - - private final AtomicReference> notifier = new AtomicReference<>(); - - TestSpanProcessor(String namespace, String entityName) { - this.namespace = namespace; - this.entityName = entityName; - } - public List getEndedSpans() { - return spans.stream().collect(Collectors.toList()); - } - - @Override - public void onStart(Context context, ReadWriteSpan readWriteSpan) { - } - - @Override - public boolean isStartRequired() { - return false; - } - - @Override - public void onEnd(ReadableSpan readableSpan) { - LOGGER.info(readableSpan.toString()); - assertEquals("Microsoft.ServiceBus", readableSpan.getAttribute(AZ_NAMESPACE)); - assertEquals("servicebus", readableSpan.getAttribute(MESSAGING_SYSTEM)); - assertEquals(entityName, readableSpan.getAttribute(MESSAGING_DESTINATION_NAME)); - - // Depending on the version of OpenTelemetry being used, the attribute name for the peer name may be - // different. The attribute name was changed from "net.peer.name" to "server.address". - String actualNamespace = readableSpan.getAttribute(NET_PEER_NAME); - if (actualNamespace == null) { - actualNamespace = readableSpan.getAttribute(SERVER_ADDRESS); - } - - assertEquals(namespace, actualNamespace); - - spans.add(readableSpan); - Consumer filter = notifier.get(); - if (filter != null) { - filter.accept(readableSpan); - } - } - - public void notifyIfCondition(CountDownLatch countDownLatch, Predicate filter) { - notifier.set((span) -> { - if (filter.test(span)) { - countDownLatch.countDown(); - } - }); - } - - @Override - public boolean isEndRequired() { - return true; - } - } } +//import com.azure.core.tracing.opentelemetry.OpenTelemetryTracingOptions; +//import com.azure.core.util.ClientOptions; +//import com.azure.core.util.IterableStream; +//import com.azure.core.util.logging.ClientLogger; +//import com.azure.messaging.servicebus.implementation.instrumentation.ServiceBusTracer; +//import com.azure.messaging.servicebus.models.DeferOptions; +//import io.opentelemetry.api.GlobalOpenTelemetry; +//import io.opentelemetry.api.OpenTelemetry; +//import io.opentelemetry.api.common.AttributeKey; +//import io.opentelemetry.api.trace.Span; +//import io.opentelemetry.api.trace.SpanContext; +//import io.opentelemetry.api.trace.SpanKind; +//import io.opentelemetry.api.trace.StatusCode; +//import io.opentelemetry.context.Context; +//import io.opentelemetry.sdk.OpenTelemetrySdk; +//import io.opentelemetry.sdk.trace.IdGenerator; +//import io.opentelemetry.sdk.trace.ReadWriteSpan; +//import io.opentelemetry.sdk.trace.ReadableSpan; +//import io.opentelemetry.sdk.trace.SdkTracerProvider; +//import io.opentelemetry.sdk.trace.SpanProcessor; +//import io.opentelemetry.sdk.trace.data.LinkData; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.api.parallel.Execution; +//import org.junit.jupiter.api.parallel.ExecutionMode; +//import reactor.core.Disposable; +//import reactor.core.scheduler.Schedulers; +//import reactor.test.StepVerifier; +// +//import java.time.Duration; +//import java.time.OffsetDateTime; +//import java.util.ArrayList; +//import java.util.Arrays; +//import java.util.Collections; +//import java.util.List; +//import java.util.UUID; +//import java.util.concurrent.ConcurrentLinkedDeque; +//import java.util.concurrent.CountDownLatch; +//import java.util.concurrent.TimeUnit; +//import java.util.concurrent.atomic.AtomicReference; +//import java.util.function.Consumer; +//import java.util.function.Predicate; +//import java.util.stream.Collectors; +// +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertFalse; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertNull; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assertions.fail; +// +//@Execution(ExecutionMode.SAME_THREAD) +//public class TracingIntegrationTests extends IntegrationTestBase { +// private ClientOptions clientOptions; +// private TestSpanProcessor spanProcessor; +// private ServiceBusSenderAsyncClient sender; +// private ServiceBusReceiverAsyncClient receiver; +// private ServiceBusReceiverClient receiverSync; +// private ServiceBusProcessorClient processor; +// +// public TracingIntegrationTests() { +// super(new ClientLogger(TracingIntegrationTests.class)); +// } +// +// @Override +// protected void beforeTest() { +// spanProcessor = new TestSpanProcessor(getFullyQualifiedDomainName(), getQueueName(0)); +// OpenTelemetryTracingOptions tracingOptions = new OpenTelemetryTracingOptions() +// .setOpenTelemetry(OpenTelemetrySdk.builder() +// .setTracerProvider( +// SdkTracerProvider.builder() +// .addSpanProcessor(spanProcessor) +// .build()) +// .build()); +// clientOptions = new ClientOptions().setTracingOptions(tracingOptions); +// +// final ServiceBusClientBuilder senderBuilder = getBuilder(); +// sender = toClose(senderBuilder +// .clientOptions(clientOptions) +// .sender() +// .queueName(getQueueName(0)) +// .buildAsyncClient()); +// +// final ServiceBusClientBuilder receiverBuilder = getBuilder(); +// receiver = toClose(receiverBuilder +// .clientOptions(clientOptions) +// .receiver() +// .maxAutoLockRenewDuration(Duration.ZERO) +// .queueName(getQueueName(0)) +// .disableAutoComplete() +// .buildAsyncClient()); +// +// final ServiceBusClientBuilder receiverSyncBuilder = getBuilder(); +// receiverSync = toClose(receiverSyncBuilder +// .clientOptions(clientOptions) +// .receiver() +// .queueName(getQueueName(0)) +// .buildClient()); +// } +// +// @Override +// protected void afterTest() { +// GlobalOpenTelemetry.resetForTest(); +// sharedBuilder = null; +// } +// +// @Test +// public void sendAndReceive() throws InterruptedException { +// ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); +// ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); +// List messages = Arrays.asList(message1, message2); +// StepVerifier.create(sender.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(2); +// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); +// +// List received = new ArrayList<>(); +// Disposable subscription = receiver.receiveMessages() +// .take(2) +// .doOnNext(msg -> { +// received.add(msg); +// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); +// String traceId = Span.current().getSpanContext().getTraceId(); +// +// // context created for the message and current are the same +// assertTrue(traceparent.startsWith("00-" + traceId)); +// assertFalse(((ReadableSpan) Span.current()).hasEnded()); +// receiver.complete(msg).block(); +// }) +// .subscribe(); +// toClose(subscription); +// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// +// List messageSpans = findSpans(spans, "ServiceBus.message"); +// assertMessageSpan(messageSpans.get(0), message1); +// assertMessageSpan(messageSpans.get(1), message2); +// +// List send = findSpans(spans, "ServiceBus.send"); +// assertClientProducerSpan(send.get(0), messages, "ServiceBus.send", "publish"); +// +// List processed = findSpans(spans, "ServiceBus.process"); +// assertConsumerSpan(processed.get(0), received.get(0), "ServiceBus.process"); +// assertConsumerSpan(processed.get(1), received.get(1), "ServiceBus.process"); +// +// List completed = findSpans(spans, "ServiceBus.complete"); +// assertClientSpan(completed.get(0), Collections.singletonList(received.get(0)), "ServiceBus.complete", "settle"); +// assertClientSpan(completed.get(1), Collections.singletonList(received.get(1)), "ServiceBus.complete", "settle"); +// assertSettledVsProcessed(completed, processed, messages.size()); +// } +// +// @Test +// public void receiveAndRenewLockWithDuration() throws InterruptedException { +// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); +// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(2); +// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewMessageLock")); +// +// AtomicReference received = new AtomicReference<>(); +// StepVerifier.create(receiver.receiveMessages() +// .next() +// .flatMap(msg -> receiver.renewMessageLock(msg, Duration.ofSeconds(2)) +// .thenReturn(msg))) +// .assertNext(msg -> received.compareAndSet(null, msg)) +// .expectComplete() +// .verify(TIMEOUT); +// assertTrue(processedFound.await(30, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// +// List processed = findSpans(spans, "ServiceBus.process"); +// assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); +// +// List renewLock = findSpans(spans, "ServiceBus.renewMessageLock"); +// assertClientSpan(renewLock.get(0), Collections.singletonList(received.get()), "ServiceBus.renewMessageLock", null); +// } +// +// @Test +// public void receiveAndRenewSessionLockWithDuration() throws InterruptedException { +// String sessionId = "10"; +// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) +// .setSessionId(sessionId); +// +// OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), getSessionQueueName(0)); +// final ServiceBusClientBuilder senderBuilder = getBuilder(); +// sender = toClose(senderBuilder +// .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) +// .sender() +// .queueName(getSessionQueueName(0)) +// .buildAsyncClient()); +// +// final ServiceBusClientBuilder receiverBuilder = getBuilder(); +// ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(receiverBuilder +// .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) +// .sessionReceiver() +// .disableAutoComplete() +// .queueName(getSessionQueueName(0)) +// .buildAsyncClient()); +// +// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(2); +// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewSessionLock")); +// +// AtomicReference received = new AtomicReference<>(); +// StepVerifier.create( +// sessionReceiver +// .acceptSession(sessionId) +// .flatMapMany(rec -> rec +// .renewSessionLock() +// .then(rec.receiveMessages().next()))) +// .assertNext(msg -> { +// received.set(msg); +// logger.atInfo() +// .addKeyValue("lockedUntil", msg.getLockedUntil()) +// .addKeyValue("sessionId", msg.getSessionId()) +// .log("message received"); +// }) +// .expectComplete() +// .verify(TIMEOUT); +// +// assertTrue(processedFound.await(30, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// +// List processed = findSpans(spans, "ServiceBus.process"); +// assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); +// +// List acceptSession = findSpans(spans, "ServiceBus.acceptSession"); +// assertClientSpan(acceptSession.get(0), Collections.emptyList(), "ServiceBus.acceptSession", null); +// +// List renewLock = findSpans(spans, "ServiceBus.renewSessionLock"); +// assertClientSpan(renewLock.get(0), Collections.emptyList(), "ServiceBus.renewSessionLock", null); +// } +// +// @Test +// public void receiveCheckSubscribe() throws InterruptedException { +// ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); +// ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); +// List messages = Arrays.asList(message1, message2); +// StepVerifier.create(sender.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(2); +// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); +// +// Disposable subscription = receiver.receiveMessages() +// .take(messages.size()) +// .subscribe(msg -> { +// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); +// String traceId = Span.current().getSpanContext().getTraceId(); +// +// // context created for the message and current are the same +// assertTrue(traceparent.startsWith("00-" + traceId)); +// assertFalse(((ReadableSpan) Span.current()).hasEnded()); +// receiver.complete(msg).block(); +// }); +// toClose(subscription); +// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messages.size()); +// } +// +// @Test +// public void sendAndReceiveParallelNoAutoCompleteAndLockRenewal() throws InterruptedException { +// int messageCount = 5; +// StepVerifier.create(sender.createMessageBatch() +// .doOnNext(batch -> { +// for (int i = 0; i < messageCount; i++) { +// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); +// } +// }) +// .flatMap(batch -> sender.sendMessages(batch))) +// .expectComplete() +// .verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(messageCount); +// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); +// +// final ServiceBusClientBuilder receiverBuilder = getBuilder(); +// ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(receiverBuilder +// .clientOptions(clientOptions) +// .receiver() +// .queueName(getQueueName(0)) +// .disableAutoComplete() +// .buildAsyncClient()); +// +// StepVerifier.create( +// receiverWithLockRenewal.receiveMessages() +// .take(messageCount) +// .doOnNext(msg -> { +// if (Span.current().getSpanContext().isValid()) { +// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); +// String traceId = Span.current().getSpanContext().getTraceId(); +// +// // context created for the message and current are the same +// assertTrue(traceparent.startsWith("00-" + traceId)); +// assertFalse(((ReadableSpan) Span.current()).hasEnded()); +// } +// receiver.complete(msg).block(); +// }) +// .parallel(messageCount, 1) +// .runOn(Schedulers.boundedElastic(), 1)) +// .expectNextCount(messageCount) +// .expectComplete() +// .verify(TIMEOUT); +// +// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// +// // all completed spans should have a parent, but complete call may start after the parent span has ended +// // the last part heavily depends on how above code is written wrt parallelization. +// // in the current form (receive -> doonnext (complete) -> parallel) +// // complete is happens synchronously from the receive perspective +// // so complete will finish before processing is completed. +// // +// // if complete call is done differently (e.g. receive -> parallel -> runon -> doonnext (complete)) +// // then doonnext callbacks become async and may happen after receiver call has completed +// // then complete will be a child of process, but will last longer than processing +// // TODO (limolkova): this is another good reason to rename receiver's span to delivery instead of processing. +// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); +// } +// +// @Test +// public void sendAndReceiveParallelAutoComplete() throws InterruptedException { +// int messageCount = 5; +// StepVerifier.create(sender.createMessageBatch() +// .doOnNext(batch -> { +// for (int i = 0; i < messageCount; i++) { +// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); +// } +// }) +// .flatMap(batch -> sender.sendMessages(batch))) +// .expectComplete() +// .verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(messageCount); +// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); +// +// final ServiceBusClientBuilder receiverBuilder = getBuilder(); +// ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(receiverBuilder +// .clientOptions(clientOptions) +// .receiver() +// .queueName(getQueueName(0)) +// .buildAsyncClient()); +// +// StepVerifier.create( +// receiverAutoComplete.receiveMessages() +// .take(messageCount) +// .doOnNext(msg -> { +// if (Span.current().getSpanContext().isValid()) { +// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); +// String traceId = Span.current().getSpanContext().getTraceId(); +// +// // context created for the message and current are the same +// assertTrue(traceparent.startsWith("00-" + traceId)); +// assertFalse(((ReadableSpan) Span.current()).hasEnded()); +// } +// }) +// .parallel(messageCount, 1) +// .runOn(Schedulers.boundedElastic(), 1)) +// .expectNextCount(messageCount) +// .expectComplete() +// .verify(TIMEOUT); +// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); +// } +// +// @Test +// public void sendReceiveRenewLockAndDefer() throws InterruptedException { +// String traceId = IdGenerator.random().generateTraceId(); +// String traceparent = "00-" + traceId + "-" + IdGenerator.random().generateSpanId() + "-01"; +// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); +// AtomicReference receivedMessage = new AtomicReference<>(); +// message.getApplicationProperties().put("traceparent", traceparent); +// +// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); +// +// CountDownLatch latch = new CountDownLatch(1); +// spanProcessor.notifyIfCondition(latch, s -> s.getName().equals("ServiceBus.receiveDeferredMessage")); +// toClose(receiver.receiveMessages() +// .filter(m -> traceparent.equals(m.getApplicationProperties().get("traceparent"))) +// .flatMap(m -> receiver.renewMessageLock(m).thenReturn(m)) +// .flatMap(m -> receiver.defer(m, new DeferOptions()).thenReturn(m)) +// .flatMap(m -> receiver.receiveDeferredMessage(m.getSequenceNumber()).thenReturn(m)) +// .subscribe(m -> { +// receivedMessage.compareAndSet(null, m); +// })); +// assertTrue(latch.await(120, TimeUnit.SECONDS)); +// +// List spans = spanProcessor.getEndedSpans(); +// +// assertEquals(0, findSpans(spans, "ServiceBus.message").size()); +// +// List send = findSpans(spans, "ServiceBus.send"); +// assertClientProducerSpan(send.get(0), Collections.singletonList(message), "ServiceBus.send", "publish"); +// +// List process = findSpans(spans, "ServiceBus.process", traceId); +// assertConsumerSpan(process.get(0), receivedMessage.get(), "ServiceBus.process"); +// +// List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock", traceId); +// assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.renewMessageLock", null); +// assertParent(renewMessageLock.get(0), process.get(0)); +// +// // for correlation to work after first async call, we need to enable otel rector instrumentations, +// // so no correlation beyond this point +// List defer = findSpans(spans, "ServiceBus.defer"); +// assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.defer", "settle"); +// +// List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); +// assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.receiveDeferredMessage", "receive"); +// } +// +// @Test +// public void sendReceiveRenewLockAndDeferSync() { +// StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) +// .expectComplete() +// .verify(TIMEOUT); +// +// ServiceBusReceivedMessage receivedMessage = null; +// while (receivedMessage == null) { +// IterableStream messages = receiverSync.receiveMessages(1, Duration.ofSeconds(10)); +// if (messages.iterator().hasNext()) { +// receivedMessage = messages.iterator().next(); +// } +// } +// +// receiverSync.renewMessageLock(receivedMessage); +// receiverSync.defer(receivedMessage, new DeferOptions()); +// receiverSync.receiveDeferredMessage(receivedMessage.getSequenceNumber()); +// +// List spans = spanProcessor.getEndedSpans(); +// +// List received = findSpans(spans, "ServiceBus.receiveMessages"); +// assertClientSpan(received.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveMessages", "receive"); +// +// List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock"); +// assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage), "ServiceBus.renewMessageLock", null); +// +// List defer = findSpans(spans, "ServiceBus.defer"); +// assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage), "ServiceBus.defer", "settle"); +// +// List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); +// assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveDeferredMessage", "receive"); +// } +// +// @Test +// public void syncReceive() { +// List messages = new ArrayList<>(); +// messages.add(new ServiceBusMessage(CONTENTS_BYTES)); +// messages.add(new ServiceBusMessage(CONTENTS_BYTES)); +// +// StepVerifier.create(sender.sendMessages(messages)) +// .expectComplete() +// .verify(TIMEOUT); +// +// List receivedMessages = receiverSync.receiveMessages(2, Duration.ofSeconds(10)) +// .stream().collect(Collectors.toList()); +// receivedMessages.forEach(receiverSync::complete); +// +// List spans = spanProcessor.getEndedSpans(); +// +// List received = findSpans(spans, "ServiceBus.receiveMessages"); +// assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); +// +// assertEquals(0, findSpans(spans, "ServiceBus.process").size()); +// +// List completed = findSpans(spans, "ServiceBus.complete"); +// assertClientSpan(completed.get(0), Collections.singletonList(receivedMessages.get(0)), "ServiceBus.complete", "settle"); +// assertClientSpan(completed.get(1), Collections.singletonList(receivedMessages.get(1)), "ServiceBus.complete", "settle"); +// } +// +// @Test +// public void syncReceiveTimeout() { +// List receivedMessages = receiverSync.receiveMessages(100, Duration.ofMillis(1)) +// .stream().collect(Collectors.toList()); +// +// List spans = spanProcessor.getEndedSpans(); +// +// List received = findSpans(spans, "ServiceBus.receiveMessages"); +// assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); +// assertEquals(StatusCode.UNSET, received.get(0).toSpanData().getStatus().getStatusCode()); +// +// assertEquals(0, findSpans(spans, "ServiceBus.process").size()); +// } +// +// @Test +// public void peekMessage() { +// StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) +// .expectComplete() +// .verify(TIMEOUT); +// +// StepVerifier.create(receiver.peekMessage()) +// .assertNext(receivedMessage -> { +// ReadableSpan received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage").get(0); +// if (receivedMessage.getApplicationProperties().containsKey("traceparent")) { +// logger.atInfo() +// .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) +// .log("span should have link"); +// assertClientSpan(received, Collections.singletonList(receivedMessage), "ServiceBus.peekMessage", "receive"); +// } else { +// assertEquals("ServiceBus.peekMessage", received.getName()); +// assertEquals(SpanKind.CLIENT, received.getKind()); +// assertEquals(0, received.toSpanData().getLinks().size()); +// assertEquals("receive", received.getAttribute(AttributeKey.stringKey("messaging.operation"))); +// } +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// @Test +// public void peekNonExistingMessage() { +// StepVerifier.create(receiver.peekMessage(Long.MAX_VALUE - 1)) +// .expectComplete() +// .verify(TIMEOUT); +// +// List received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage"); +// assertClientSpan(received.get(0), Collections.emptyList(), "ServiceBus.peekMessage", "receive"); +// } +// +// @Test +// public void sendAndProcessNoAutoComplete() throws InterruptedException { +// String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) +// .setMessageId(messageId); +// +// StepVerifier.create(sender.sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// +// String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); +// CountDownLatch processFound = new CountDownLatch(1); +// spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") && span.getParentSpanContext().getSpanId().equals(message1SpanId)); +// +// AtomicReference currentInProcess = new AtomicReference<>(); +// AtomicReference receivedMessage = new AtomicReference<>(); +// final ServiceBusClientBuilder processorBuilder = getBuilder(); +// processor = toClose(processorBuilder +// .clientOptions(clientOptions) +// .processor() +// .queueName(getQueueName(0)) +// .processMessage(mc -> { +// if (mc.getMessage().getMessageId().equals(messageId)) { +// currentInProcess.compareAndSet(null, Span.current()); +// receivedMessage.compareAndSet(null, mc.getMessage()); +// } +// mc.complete(); +// }) +// .processError(e -> fail("unexpected error", e.getException())) +// .buildProcessorClient()); +// +// toClose((AutoCloseable) () -> processor.stop()); +// processor.start(); +// assertTrue(processFound.await(20, TimeUnit.SECONDS)); +// processor.stop(); +// +// assertTrue(currentInProcess.get().getSpanContext().isValid()); +// List spans = spanProcessor.getEndedSpans(); +// +// assertMessageSpan(spans.get(0), message); +// assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.send", "publish"); +// +// assertEquals(0, findSpans(spans, "ServiceBus.consume").size()); +// List processed = findSpans(spans, "ServiceBus.process") +// .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); +// assertEquals(1, processed.size()); +// assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); +// +// List completed = findSpans(spans, "ServiceBus.complete").stream() +// .filter(c -> { +// List links = c.toSpanData().getLinks(); +// return !links.isEmpty() && links.get(0).getSpanContext().getSpanId().equals(message1SpanId); +// }) +// .collect(Collectors.toList()); +// assertEquals(1, completed.size()); +// assertClientProducerSpan(completed.get(0), Collections.singletonList(message), "ServiceBus.complete", "settle"); +// +// assertSettledVsProcessed(completed, processed, 1); +// } +// +// @Test +// public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { +// String sessionQueueName = getSessionQueueName(0); +// String sessionId = UUID.randomUUID().toString(); +// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES).setSessionId(sessionId); +// +// OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), sessionQueueName); +// clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); +// final ServiceBusClientBuilder senderBuilder = getBuilder(); +// sender = toClose(senderBuilder +// .clientOptions(clientOptions) +// .sender() +// .queueName(sessionQueueName) +// .buildAsyncClient()); +// +// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); +// +// CountDownLatch processFound = new CountDownLatch(2); +// spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); +// +// AtomicReference currentInProcess = new AtomicReference<>(); +// AtomicReference receivedMessage = new AtomicReference<>(); +// final ServiceBusClientBuilder processorBuilder = getBuilder(); +// processor = toClose(processorBuilder +// .clientOptions(clientOptions) +// .sessionProcessor() +// .maxConcurrentSessions(1) +// .queueName(sessionQueueName) +// .disableAutoComplete() +// .processMessage(mc -> { +// currentInProcess.compareAndSet(null, Span.current()); +// receivedMessage.compareAndSet(null, mc.getMessage()); +// mc.complete(); +// }) +// .processError(e -> fail("unexpected error", e.getException())) +// .buildProcessorClient()); +// +// toClose((AutoCloseable) () -> processor.stop()); +// processor.start(); +// assertTrue(processFound.await(20, TimeUnit.SECONDS)); +// processor.stop(); +// +// assertTrue(currentInProcess.get().getSpanContext().isValid()); +// List spans = spanProcessor.getEndedSpans(); +// +// List processed = findSpans(spans, "ServiceBus.process") +// .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); +// assertEquals(1, processed.size()); +// assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); +// +// List completed = findSpans(spans, "ServiceBus.complete"); +// assertEquals(1, completed.size()); +// assertClientSpan(completed.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.complete", "settle"); +// assertSettledVsProcessed(completed, processed, 1); +// } +// +// @Test +// public void sendAndProcessParallel() throws InterruptedException { +// int messageCount = 10; +// StepVerifier.create(sender.createMessageBatch() +// .doOnNext(batch -> { +// for (int i = 0; i < messageCount; i++) { +// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES) +// .setMessageId(UUID.randomUUID().toString())); +// } +// }) +// .flatMap(batch -> { +// logMessages(batch.getMessages(), sender.getEntityPath(), "sending"); +// return sender.sendMessages(batch); +// })) +// .expectComplete() +// .verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(messageCount * 2); +// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); +// +// final ServiceBusClientBuilder processorBuilder = getBuilder(); +// processor = toClose(processorBuilder +// .clientOptions(clientOptions) +// .processor() +// .queueName(getQueueName(0)) +// .maxConcurrentCalls(messageCount) +// .processMessage(mc -> { +// logMessage(mc.getMessage(), processor.getQueueName(), "processing"); +// String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); +// String traceId = Span.current().getSpanContext().getTraceId(); +// +// // context created for the message and current are the same +// assertTrue(traceparent.startsWith("00-" + traceId)); +// assertFalse(((ReadableSpan) Span.current()).hasEnded()); +// }) +// .processError(e -> fail("unexpected error", e.getException())) +// .buildProcessorClient()); +// toClose((AutoCloseable) () -> processor.stop()); +// processor.start(); +// assertTrue(processedFound.await(30, TimeUnit.SECONDS)); +// processor.stop(); +// +// List spans = spanProcessor.getEndedSpans(); +// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); +// } +// +// @Test +// public void sendAndProcessParallelNoAutoComplete() throws InterruptedException { +// int messageCount = 5; +// StepVerifier.create(sender.createMessageBatch() +// .doOnNext(batch -> { +// for (int i = 0; i < messageCount; i++) { +// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); +// } +// }) +// .flatMap(batch -> sender.sendMessages(batch))) +// .expectComplete() +// .verify(TIMEOUT); +// +// CountDownLatch processedFound = new CountDownLatch(messageCount); +// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); +// +// final ServiceBusClientBuilder processorBuilder = getBuilder(); +// processor = toClose(processorBuilder +// .clientOptions(clientOptions) +// .processor() +// .queueName(getQueueName(0)) +// .maxConcurrentCalls(messageCount) +// .disableAutoComplete() +// .processMessage(mc -> { +// String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); +// String traceId = Span.current().getSpanContext().getTraceId(); +// +// // context created for the message and current are the same +// assertTrue(traceparent.startsWith("00-" + traceId)); +// mc.complete(); +// }) +// .processError(e -> fail("unexpected error", e.getException())) +// .buildProcessorClient()); +// toClose((AutoCloseable) () -> processor.stop()); +// processor.start(); +// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); +// processor.stop(); +// +// List spans = spanProcessor.getEndedSpans(); +// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); +// } +// +// @Test +// public void sendProcessAndFail() throws InterruptedException { +// String messageId = UUID.randomUUID().toString(); +// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) +// .setMessageId(messageId); +// +// StepVerifier.create(sender.sendMessage(message)) +// .expectComplete() +// .verify(TIMEOUT); +// +// String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); +// +// CountDownLatch messageProcessed = new CountDownLatch(1); +// spanProcessor.notifyIfCondition(messageProcessed, span -> +// "ServiceBus.process".equals(span.getName()) && span.getParentSpanContext().getSpanId().equals(message1SpanId)); +// +// AtomicReference receivedMessage = new AtomicReference<>(); +// final ServiceBusClientBuilder processorBuilder = getBuilder(); +// processor = toClose(processorBuilder +// .clientOptions(clientOptions) +// .processor() +// .queueName(getQueueName(0)) +// .processMessage(mc -> { +// if (mc.getMessage().getMessageId().equals(messageId)) { +// receivedMessage.compareAndSet(null, mc.getMessage()); +// throw new RuntimeException("foo"); +// } +// }) +// .processError(e -> { }) +// .buildProcessorClient()); +// toClose((AutoCloseable) () -> processor.stop()); +// processor.start(); +// assertTrue(messageProcessed.await(30, TimeUnit.SECONDS)); +// processor.stop(); +// +// List spans = spanProcessor.getEndedSpans(); +// List processed = findSpans(spans, "ServiceBus.process") +// .stream().filter(p -> p.getParentSpanContext().isValid()) +// .filter(p -> p.toSpanData().getStatus().getStatusCode() == StatusCode.ERROR) +// .collect(Collectors.toList()); +// assertEquals(1, processed.size()); +// assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); +// +// List abandoned = findSpans(spans, "ServiceBus.abandon").stream() +// .filter(c -> c.toSpanData().getLinks().get(0).getSpanContext().getSpanId().equals(message1SpanId)) +// .collect(Collectors.toList()); +// assertEquals(1, abandoned.size()); +// assertClientProducerSpan(abandoned.get(0), Collections.singletonList(message), "ServiceBus.abandon", "settle"); +// assertSettledVsProcessed(abandoned, processed, 1); +// } +// +// @Test +// public void scheduleAndCancelMessage() { +// ServiceBusMessage message = new ServiceBusMessage("m"); +// StepVerifier.create( +// sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(100)) +// .flatMap(l -> sender.cancelScheduledMessage(l))) +// .expectComplete() +// .verify(TIMEOUT); +// +// List spans = spanProcessor.getEndedSpans(); +// assertMessageSpan(spans.get(0), message); +// assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.scheduleMessage", "publish"); +// assertClientProducerSpan(spans.get(2), Collections.emptyList(), "ServiceBus.cancelScheduledMessage", null); +// } +// +// private void assertMessageSpan(ReadableSpan actual, ServiceBusMessage message) { +// assertEquals("ServiceBus.message", actual.getName()); +// assertEquals(SpanKind.PRODUCER, actual.getKind()); +// assertNull(actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); +// String traceparent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getSpanContext().getSpanId() + "-01"; +// assertEquals(message.getApplicationProperties().get("Diagnostic-Id"), traceparent); +// assertEquals(message.getApplicationProperties().get("traceparent"), traceparent); +// } +// +// private void assertClientProducerSpan(ReadableSpan actual, List messages, String spanName, String operationName) { +// assertEquals(spanName, actual.getName()); +// assertEquals(SpanKind.CLIENT, actual.getKind()); +// List links = actual.toSpanData().getLinks(); +// assertEquals(messages.size(), links.size()); +// assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); +// if (messages.size() > 1) { +// assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); +// } +// +// for (int i = 0; i < links.size(); i++) { +// String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); +// SpanContext linkContext = links.get(i).getSpanContext(); +// String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; +// assertEquals(messageTraceparent, linkTraceparent); +// } +// } +// +// private void assertClientSpan(ReadableSpan actual, List messages, String spanName, String operationName) { +// assertEquals(spanName, actual.getName()); +// assertEquals(SpanKind.CLIENT, actual.getKind()); +// List links = actual.toSpanData().getLinks(); +// assertEquals(messages.size(), links.size()); +// assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); +// if (messages.size() > 1) { +// assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); +// } +// for (int i = 0; i < links.size(); i++) { +// String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); +// SpanContext linkContext = links.get(i).getSpanContext(); +// String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; +// assertEquals(messageTraceparent, linkTraceparent); +// assertNotNull(links.get(i).getAttributes().get(AttributeKey.longKey(ServiceBusTracer.MESSAGE_ENQUEUED_TIME_ATTRIBUTE_NAME))); +// } +// } +// +// private void assertConsumerSpan(ReadableSpan actual, ServiceBusReceivedMessage message, String spanName) { +// assertEquals(spanName, actual.getName()); +// assertEquals(SpanKind.CONSUMER, actual.getKind()); +// assertEquals(0, actual.toSpanData().getLinks().size()); +// assertEquals("process", actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); +// String messageTraceparent = (String) message.getApplicationProperties().get("traceparent"); +// String parent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getParentSpanContext().getSpanId() + "-01"; +// assertEquals(messageTraceparent, parent); +// } +// +// private void assertParent(ReadableSpan child, ReadableSpan parent) { +// assertEquals(child.getParentSpanContext().getTraceId(), parent.getSpanContext().getTraceId()); +// assertEquals(child.getParentSpanContext().getSpanId(), parent.getSpanContext().getSpanId()); +// } +// +// private void assertSettledVsProcessed(List settled, List processed, int expectedCount) { +// assertTrue(settled.size() >= expectedCount, +// String.format("Expected at least %d completed spans, but found %d", expectedCount, settled.size())); +// assertTrue(processed.size() >= expectedCount, +// String.format("Expected at least %d processed spans, but found %d", expectedCount, processed.size())); +// +// // there could be more completed spans than processed because completion happens before processing, and we can have more messages in the queue than we expected. +// assertTrue(settled.size() >= processed.size(), +// String.format("Expected at least as many completed spans as processed spans, but found %d completed and %d processed", settled.size(), processed.size())); +// +// int processedFound = 0; +// for (ReadableSpan readableSpan : settled) { +// ReadableSpan parent = findParent(readableSpan, processed); +// if (parent != null) { +// processedFound++; +// assertTrue(readableSpan.getLatencyNanos() <= parent.getLatencyNanos(), () -> +// String.format("Expected settled span to have less latency than processed span, but found %d vs %d", +// readableSpan.getLatencyNanos(), parent.getLatencyNanos())); +// } +// } +// +// assertEquals(expectedCount, processedFound); +// } +// +// private ReadableSpan findParent(ReadableSpan child, List possibleParents) { +// String traceId = child.getParentSpanContext().getTraceId(); +// String parentId = child.getParentSpanContext().getSpanId(); +// for (ReadableSpan p : possibleParents) { +// if (traceId.equals(p.getSpanContext().getTraceId()) +// && parentId.equals(p.getSpanContext().getSpanId())) { +// return p; +// } +// } +// +// return null; +// } +// +// private List findSpans(List spans, String spanName) { +// return spans.stream() +// .filter(s -> s.getName().equals(spanName)) +// .collect(Collectors.toList()); +// } +// +// private List findSpans(List spans, String spanName, String traceId) { +// return spans.stream() +// .filter(s -> s.getName().equals(spanName)) +// .filter(s -> s.getSpanContext().getTraceId().equals(traceId)) +// .collect(Collectors.toList()); +// } +// +// private OpenTelemetry configureOTel(String namespace, String entityName) { +// GlobalOpenTelemetry.resetForTest(); +// spanProcessor = new TestSpanProcessor(namespace, entityName); +// return OpenTelemetrySdk.builder().setTracerProvider( +// SdkTracerProvider.builder() +// .addSpanProcessor(spanProcessor) +// .build()).build(); +// } +// +// static class TestSpanProcessor implements SpanProcessor { +// private static final ClientLogger LOGGER = new ClientLogger(TestSpanProcessor.class); +// private static final AttributeKey AZ_NAMESPACE = AttributeKey.stringKey("az.namespace"); +// private static final AttributeKey MESSAGING_SYSTEM = AttributeKey.stringKey("messaging.system"); +// private static final AttributeKey MESSAGING_DESTINATION_NAME +// = AttributeKey.stringKey("messaging.destination.name"); +// private static final AttributeKey NET_PEER_NAME = AttributeKey.stringKey("net.peer.name"); +// private static final AttributeKey SERVER_ADDRESS = AttributeKey.stringKey("server.address"); +// +// private final ConcurrentLinkedDeque spans = new ConcurrentLinkedDeque<>(); +// private final String entityName; +// private final String namespace; +// +// private final AtomicReference> notifier = new AtomicReference<>(); +// +// TestSpanProcessor(String namespace, String entityName) { +// this.namespace = namespace; +// this.entityName = entityName; +// } +// public List getEndedSpans() { +// return spans.stream().collect(Collectors.toList()); +// } +// +// @Override +// public void onStart(Context context, ReadWriteSpan readWriteSpan) { +// } +// +// @Override +// public boolean isStartRequired() { +// return false; +// } +// +// @Override +// public void onEnd(ReadableSpan readableSpan) { +// LOGGER.info(readableSpan.toString()); +// assertEquals("Microsoft.ServiceBus", readableSpan.getAttribute(AZ_NAMESPACE)); +// assertEquals("servicebus", readableSpan.getAttribute(MESSAGING_SYSTEM)); +// assertEquals(entityName, readableSpan.getAttribute(MESSAGING_DESTINATION_NAME)); +// +// // Depending on the version of OpenTelemetry being used, the attribute name for the peer name may be +// // different. The attribute name was changed from "net.peer.name" to "server.address". +// String actualNamespace = readableSpan.getAttribute(NET_PEER_NAME); +// if (actualNamespace == null) { +// actualNamespace = readableSpan.getAttribute(SERVER_ADDRESS); +// } +// +// assertEquals(namespace, actualNamespace); +// +// spans.add(readableSpan); +// Consumer filter = notifier.get(); +// if (filter != null) { +// filter.accept(readableSpan); +// } +// } +// +// public void notifyIfCondition(CountDownLatch countDownLatch, Predicate filter) { +// notifier.set((span) -> { +// if (filter.test(span)) { +// countDownLatch.countDown(); +// } +// }); +// } +// +// @Override +// public boolean isEndRequired() { +// return true; +// } +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 98bb1a2989f2..9d0dfcf116e8 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -3,79 +3,16 @@ package com.azure.messaging.servicebus.administration; -import com.azure.core.credential.AzureSasCredential; -import com.azure.core.credential.TokenCredential; -import com.azure.core.exception.ClientAuthenticationException; -import com.azure.core.exception.ResourceExistsException; -import com.azure.core.exception.ResourceNotFoundException; -import com.azure.core.http.HttpClient; -import com.azure.core.http.HttpResponse; -import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; -import com.azure.core.http.policy.HttpLogDetailLevel; -import com.azure.core.http.policy.HttpLogOptions; -import com.azure.core.test.InterceptorManager; -import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.models.CustomMatcher; import com.azure.core.test.models.TestProxyRequestMatcher; import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; -import com.azure.core.test.utils.MockTokenCredential; -import com.azure.identity.AzurePowerShellCredentialBuilder; -import com.azure.identity.DefaultAzureCredentialBuilder; -import com.azure.messaging.servicebus.TestUtils; -import com.azure.messaging.servicebus.administration.models.AccessRights; -import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; -import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; -import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; -import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; -import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; -import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; -import com.azure.messaging.servicebus.administration.models.NamespaceProperties; -import com.azure.messaging.servicebus.administration.models.NamespaceType; -import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; -import com.azure.messaging.servicebus.administration.models.RuleProperties; -import com.azure.messaging.servicebus.administration.models.SharedAccessAuthorizationRule; -import com.azure.messaging.servicebus.administration.models.SqlRuleAction; -import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; -import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; -import com.azure.messaging.servicebus.administration.models.TopicProperties; -import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; -import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.time.Clock; import java.time.Duration; -import java.time.OffsetDateTime; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; -import static com.azure.messaging.servicebus.TestUtils.getConnectionString; -import static com.azure.messaging.servicebus.TestUtils.getEntityName; -import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; -import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; -import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; -/** - * Tests {@link ServiceBusAdministrationAsyncClient}. - */ -@Tag("integration") -class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBase { +class ServiceBusAdministrationAsyncClientIntegrationTest { private static final Duration TIMEOUT = Duration.ofSeconds(20); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); @@ -101,1146 +38,1246 @@ class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBa TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); } - - public static Stream createHttpClients() { - return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); - } - - /** - * Test to connect to the service bus with an azure identity TokenCredential. - * com.azure.identity.ClientSecretCredential is used in this test. - * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below - * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. - */ - @ParameterizedTest - @MethodSource("createHttpClients") - void azureIdentityCredentials(HttpClient httpClient) { - - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); - - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); - - if (interceptorManager.isPlaybackMode()) { - builder.httpClient(interceptorManager.getPlaybackClient()); - } else if (interceptorManager.isLiveMode()) { - builder.httpClient(httpClient); - } else { - builder.httpClient(httpClient) - .addPolicy(interceptorManager.getRecordPolicy()); - } - - final ServiceBusAdministrationAsyncClient client = builder - .credential(fullyQualifiedDomainName, tokenCredential) - .buildAsyncClient(); - - StepVerifier.create(client.getNamespaceProperties()) - .assertNext(properties -> { - assertNotNull(properties); - - if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); - assertEquals(split[0], properties.getName()); - } - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - /** - * Test to connect to the service bus with an azure sas credential. - * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below - * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. - */ - @Test - void azureSasCredentialsTest() { - // Arrange - assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - - String connectionString = getConnectionString(true); - Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); - Matcher matcher = sasPattern.matcher(connectionString); - assertTrue(matcher.find(), "Couldn't find SAS from connection string"); - - ServiceBusAdministrationAsyncClient client = new ServiceBusAdministrationClientBuilder() - .endpoint("https://" + fullyQualifiedDomainName) - .credential(new AzureSasCredential(matcher.group(1))) - .buildAsyncClient(); - - // Act & Assert - StepVerifier.create(client.getNamespacePropertiesWithResponse()) - .assertNext(response -> { - final NamespaceProperties np = response.getValue(); - assertNotNull(np.getName()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - //region Create tests - - @ParameterizedTest - @MethodSource("createHttpClients") - void createQueue(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("test", 10); - final CreateQueueOptions expected = new CreateQueueOptions() - .setMaxSizeInMegabytes(1024) - .setMaxDeliveryCount(7) - .setLockDuration(Duration.ofSeconds(45)) - .setSessionRequired(true) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing"); - - // Act & Assert - StepVerifier.create(client.createQueue(queueName, expected)) - .assertNext(actual -> { - assertEquals(queueName, actual.getName()); - - assertEquals(expected.getLockDuration(), actual.getLockDuration()); - assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); - assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - - assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); - assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); - assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); - assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); - assertEquals(0, runtimeProperties.getTotalMessageCount()); - assertEquals(0, runtimeProperties.getSizeInBytes()); - assertNotNull(runtimeProperties.getCreatedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createQueueExistingName(HttpClient httpClient) { - // Arrange - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); - final CreateQueueOptions options = new CreateQueueOptions(); - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // Act & Assert - StepVerifier.create(client.createQueue(queueName, options)) - .expectError(ResourceExistsException.class) - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createQueueWithForwarding(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("test", 10); - final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); - final CreateQueueOptions expected = new CreateQueueOptions() - .setForwardTo(forwardToEntityName) - .setForwardDeadLetteredMessagesTo(forwardToEntityName); - - // Act & Assert - StepVerifier.create(client.createQueue(queueName, expected)) - .assertNext(actual -> { - assertEquals(queueName, actual.getName()); - - // The URLs will be fake in playback mode. - if (!interceptorManager.isPlaybackMode()) { - assertEquals(expected.getForwardTo(), actual.getForwardTo()); - assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); - } - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); - assertNotNull(runtimeProperties.getCreatedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createQueueAuthorizationRules(HttpClient httpClient) { - // Arrange - final String keyName = "test-rule"; - final List accessRights = Collections.singletonList(AccessRights.SEND); - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("test", 10); - final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() - ? new SharedAccessAuthorizationRule(keyName, "REDACTED", - "REDACTED", accessRights) - : new SharedAccessAuthorizationRule(keyName, accessRights); - - final CreateQueueOptions expected = new CreateQueueOptions() - .setMaxSizeInMegabytes(1024) - .setMaxDeliveryCount(7) - .setLockDuration(Duration.ofSeconds(45)) - .setSessionRequired(true) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing"); - - expected.getAuthorizationRules().add(rule); - - // Act & Assert - StepVerifier.create(client.createQueue(queueName, expected)) - .assertNext(actual -> { - assertEquals(queueName, actual.getName()); - - assertEquals(expected.getLockDuration(), actual.getLockDuration()); - assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); - assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - - assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); - assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); - assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); - assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); - assertEquals(0, runtimeProperties.getTotalMessageCount()); - assertEquals(0, runtimeProperties.getSizeInBytes()); - assertNotNull(runtimeProperties.getCreatedAt()); - - assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createRule(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - final String ruleName = testResourceNamer.randomName("rule", 10); - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); - final CreateRuleOptions options = new CreateRuleOptions() - .setAction(action) - .setFilter(new FalseRuleFilter()); - - // Act & Assert - StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName, options)) - .assertNext(contents -> { - - assertNotNull(contents); - assertEquals(ruleName, contents.getName()); - - assertNotNull(contents.getAction()); - assertTrue(contents.getAction() instanceof SqlRuleAction); - assertEquals(action.getSqlExpression(), ((SqlRuleAction) contents.getAction()).getSqlExpression()); - - assertNotNull(contents.getFilter()); - assertTrue(contents.getFilter() instanceof FalseRuleFilter); - - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createRuleDefaults(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - final String ruleName = testResourceNamer.randomName("rule", 10); - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName)) - .assertNext(contents -> { - assertEquals(ruleName, contents.getName()); - assertTrue(contents.getFilter() instanceof TrueRuleFilter); - assertTrue(contents.getAction() instanceof EmptyRuleAction); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createRuleResponse(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - final String ruleName = testResourceNamer.randomName("rule", 10); - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); - filter.getParameters().put("@MyParameter", "My-Parameter-Value"); - - final CreateRuleOptions options = new CreateRuleOptions() - .setAction(new EmptyRuleAction()) - .setFilter(filter); - - // Act & Assert - StepVerifier.create(client.createRuleWithResponse(topicName, subscriptionName, ruleName, options)) - .assertNext(response -> { - assertEquals(201, response.getStatusCode()); - - final RuleProperties contents = response.getValue(); - - assertNotNull(contents); - assertEquals(ruleName, contents.getName()); - - assertNotNull(contents.getFilter()); - assertTrue(contents.getFilter() instanceof SqlRuleFilter); - - final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); - assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); - - assertNotNull(contents.getAction()); - assertTrue(contents.getAction() instanceof EmptyRuleAction); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createSubscription(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 0); - final String subscriptionName = testResourceNamer.randomName("sub", 10); - final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() - .setMaxDeliveryCount(7) - .setLockDuration(Duration.ofSeconds(45)) - .setUserMetadata("some-metadata-for-testing-subscriptions"); - - // Act & Assert - StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) - .assertNext(actual -> { - assertEquals(topicName, actual.getTopicName()); - assertEquals(subscriptionName, actual.getSubscriptionName()); - - assertEquals(expected.getLockDuration(), actual.getLockDuration()); - assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - - assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); - assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createSubscriptionWithRule(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 0); - final String subscriptionName = testResourceNamer.randomName("sub", 10); - final CreateSubscriptionOptions subscriptionOptions = new CreateSubscriptionOptions() - .setMaxDeliveryCount(7) - .setLockDuration(Duration.ofSeconds(45)) - .setUserMetadata("some-metadata-for-testing-subscriptions"); - - final String ruleName = testResourceNamer.randomName("rule", 10); - final CreateRuleOptions ruleOptions = new CreateRuleOptions(new SqlRuleFilter("color='red'")); - // Act & Assert - StepVerifier.create(client.createSubscription(topicName, subscriptionName, ruleName, subscriptionOptions, ruleOptions) - .flatMap(s -> client.getRule(topicName, subscriptionName, ruleName))) - .assertNext(rule -> { - assertEquals(ruleName, rule.getName()); - assertTrue(rule.getFilter() instanceof SqlRuleFilter); - assertEquals("color='red'", ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createSubscriptionExistingName(HttpClient httpClient) { - // Arrange - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = getSessionSubscriptionBaseName(); - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // Act & Assert - StepVerifier.create(client.createSubscription(topicName, subscriptionName)) - .expectError(ResourceExistsException.class) - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createSubscriptionWithForwarding(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 3); - final String subscriptionName = testResourceNamer.randomName("sub", 50); - final String forwardToTopic = getEntityName(getTopicBaseName(), 4); - final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() - .setForwardTo(forwardToTopic) - .setForwardDeadLetteredMessagesTo(forwardToTopic); - - // Act & Assert - StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) - .assertNext(actual -> { - assertEquals(topicName, actual.getTopicName()); - assertEquals(subscriptionName, actual.getSubscriptionName()); - - // URLs are redacted so they will not match. - if (!interceptorManager.isPlaybackMode()) { - assertEquals(expected.getForwardTo(), actual.getForwardTo()); - assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); - } - }) - .expectComplete() - .verify(TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createTopicWithResponse(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("test", 10); - final CreateTopicOptions expected = new CreateTopicOptions() - .setMaxSizeInMegabytes(2048L) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing-topic"); - - // Act & Assert - StepVerifier.create(client.createTopicWithResponse(topicName, expected)) - .assertNext(response -> { - assertEquals(201, response.getStatusCode()); - - // Assert values on a topic. - final TopicProperties actual = response.getValue(); - - assertEquals(topicName, actual.getName()); - - assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - - assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); - assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); - - final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); - assertEquals(0, runtimeProperties.getSubscriptionCount()); - assertEquals(0, runtimeProperties.getSizeInBytes()); - assertNotNull(runtimeProperties.getCreatedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void createTopicExistingName(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 3); - final CreateTopicOptions expected = new CreateTopicOptions() - .setMaxSizeInMegabytes(2048L) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing-topic"); - - // Act & Assert - StepVerifier.create(client.createTopicWithResponse(topicName, expected)) - .expectError(ResourceExistsException.class) - .verify(DEFAULT_TIMEOUT); - } - - //endregion - - //region Delete tests - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteQueue(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("sub", 10); - - client.createQueue(queueName) - .onErrorResume(ResourceExistsException.class, e -> Mono.empty()) - .block(TIMEOUT); - - // Act & Assert - StepVerifier.create(client.deleteQueue(queueName)) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteQueueDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("queue", 10); - - // Act & Assert - StepVerifier.create(client.deleteQueue(queueName)) - .expectError(ResourceNotFoundException.class) - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteRule(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String ruleName = testResourceNamer.randomName("rule-", 11); - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); - - // Act & Assert - StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteRuleDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String ruleName = testResourceNamer.randomName("rule-", 11); - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) - .expectError(ResourceNotFoundException.class) - .verify(TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteSubscription(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("topic", 10); - final String subscriptionName = testResourceNamer.randomName("sub", 7); - - client.createTopic(topicName).block(TIMEOUT); - client.createSubscription(topicName, subscriptionName).block(TIMEOUT); - - // Act & Assert - StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteSubscriptionDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("topic", 10); - final String subscriptionName = testResourceNamer.randomName("sub", 7); - - // The topic exists but the subscription does not. - client.createTopic(topicName).block(TIMEOUT); - - // Act & Assert - StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) - .expectError(ResourceNotFoundException.class) - .verify(TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteTopic(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("topic", 10); - - client.createTopic(topicName).block(TIMEOUT); - - // Act & Assert - StepVerifier.create(client.deleteTopic(topicName)) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void deleteTopicDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("topic", 10); - - // Act & Assert - StepVerifier.create(client.deleteTopic(topicName)) - .expectError(ResourceNotFoundException.class) - .verify(TIMEOUT); - } - - //endregion - - //region Get and exists tests - - @ParameterizedTest - @MethodSource("createHttpClients") - void getQueue(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - // Act & Assert - StepVerifier.create(client.getQueue(queueName)) - .assertNext(queueDescription -> { - assertEquals(queueName, queueDescription.getName()); - - assertFalse(queueDescription.isPartitioningEnabled()); - assertFalse(queueDescription.isSessionRequired()); - assertNotNull(queueDescription.getLockDuration()); - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueDescription); - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getNamespace(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // Act & Assert - StepVerifier.create(client.getNamespaceProperties()) - .assertNext(properties -> { - assertEquals(NamespaceType.MESSAGING, properties.getNamespaceType()); - if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); - assertEquals(split[0], properties.getName()); - } - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getQueueDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("exist", 10); - - // Act & Assert - StepVerifier.create(client.getQueue(queueName)) - .expectError(ResourceNotFoundException.class) - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getQueueExists(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); - - // Act & Assert - StepVerifier.create(client.getQueueExists(queueName)) - .expectNext(true) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getQueueExistsFalse(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = testResourceNamer.randomName("exist", 10); - - // Act & Assert - StepVerifier.create(client.getQueueExists(queueName)) - .expectNext(false) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getQueueRuntimeProperties(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - // Act & Assert - StepVerifier.create(client.getQueueRuntimeProperties(queueName)) - .assertNext(RuntimeProperties -> { - assertEquals(queueName, RuntimeProperties.getName()); - - assertNotNull(RuntimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); - assertNotNull(RuntimeProperties.getAccessedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getRule(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // There is a single default rule created. - final String ruleName = "$Default"; - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) - .assertNext(response -> { - assertEquals(200, response.getStatusCode()); - - final RuleProperties contents = response.getValue(); - - assertNotNull(contents); - assertEquals(ruleName, contents.getName()); - assertNotNull(contents.getFilter()); - assertTrue(contents.getFilter() instanceof TrueRuleFilter); - - assertNotNull(contents.getAction()); - assertTrue(contents.getAction() instanceof EmptyRuleAction); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getRuleDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - final String ruleName = "does-not-exist-rule"; - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) - .expectError(ResourceNotFoundException.class) - .verify(TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getSubscription(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = getSessionSubscriptionBaseName(); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - // Act & Assert - StepVerifier.create(client.getSubscription(topicName, subscriptionName)) - .assertNext(description -> { - assertEquals(topicName, description.getTopicName()); - assertEquals(subscriptionName, description.getSubscriptionName()); - - assertTrue(description.isSessionRequired()); - assertNotNull(description.getLockDuration()); - - final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(description); - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getSubscriptionDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = "subscription-session-not-exist"; - - // Act & Assert - StepVerifier.create(client.getSubscription(topicName, subscriptionName)) - .expectError(ResourceNotFoundException.class) - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getSubscriptionExists(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = getSessionSubscriptionBaseName(); - - // Act & Assert - StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) - .expectNext(true) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getSubscriptionExistsFalse(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = "subscription-session-not-exist"; - - // Act & Assert - StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) - .expectNext(false) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getSubscriptionRuntimeProperties(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = getSessionSubscriptionBaseName(); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - // Act & Assert - StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) - .assertNext(description -> { - assertEquals(topicName, description.getTopicName()); - assertEquals(subscriptionName, description.getSubscriptionName()); - - assertTrue(description.getTotalMessageCount() >= 0); - assertEquals(0, description.getActiveMessageCount()); - assertEquals(0, description.getTransferDeadLetterMessageCount()); - assertEquals(0, description.getTransferMessageCount()); - assertTrue(description.getDeadLetterMessageCount() >= 0); - - assertNotNull(description.getCreatedAt()); - assertTrue(nowUtc.isAfter(description.getCreatedAt())); - assertNotNull(description.getAccessedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getTopic(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - // Act & Assert - StepVerifier.create(client.getTopic(topicName)) - .assertNext(topicDescription -> { - assertEquals(topicName, topicDescription.getName()); - - assertTrue(topicDescription.isBatchedOperationsEnabled()); - assertFalse(topicDescription.isDuplicateDetectionRequired()); - assertNotNull(topicDescription.getDuplicateDetectionHistoryTimeWindow()); - assertNotNull(topicDescription.getDefaultMessageTimeToLive()); - assertFalse(topicDescription.isPartitioningEnabled()); - - final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicDescription); - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getTopicDoesNotExist(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("exists", 10); - - // Act & Assert - StepVerifier.create(client.getTopic(topicName)) - .consumeErrorWith(error -> { - assertTrue(error instanceof ResourceNotFoundException); - - final ResourceNotFoundException notFoundError = (ResourceNotFoundException) error; - final HttpResponse response = notFoundError.getResponse(); - - assertNotNull(response); - assertEquals(200, response.getStatusCode()); - StepVerifier.create(response.getBody()) - .verifyComplete(); - }) - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getTopicExists(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - - // Act & Assert - StepVerifier.create(client.getTopicExists(topicName)) - .expectNext(true) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getTopicExistsFalse(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = testResourceNamer.randomName("exists", 10); - - // Act & Assert - StepVerifier.create(client.getTopicExists(topicName)) - .expectNext(false) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getTopicRuntimeProperties(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - // Act & Assert - StepVerifier.create(client.getTopicRuntimeProperties(topicName)) - .assertNext(RuntimeProperties -> { - assertEquals(topicName, RuntimeProperties.getName()); - - assertTrue(RuntimeProperties.getSubscriptionCount() > 1); - - assertNotNull(RuntimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); - assertNotNull(RuntimeProperties.getAccessedAt()); - assertTrue(nowUtc.isAfter(RuntimeProperties.getAccessedAt())); - assertEquals(0, RuntimeProperties.getScheduledMessageCount()); - - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { - // Arrange - final String connectionString = interceptorManager.isPlaybackMode() - ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" - : TestUtils.getConnectionString(false); - - final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", - "SharedAccessKey=fake-key-"); - - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() - .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .connectionString(connectionStringUpdated); - - if (interceptorManager.isPlaybackMode()) { - builder.httpClient(interceptorManager.getPlaybackClient()); - } else if (interceptorManager.isLiveMode()) { - builder.httpClient(httpClient); - } else { - builder.httpClient(httpClient) - .addPolicy(interceptorManager.getRecordPolicy()); - } - - final ServiceBusAdministrationAsyncClient client = builder.buildAsyncClient(); - - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); - - // Act & Assert - StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) - .expectErrorMatches(throwable -> throwable instanceof ClientAuthenticationException) - .verify(DEFAULT_TIMEOUT); - } - - //endregion - - //region List tests - - @ParameterizedTest - @MethodSource("createHttpClients") - void listRules(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // There is a single default rule created. - final String ruleName = "$Default"; - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - StepVerifier.create(client.listRules(topicName, subscriptionName)) - .assertNext(response -> { - assertEquals(ruleName, response.getName()); - assertNotNull(response.getFilter()); - assertTrue(response.getFilter() instanceof TrueRuleFilter); - - assertNotNull(response.getAction()); - assertTrue(response.getAction() instanceof EmptyRuleAction); - }) - .thenCancel() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void listQueues(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // Act & Assert - StepVerifier.create(client.listQueues()) - .assertNext(queueDescription -> { - assertNotNull(queueDescription.getName()); - assertTrue(queueDescription.isBatchedOperationsEnabled()); - assertFalse(queueDescription.isDuplicateDetectionRequired()); - assertFalse(queueDescription.isPartitioningEnabled()); - }) - .expectNextCount(9) - .thenCancel() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void listSubscriptions(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - final String topicName = getEntityName(getTopicBaseName(), 1); - - // Act & Assert - StepVerifier.create(client.listSubscriptions(topicName)) - .assertNext(subscription -> { - assertEquals(topicName, subscription.getTopicName()); - assertNotNull(subscription.getSubscriptionName()); - }) - .expectNextCount(1) - .thenCancel() - .verify(DEFAULT_TIMEOUT); - } - - @ParameterizedTest - @MethodSource("createHttpClients") - void listTopics(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - // Act & Assert - StepVerifier.create(client.listTopics()) - .assertNext(topics -> { - assertNotNull(topics.getName()); - assertTrue(topics.isBatchedOperationsEnabled()); - assertFalse(topics.isPartitioningEnabled()); - }) - .expectNextCount(2) - .thenCancel() - .verify(DEFAULT_TIMEOUT); - } - - //endregion - - @ParameterizedTest - @MethodSource("createHttpClients") - void updateRuleResponse(HttpClient httpClient) { - // Arrange - final ServiceBusAdministrationAsyncClient client = createClient(httpClient); - - final String ruleName = testResourceNamer.randomName("rule", 15); - final String topicName = getEntityName(getTopicBaseName(), 12); - final String subscriptionName = getSubscriptionBaseName(); - final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); - final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); - - final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); - assertNotNull(existingRule); - - existingRule.setAction(expectedAction).setFilter(expectedFilter); - - // Act & Assert - StepVerifier.create(client.updateRule(topicName, subscriptionName, existingRule)) - .assertNext(contents -> { - assertNotNull(contents); - assertEquals(ruleName, contents.getName()); - - assertTrue(contents.getFilter() instanceof SqlRuleFilter); - assertEquals(expectedFilter.getSqlExpression(), - ((SqlRuleFilter) contents.getFilter()).getSqlExpression()); - - assertTrue(contents.getAction() instanceof SqlRuleAction); - assertEquals(expectedAction.getSqlExpression(), - ((SqlRuleAction) contents.getAction()).getSqlExpression()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - - private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() - .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .credential(getTestTokenCredential(interceptorManager)); - - if (interceptorManager.isPlaybackMode()) { - builder.httpClient(interceptorManager.getPlaybackClient()); - } else if (interceptorManager.isLiveMode()) { - builder.httpClient(httpClient); - } else { - builder.httpClient(httpClient).addPolicy(interceptorManager.getRecordPolicy()); - } - - if (!interceptorManager.isLiveMode()) { - interceptorManager.addSanitizers(TEST_PROXY_SANITIZERS); - interceptorManager.addMatchers(TEST_PROXY_REQUEST_MATCHERS); - } - - return builder.buildAsyncClient(); - } - - /** - * Retrieve the appropriate TokenCredential based on the test mode. - * - * @param interceptorManager the interceptor manager - * @return The appropriate token credential - */ - private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { - if (interceptorManager.isLiveMode()) { - return new AzurePowerShellCredentialBuilder().build(); - } else if (interceptorManager.isRecordMode()) { - return new DefaultAzureCredentialBuilder().build(); - } else { - return new MockTokenCredential(); - } - } } +// +//import com.azure.core.credential.AzureSasCredential; +//import com.azure.core.credential.TokenCredential; +//import com.azure.core.exception.ClientAuthenticationException; +//import com.azure.core.exception.ResourceExistsException; +//import com.azure.core.exception.ResourceNotFoundException; +//import com.azure.core.http.HttpClient; +//import com.azure.core.http.HttpResponse; +//import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; +//import com.azure.core.http.policy.HttpLogDetailLevel; +//import com.azure.core.http.policy.HttpLogOptions; +//import com.azure.core.test.InterceptorManager; +//import com.azure.core.test.TestProxyTestBase; +//import com.azure.core.test.models.CustomMatcher; +//import com.azure.core.test.models.TestProxyRequestMatcher; +//import com.azure.core.test.models.TestProxySanitizer; +//import com.azure.core.test.models.TestProxySanitizerType; +//import com.azure.core.test.utils.MockTokenCredential; +//import com.azure.identity.AzurePowerShellCredentialBuilder; +//import com.azure.identity.DefaultAzureCredentialBuilder; +//import com.azure.messaging.servicebus.TestUtils; +//import com.azure.messaging.servicebus.administration.models.AccessRights; +//import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; +//import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; +//import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; +//import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; +//import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; +//import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; +//import com.azure.messaging.servicebus.administration.models.NamespaceProperties; +//import com.azure.messaging.servicebus.administration.models.NamespaceType; +//import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; +//import com.azure.messaging.servicebus.administration.models.RuleProperties; +//import com.azure.messaging.servicebus.administration.models.SharedAccessAuthorizationRule; +//import com.azure.messaging.servicebus.administration.models.SqlRuleAction; +//import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; +//import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; +//import com.azure.messaging.servicebus.administration.models.TopicProperties; +//import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; +//import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +//import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.params.ParameterizedTest; +//import org.junit.jupiter.params.provider.Arguments; +//import org.junit.jupiter.params.provider.MethodSource; +//import reactor.core.publisher.Mono; +//import reactor.test.StepVerifier; +// +//import java.time.Clock; +//import java.time.Duration; +//import java.time.OffsetDateTime; +//import java.util.Arrays; +//import java.util.Collections; +//import java.util.List; +//import java.util.regex.Matcher; +//import java.util.regex.Pattern; +//import java.util.stream.Stream; +// +//import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; +//import static com.azure.messaging.servicebus.TestUtils.getConnectionString; +//import static com.azure.messaging.servicebus.TestUtils.getEntityName; +//import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; +//import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; +//import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; +//import static org.junit.jupiter.api.Assertions.assertEquals; +//import static org.junit.jupiter.api.Assertions.assertFalse; +//import static org.junit.jupiter.api.Assertions.assertNotNull; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assumptions.assumeTrue; +// +///** +// * Tests {@link ServiceBusAdministrationAsyncClient}. +// */ +//@Tag("integration") +//class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBase { +// private static final Duration TIMEOUT = Duration.ofSeconds(20); +// private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); +// +// /** +// * Sanitizer to remove header values for ServiceBusDlqSupplementaryAuthorization and +// * ServiceBusSupplementaryAuthorization. +// */ +// static final TestProxySanitizer AUTHORIZATION_HEADER; +// +// static final List TEST_PROXY_SANITIZERS; +// +// static final List TEST_PROXY_REQUEST_MATCHERS; +// +// static { +// AUTHORIZATION_HEADER = new TestProxySanitizer("SupplementaryAuthorization", null, +// "SharedAccessSignature sr=https%3A%2F%2Ffoo.servicebus.windows.net&sig=dummyValue%3D&se=1687267490&skn=dummyKey", +// TestProxySanitizerType.HEADER); +// TEST_PROXY_SANITIZERS = Collections.singletonList(AUTHORIZATION_HEADER); +// +// final List skippedHeaders = Arrays.asList("ServiceBusDlqSupplementaryAuthorization", +// "ServiceBusSupplementaryAuthorization"); +// final CustomMatcher customMatcher = new CustomMatcher().setExcludedHeaders(skippedHeaders); +// +// TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); +// } +// +// public static Stream createHttpClients() { +// return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); +// } +// +// /** +// * Test to connect to the service bus with an azure identity TokenCredential. +// * com.azure.identity.ClientSecretCredential is used in this test. +// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below +// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. +// */ +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void azureIdentityCredentials(HttpClient httpClient) { +// +// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); +// final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); +// +// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); +// +// if (interceptorManager.isPlaybackMode()) { +// builder.httpClient(interceptorManager.getPlaybackClient()); +// } else if (interceptorManager.isLiveMode()) { +// builder.httpClient(httpClient); +// } else { +// builder.httpClient(httpClient) +// .addPolicy(interceptorManager.getRecordPolicy()); +// } +// +// final ServiceBusAdministrationAsyncClient client = builder +// .credential(fullyQualifiedDomainName, tokenCredential) +// .buildAsyncClient(); +// +// StepVerifier.create(client.getNamespaceProperties()) +// .assertNext(properties -> { +// assertNotNull(properties); +// +// if (!interceptorManager.isPlaybackMode()) { +// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); +// assertEquals(split[0], properties.getName()); +// } +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// /** +// * Test to connect to the service bus with an azure sas credential. +// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below +// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. +// */ +// @Test +// void azureSasCredentialsTest() { +// // Arrange +// assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); +// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); +// +// assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), +// "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); +// +// String connectionString = getConnectionString(true); +// Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); +// Matcher matcher = sasPattern.matcher(connectionString); +// assertTrue(matcher.find(), "Couldn't find SAS from connection string"); +// +// ServiceBusAdministrationAsyncClient client = new ServiceBusAdministrationClientBuilder() +// .endpoint("https://" + fullyQualifiedDomainName) +// .credential(new AzureSasCredential(matcher.group(1))) +// .buildAsyncClient(); +// +// // Act & Assert +// StepVerifier.create(client.getNamespacePropertiesWithResponse()) +// .assertNext(response -> { +// final NamespaceProperties np = response.getValue(); +// assertNotNull(np.getName()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// //region Create tests +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createQueue(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("test", 10); +// final CreateQueueOptions expected = new CreateQueueOptions() +// .setMaxSizeInMegabytes(1024) +// .setMaxDeliveryCount(7) +// .setLockDuration(Duration.ofSeconds(45)) +// .setSessionRequired(true) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing"); +// +// // Act & Assert +// StepVerifier.create(client.createQueue(queueName, expected)) +// .assertNext(actual -> { +// assertEquals(queueName, actual.getName()); +// +// assertEquals(expected.getLockDuration(), actual.getLockDuration()); +// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); +// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// +// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); +// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); +// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); +// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); +// assertEquals(0, runtimeProperties.getTotalMessageCount()); +// assertEquals(0, runtimeProperties.getSizeInBytes()); +// assertNotNull(runtimeProperties.getCreatedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createQueueExistingName(HttpClient httpClient) { +// // Arrange +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); +// final CreateQueueOptions options = new CreateQueueOptions(); +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // Act & Assert +// StepVerifier.create(client.createQueue(queueName, options)) +// .expectError(ResourceExistsException.class) +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createQueueWithForwarding(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("test", 10); +// final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); +// final CreateQueueOptions expected = new CreateQueueOptions() +// .setForwardTo(forwardToEntityName) +// .setForwardDeadLetteredMessagesTo(forwardToEntityName); +// +// // Act & Assert +// StepVerifier.create(client.createQueue(queueName, expected)) +// .assertNext(actual -> { +// assertEquals(queueName, actual.getName()); +// +// // The URLs will be fake in playback mode. +// if (!interceptorManager.isPlaybackMode()) { +// assertEquals(expected.getForwardTo(), actual.getForwardTo()); +// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); +// } +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); +// assertNotNull(runtimeProperties.getCreatedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createQueueAuthorizationRules(HttpClient httpClient) { +// // Arrange +// final String keyName = "test-rule"; +// final List accessRights = Collections.singletonList(AccessRights.SEND); +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("test", 10); +// final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() +// ? new SharedAccessAuthorizationRule(keyName, "REDACTED", +// "REDACTED", accessRights) +// : new SharedAccessAuthorizationRule(keyName, accessRights); +// +// final CreateQueueOptions expected = new CreateQueueOptions() +// .setMaxSizeInMegabytes(1024) +// .setMaxDeliveryCount(7) +// .setLockDuration(Duration.ofSeconds(45)) +// .setSessionRequired(true) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing"); +// +// expected.getAuthorizationRules().add(rule); +// +// // Act & Assert +// StepVerifier.create(client.createQueue(queueName, expected)) +// .assertNext(actual -> { +// assertEquals(queueName, actual.getName()); +// +// assertEquals(expected.getLockDuration(), actual.getLockDuration()); +// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); +// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// +// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); +// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); +// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); +// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); +// assertEquals(0, runtimeProperties.getTotalMessageCount()); +// assertEquals(0, runtimeProperties.getSizeInBytes()); +// assertNotNull(runtimeProperties.getCreatedAt()); +// +// assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createRule(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// final String ruleName = testResourceNamer.randomName("rule", 10); +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); +// final CreateRuleOptions options = new CreateRuleOptions() +// .setAction(action) +// .setFilter(new FalseRuleFilter()); +// +// // Act & Assert +// StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName, options)) +// .assertNext(contents -> { +// +// assertNotNull(contents); +// assertEquals(ruleName, contents.getName()); +// +// assertNotNull(contents.getAction()); +// assertTrue(contents.getAction() instanceof SqlRuleAction); +// assertEquals(action.getSqlExpression(), ((SqlRuleAction) contents.getAction()).getSqlExpression()); +// +// assertNotNull(contents.getFilter()); +// assertTrue(contents.getFilter() instanceof FalseRuleFilter); +// +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createRuleDefaults(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// final String ruleName = testResourceNamer.randomName("rule", 10); +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName)) +// .assertNext(contents -> { +// assertEquals(ruleName, contents.getName()); +// assertTrue(contents.getFilter() instanceof TrueRuleFilter); +// assertTrue(contents.getAction() instanceof EmptyRuleAction); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createRuleResponse(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// final String ruleName = testResourceNamer.randomName("rule", 10); +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); +// filter.getParameters().put("@MyParameter", "My-Parameter-Value"); +// +// final CreateRuleOptions options = new CreateRuleOptions() +// .setAction(new EmptyRuleAction()) +// .setFilter(filter); +// +// // Act & Assert +// StepVerifier.create(client.createRuleWithResponse(topicName, subscriptionName, ruleName, options)) +// .assertNext(response -> { +// assertEquals(201, response.getStatusCode()); +// +// final RuleProperties contents = response.getValue(); +// +// assertNotNull(contents); +// assertEquals(ruleName, contents.getName()); +// +// assertNotNull(contents.getFilter()); +// assertTrue(contents.getFilter() instanceof SqlRuleFilter); +// +// final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); +// assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); +// +// assertNotNull(contents.getAction()); +// assertTrue(contents.getAction() instanceof EmptyRuleAction); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createSubscription(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 0); +// final String subscriptionName = testResourceNamer.randomName("sub", 10); +// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() +// .setMaxDeliveryCount(7) +// .setLockDuration(Duration.ofSeconds(45)) +// .setUserMetadata("some-metadata-for-testing-subscriptions"); +// +// // Act & Assert +// StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) +// .assertNext(actual -> { +// assertEquals(topicName, actual.getTopicName()); +// assertEquals(subscriptionName, actual.getSubscriptionName()); +// +// assertEquals(expected.getLockDuration(), actual.getLockDuration()); +// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// +// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); +// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createSubscriptionWithRule(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 0); +// final String subscriptionName = testResourceNamer.randomName("sub", 10); +// final CreateSubscriptionOptions subscriptionOptions = new CreateSubscriptionOptions() +// .setMaxDeliveryCount(7) +// .setLockDuration(Duration.ofSeconds(45)) +// .setUserMetadata("some-metadata-for-testing-subscriptions"); +// +// final String ruleName = testResourceNamer.randomName("rule", 10); +// final CreateRuleOptions ruleOptions = new CreateRuleOptions(new SqlRuleFilter("color='red'")); +// // Act & Assert +// StepVerifier.create(client.createSubscription(topicName, subscriptionName, ruleName, subscriptionOptions, ruleOptions) +// .flatMap(s -> client.getRule(topicName, subscriptionName, ruleName))) +// .assertNext(rule -> { +// assertEquals(ruleName, rule.getName()); +// assertTrue(rule.getFilter() instanceof SqlRuleFilter); +// assertEquals("color='red'", ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createSubscriptionExistingName(HttpClient httpClient) { +// // Arrange +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = getSessionSubscriptionBaseName(); +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // Act & Assert +// StepVerifier.create(client.createSubscription(topicName, subscriptionName)) +// .expectError(ResourceExistsException.class) +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createSubscriptionWithForwarding(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 3); +// final String subscriptionName = testResourceNamer.randomName("sub", 50); +// final String forwardToTopic = getEntityName(getTopicBaseName(), 4); +// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() +// .setForwardTo(forwardToTopic) +// .setForwardDeadLetteredMessagesTo(forwardToTopic); +// +// // Act & Assert +// StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) +// .assertNext(actual -> { +// assertEquals(topicName, actual.getTopicName()); +// assertEquals(subscriptionName, actual.getSubscriptionName()); +// +// // URLs are redacted so they will not match. +// if (!interceptorManager.isPlaybackMode()) { +// assertEquals(expected.getForwardTo(), actual.getForwardTo()); +// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); +// } +// }) +// .expectComplete() +// .verify(TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createTopicWithResponse(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("test", 10); +// final CreateTopicOptions expected = new CreateTopicOptions() +// .setMaxSizeInMegabytes(2048L) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing-topic"); +// +// // Act & Assert +// StepVerifier.create(client.createTopicWithResponse(topicName, expected)) +// .assertNext(response -> { +// assertEquals(201, response.getStatusCode()); +// +// // Assert values on a topic. +// final TopicProperties actual = response.getValue(); +// +// assertEquals(topicName, actual.getName()); +// +// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// +// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); +// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); +// +// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); +// assertEquals(0, runtimeProperties.getSubscriptionCount()); +// assertEquals(0, runtimeProperties.getSizeInBytes()); +// assertNotNull(runtimeProperties.getCreatedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void createTopicExistingName(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 3); +// final CreateTopicOptions expected = new CreateTopicOptions() +// .setMaxSizeInMegabytes(2048L) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing-topic"); +// +// // Act & Assert +// StepVerifier.create(client.createTopicWithResponse(topicName, expected)) +// .expectError(ResourceExistsException.class) +// .verify(DEFAULT_TIMEOUT); +// } +// +// //endregion +// +// //region Delete tests +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteQueue(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("sub", 10); +// +// client.createQueue(queueName) +// .onErrorResume(ResourceExistsException.class, e -> Mono.empty()) +// .block(TIMEOUT); +// +// // Act & Assert +// StepVerifier.create(client.deleteQueue(queueName)) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteQueueDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("queue", 10); +// +// // Act & Assert +// StepVerifier.create(client.deleteQueue(queueName)) +// .expectError(ResourceNotFoundException.class) +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteRule(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String ruleName = testResourceNamer.randomName("rule-", 11); +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); +// +// // Act & Assert +// StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteRuleDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String ruleName = testResourceNamer.randomName("rule-", 11); +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) +// .expectError(ResourceNotFoundException.class) +// .verify(TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteSubscription(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("topic", 10); +// final String subscriptionName = testResourceNamer.randomName("sub", 7); +// +// client.createTopic(topicName).block(TIMEOUT); +// client.createSubscription(topicName, subscriptionName).block(TIMEOUT); +// +// // Act & Assert +// StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteSubscriptionDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("topic", 10); +// final String subscriptionName = testResourceNamer.randomName("sub", 7); +// +// // The topic exists but the subscription does not. +// client.createTopic(topicName).block(TIMEOUT); +// +// // Act & Assert +// StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) +// .expectError(ResourceNotFoundException.class) +// .verify(TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteTopic(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("topic", 10); +// +// client.createTopic(topicName).block(TIMEOUT); +// +// // Act & Assert +// StepVerifier.create(client.deleteTopic(topicName)) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void deleteTopicDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("topic", 10); +// +// // Act & Assert +// StepVerifier.create(client.deleteTopic(topicName)) +// .expectError(ResourceNotFoundException.class) +// .verify(TIMEOUT); +// } +// +// //endregion +// +// //region Get and exists tests +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getQueue(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// // Act & Assert +// StepVerifier.create(client.getQueue(queueName)) +// .assertNext(queueDescription -> { +// assertEquals(queueName, queueDescription.getName()); +// +// assertFalse(queueDescription.isPartitioningEnabled()); +// assertFalse(queueDescription.isSessionRequired()); +// assertNotNull(queueDescription.getLockDuration()); +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueDescription); +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getNamespace(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // Act & Assert +// StepVerifier.create(client.getNamespaceProperties()) +// .assertNext(properties -> { +// assertEquals(NamespaceType.MESSAGING, properties.getNamespaceType()); +// if (!interceptorManager.isPlaybackMode()) { +// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); +// assertEquals(split[0], properties.getName()); +// } +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getQueueDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("exist", 10); +// +// // Act & Assert +// StepVerifier.create(client.getQueue(queueName)) +// .expectError(ResourceNotFoundException.class) +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getQueueExists(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); +// +// // Act & Assert +// StepVerifier.create(client.getQueueExists(queueName)) +// .expectNext(true) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getQueueExistsFalse(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = testResourceNamer.randomName("exist", 10); +// +// // Act & Assert +// StepVerifier.create(client.getQueueExists(queueName)) +// .expectNext(false) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getQueueRuntimeProperties(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// // Act & Assert +// StepVerifier.create(client.getQueueRuntimeProperties(queueName)) +// .assertNext(RuntimeProperties -> { +// assertEquals(queueName, RuntimeProperties.getName()); +// +// assertNotNull(RuntimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); +// assertNotNull(RuntimeProperties.getAccessedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getRule(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // There is a single default rule created. +// final String ruleName = "$Default"; +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) +// .assertNext(response -> { +// assertEquals(200, response.getStatusCode()); +// +// final RuleProperties contents = response.getValue(); +// +// assertNotNull(contents); +// assertEquals(ruleName, contents.getName()); +// assertNotNull(contents.getFilter()); +// assertTrue(contents.getFilter() instanceof TrueRuleFilter); +// +// assertNotNull(contents.getAction()); +// assertTrue(contents.getAction() instanceof EmptyRuleAction); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getRuleDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// final String ruleName = "does-not-exist-rule"; +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) +// .expectError(ResourceNotFoundException.class) +// .verify(TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getSubscription(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = getSessionSubscriptionBaseName(); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// // Act & Assert +// StepVerifier.create(client.getSubscription(topicName, subscriptionName)) +// .assertNext(description -> { +// assertEquals(topicName, description.getTopicName()); +// assertEquals(subscriptionName, description.getSubscriptionName()); +// +// assertTrue(description.isSessionRequired()); +// assertNotNull(description.getLockDuration()); +// +// final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(description); +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getSubscriptionDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = "subscription-session-not-exist"; +// +// // Act & Assert +// StepVerifier.create(client.getSubscription(topicName, subscriptionName)) +// .expectError(ResourceNotFoundException.class) +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getSubscriptionExists(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = getSessionSubscriptionBaseName(); +// +// // Act & Assert +// StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) +// .expectNext(true) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getSubscriptionExistsFalse(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = "subscription-session-not-exist"; +// +// // Act & Assert +// StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) +// .expectNext(false) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getSubscriptionRuntimeProperties(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = getSessionSubscriptionBaseName(); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// // Act & Assert +// StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) +// .assertNext(description -> { +// assertEquals(topicName, description.getTopicName()); +// assertEquals(subscriptionName, description.getSubscriptionName()); +// +// assertTrue(description.getTotalMessageCount() >= 0); +// assertEquals(0, description.getActiveMessageCount()); +// assertEquals(0, description.getTransferDeadLetterMessageCount()); +// assertEquals(0, description.getTransferMessageCount()); +// assertTrue(description.getDeadLetterMessageCount() >= 0); +// +// assertNotNull(description.getCreatedAt()); +// assertTrue(nowUtc.isAfter(description.getCreatedAt())); +// assertNotNull(description.getAccessedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getTopic(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// // Act & Assert +// StepVerifier.create(client.getTopic(topicName)) +// .assertNext(topicDescription -> { +// assertEquals(topicName, topicDescription.getName()); +// +// assertTrue(topicDescription.isBatchedOperationsEnabled()); +// assertFalse(topicDescription.isDuplicateDetectionRequired()); +// assertNotNull(topicDescription.getDuplicateDetectionHistoryTimeWindow()); +// assertNotNull(topicDescription.getDefaultMessageTimeToLive()); +// assertFalse(topicDescription.isPartitioningEnabled()); +// +// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicDescription); +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getTopicDoesNotExist(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("exists", 10); +// +// // Act & Assert +// StepVerifier.create(client.getTopic(topicName)) +// .consumeErrorWith(error -> { +// assertTrue(error instanceof ResourceNotFoundException); +// +// final ResourceNotFoundException notFoundError = (ResourceNotFoundException) error; +// final HttpResponse response = notFoundError.getResponse(); +// +// assertNotNull(response); +// assertEquals(200, response.getStatusCode()); +// StepVerifier.create(response.getBody()) +// .verifyComplete(); +// }) +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getTopicExists(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// +// // Act & Assert +// StepVerifier.create(client.getTopicExists(topicName)) +// .expectNext(true) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getTopicExistsFalse(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = testResourceNamer.randomName("exists", 10); +// +// // Act & Assert +// StepVerifier.create(client.getTopicExists(topicName)) +// .expectNext(false) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getTopicRuntimeProperties(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// // Act & Assert +// StepVerifier.create(client.getTopicRuntimeProperties(topicName)) +// .assertNext(RuntimeProperties -> { +// assertEquals(topicName, RuntimeProperties.getName()); +// +// assertTrue(RuntimeProperties.getSubscriptionCount() > 1); +// +// assertNotNull(RuntimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); +// assertNotNull(RuntimeProperties.getAccessedAt()); +// assertTrue(nowUtc.isAfter(RuntimeProperties.getAccessedAt())); +// assertEquals(0, RuntimeProperties.getScheduledMessageCount()); +// +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { +// // Arrange +// final String connectionString = interceptorManager.isPlaybackMode() +// ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" +// : TestUtils.getConnectionString(false); +// +// final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", +// "SharedAccessKey=fake-key-"); +// +// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() +// .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) +// .connectionString(connectionStringUpdated); +// +// if (interceptorManager.isPlaybackMode()) { +// builder.httpClient(interceptorManager.getPlaybackClient()); +// } else if (interceptorManager.isLiveMode()) { +// builder.httpClient(httpClient); +// } else { +// builder.httpClient(httpClient) +// .addPolicy(interceptorManager.getRecordPolicy()); +// } +// +// final ServiceBusAdministrationAsyncClient client = builder.buildAsyncClient(); +// +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); +// +// // Act & Assert +// StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) +// .expectErrorMatches(throwable -> throwable instanceof ClientAuthenticationException) +// .verify(DEFAULT_TIMEOUT); +// } +// +// //endregion +// +// //region List tests +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void listRules(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // There is a single default rule created. +// final String ruleName = "$Default"; +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// StepVerifier.create(client.listRules(topicName, subscriptionName)) +// .assertNext(response -> { +// assertEquals(ruleName, response.getName()); +// assertNotNull(response.getFilter()); +// assertTrue(response.getFilter() instanceof TrueRuleFilter); +// +// assertNotNull(response.getAction()); +// assertTrue(response.getAction() instanceof EmptyRuleAction); +// }) +// .thenCancel() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void listQueues(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // Act & Assert +// StepVerifier.create(client.listQueues()) +// .assertNext(queueDescription -> { +// assertNotNull(queueDescription.getName()); +// assertTrue(queueDescription.isBatchedOperationsEnabled()); +// assertFalse(queueDescription.isDuplicateDetectionRequired()); +// assertFalse(queueDescription.isPartitioningEnabled()); +// }) +// .expectNextCount(9) +// .thenCancel() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void listSubscriptions(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// +// // Act & Assert +// StepVerifier.create(client.listSubscriptions(topicName)) +// .assertNext(subscription -> { +// assertEquals(topicName, subscription.getTopicName()); +// assertNotNull(subscription.getSubscriptionName()); +// }) +// .expectNextCount(1) +// .thenCancel() +// .verify(DEFAULT_TIMEOUT); +// } +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void listTopics(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// // Act & Assert +// StepVerifier.create(client.listTopics()) +// .assertNext(topics -> { +// assertNotNull(topics.getName()); +// assertTrue(topics.isBatchedOperationsEnabled()); +// assertFalse(topics.isPartitioningEnabled()); +// }) +// .expectNextCount(2) +// .thenCancel() +// .verify(DEFAULT_TIMEOUT); +// } +// +// //endregion +// +// @ParameterizedTest +// @MethodSource("createHttpClients") +// void updateRuleResponse(HttpClient httpClient) { +// // Arrange +// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); +// +// final String ruleName = testResourceNamer.randomName("rule", 15); +// final String topicName = getEntityName(getTopicBaseName(), 12); +// final String subscriptionName = getSubscriptionBaseName(); +// final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); +// final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); +// +// final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); +// assertNotNull(existingRule); +// +// existingRule.setAction(expectedAction).setFilter(expectedFilter); +// +// // Act & Assert +// StepVerifier.create(client.updateRule(topicName, subscriptionName, existingRule)) +// .assertNext(contents -> { +// assertNotNull(contents); +// assertEquals(ruleName, contents.getName()); +// +// assertTrue(contents.getFilter() instanceof SqlRuleFilter); +// assertEquals(expectedFilter.getSqlExpression(), +// ((SqlRuleFilter) contents.getFilter()).getSqlExpression()); +// +// assertTrue(contents.getAction() instanceof SqlRuleAction); +// assertEquals(expectedAction.getSqlExpression(), +// ((SqlRuleAction) contents.getAction()).getSqlExpression()); +// }) +// .expectComplete() +// .verify(DEFAULT_TIMEOUT); +// } +// +// private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { +// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() +// .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) +// .credential(getTestTokenCredential(interceptorManager)); +// +// if (interceptorManager.isPlaybackMode()) { +// builder.httpClient(interceptorManager.getPlaybackClient()); +// } else if (interceptorManager.isLiveMode()) { +// builder.httpClient(httpClient); +// } else { +// builder.httpClient(httpClient).addPolicy(interceptorManager.getRecordPolicy()); +// } +// +// if (!interceptorManager.isLiveMode()) { +// interceptorManager.addSanitizers(TEST_PROXY_SANITIZERS); +// interceptorManager.addMatchers(TEST_PROXY_REQUEST_MATCHERS); +// } +// +// return builder.buildAsyncClient(); +// } +// +// /** +// * Retrieve the appropriate TokenCredential based on the test mode. +// * +// * @param interceptorManager the interceptor manager +// * @return The appropriate token credential +// */ +// private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { +// if (interceptorManager.isLiveMode()) { +// return new AzurePowerShellCredentialBuilder().build(); +// } else if (interceptorManager.isRecordMode()) { +// return new DefaultAzureCredentialBuilder().build(); +// } else { +// return new MockTokenCredential(); +// } +// } +//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index fd6dfb9548f7..65a26fcbe3c1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -3,73 +3,73 @@ package com.azure.messaging.servicebus.administration; -import com.azure.core.credential.AzureSasCredential; +//import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; -import com.azure.core.exception.ClientAuthenticationException; -import com.azure.core.exception.ResourceExistsException; -import com.azure.core.exception.ResourceNotFoundException; +//import com.azure.core.exception.ClientAuthenticationException; +//import com.azure.core.exception.ResourceExistsException; +//import com.azure.core.exception.ResourceNotFoundException; import com.azure.core.http.policy.FixedDelayOptions; import com.azure.core.http.policy.HttpLogDetailLevel; import com.azure.core.http.policy.HttpLogOptions; import com.azure.core.http.policy.RetryOptions; -import com.azure.core.http.rest.PagedIterable; -import com.azure.core.http.rest.Response; +//import com.azure.core.http.rest.PagedIterable; +//import com.azure.core.http.rest.Response; import com.azure.core.test.InterceptorManager; import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.utils.MockTokenCredential; -import com.azure.core.util.Context; +//import com.azure.core.util.Context; import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; -import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; -import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; -import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; -import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; -import com.azure.messaging.servicebus.administration.models.EntityStatus; -import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; -import com.azure.messaging.servicebus.administration.models.NamespaceProperties; -import com.azure.messaging.servicebus.administration.models.NamespaceType; +//import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; +//import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; +//import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; +//import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; +//import com.azure.messaging.servicebus.administration.models.EntityStatus; +//import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; +//import com.azure.messaging.servicebus.administration.models.NamespaceProperties; +//import com.azure.messaging.servicebus.administration.models.NamespaceType; import com.azure.messaging.servicebus.administration.models.QueueProperties; import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; -import com.azure.messaging.servicebus.administration.models.RuleProperties; +//import com.azure.messaging.servicebus.administration.models.RuleProperties; import com.azure.messaging.servicebus.administration.models.SharedAccessAuthorizationRule; -import com.azure.messaging.servicebus.administration.models.SqlRuleAction; -import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; -import com.azure.messaging.servicebus.administration.models.SubscriptionProperties; -import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; -import com.azure.messaging.servicebus.administration.models.TopicProperties; -import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; -import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +//import com.azure.messaging.servicebus.administration.models.SqlRuleAction; +//import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; +//import com.azure.messaging.servicebus.administration.models.SubscriptionProperties; +//import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; +//import com.azure.messaging.servicebus.administration.models.TopicProperties; +//import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; +//import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import java.time.Clock; +//import java.time.Clock; import java.time.Duration; -import java.time.OffsetDateTime; +//import java.time.OffsetDateTime; import java.util.Collections; import java.util.List; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +//import java.util.Optional; +//import java.util.regex.Matcher; +//import java.util.regex.Pattern; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; -import static com.azure.messaging.servicebus.TestUtils.getConnectionString; +//import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getQueueBaseName; -import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; -import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; -import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; +//import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; +//import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; +//import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; +//import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; +//import static org.junit.jupiter.api.Assertions.assertSame; +//import static org.junit.jupiter.api.Assertions.assertThrows; +//import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Tests {@link ServiceBusAdministrationClient}. @@ -79,66 +79,66 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTestBase { private static final Duration TIMEOUT = Duration.ofSeconds(20); - /** - * Test to connect to the service bus with an azure identity TokenCredential. - * com.azure.identity.ClientSecretCredential is used in this test. - * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below - * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. - */ - @Test - void azureIdentityCredentials() { - // Arrange - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); - - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); - - if (interceptorManager.isPlaybackMode()) { - builder.httpClient(interceptorManager.getPlaybackClient()); - } else if (interceptorManager.isRecordMode()) { - builder.addPolicy(interceptorManager.getRecordPolicy()); - } - - final ServiceBusAdministrationClient client = builder - .credential(fullyQualifiedDomainName, tokenCredential) - .buildClient(); - - // Act - NamespaceProperties properties = client.getNamespaceProperties(); - - // Assert - assertNotNull(properties); - - if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); - assertEquals(split[0], properties.getName()); - } - } - - /** - * Test to connect to the service bus with an azure sas credential. - * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below - * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. - */ - @Test - void azureSasCredentialsTest() { - assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - - String connectionString = getConnectionString(true); - Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); - Matcher matcher = sasPattern.matcher(connectionString); - assertTrue(matcher.find(), "Couldn't find SAS from connection string"); - ServiceBusAdministrationClient client = new ServiceBusAdministrationClientBuilder() - .endpoint("https://" + fullyQualifiedDomainName) - .credential(new AzureSasCredential(matcher.group(1))) - .buildClient(); - NamespaceProperties np = client.getNamespaceProperties(); - assertNotNull(np.getName()); - } +// /** +// * Test to connect to the service bus with an azure identity TokenCredential. +// * com.azure.identity.ClientSecretCredential is used in this test. +// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below +// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. +// */ +// @Test +// void azureIdentityCredentials() { +// // Arrange +// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); +// final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); +// +// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); +// +// if (interceptorManager.isPlaybackMode()) { +// builder.httpClient(interceptorManager.getPlaybackClient()); +// } else if (interceptorManager.isRecordMode()) { +// builder.addPolicy(interceptorManager.getRecordPolicy()); +// } +// +// final ServiceBusAdministrationClient client = builder +// .credential(fullyQualifiedDomainName, tokenCredential) +// .buildClient(); +// +// // Act +// NamespaceProperties properties = client.getNamespaceProperties(); +// +// // Assert +// assertNotNull(properties); +// +// if (!interceptorManager.isPlaybackMode()) { +// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); +// assertEquals(split[0], properties.getName()); +// } +// } +// +// /** +// * Test to connect to the service bus with an azure sas credential. +// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below +// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. +// */ +// @Test +// void azureSasCredentialsTest() { +// assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); +// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); +// +// assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), +// "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); +// +// String connectionString = getConnectionString(true); +// Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); +// Matcher matcher = sasPattern.matcher(connectionString); +// assertTrue(matcher.find(), "Couldn't find SAS from connection string"); +// ServiceBusAdministrationClient client = new ServiceBusAdministrationClientBuilder() +// .endpoint("https://" + fullyQualifiedDomainName) +// .credential(new AzureSasCredential(matcher.group(1))) +// .buildClient(); +// NamespaceProperties np = client.getNamespaceProperties(); +// assertNotNull(np.getName()); +// } //region Create tests @@ -193,742 +193,743 @@ void createQueue() { assertNotNull(runtimeProperties.getCreatedAt()); } - @Test - void createQueueWithForwarding() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String queueName = testResourceNamer.randomName("test", 10); - final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); - final CreateQueueOptions expected = new CreateQueueOptions() - .setForwardTo(forwardToEntityName) - .setForwardDeadLetteredMessagesTo(forwardToEntityName); - - // Act - final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); - final QueueProperties actual = response.getValue(); - - // Assert - assertEquals(queueName, actual.getName()); - - // The URLs will be fake in playback mode. - if (!interceptorManager.isPlaybackMode()) { - assertEquals(expected.getForwardTo(), actual.getForwardTo()); - assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); - } - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); - assertNotNull(runtimeProperties.getCreatedAt()); - } - - @Test - void createQueueAuthorizationRules() { - // Arrange - final String keyName = "test-rule"; - final List accessRights = Collections.singletonList(AccessRights.SEND); - final ServiceBusAdministrationClient client = getClient(); - final String queueName = testResourceNamer.randomName("test", 10); - final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() - ? new SharedAccessAuthorizationRule(keyName, "REDACTED", - "REDACTED", accessRights) - : new SharedAccessAuthorizationRule(keyName, accessRights); - - final CreateQueueOptions expected = new CreateQueueOptions() - .setMaxSizeInMegabytes(1024) - .setMaxDeliveryCount(7) - .setLockDuration(Duration.ofSeconds(45)) - .setSessionRequired(true) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing"); - - expected.getAuthorizationRules().add(rule); - - // Act - final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); - final QueueProperties actual = response.getValue(); - - // Assert - assertEquals(queueName, actual.getName()); - - assertEquals(expected.getLockDuration(), actual.getLockDuration()); - assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); - assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - - assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); - assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); - assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); - assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); - assertEquals(0, runtimeProperties.getTotalMessageCount()); - assertEquals(0, runtimeProperties.getSizeInBytes()); - assertNotNull(runtimeProperties.getCreatedAt()); - - assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); - } - - @Test - void createTopicWithResponse() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = testResourceNamer.randomName("test", 10); - final CreateTopicOptions expected = new CreateTopicOptions() - .setMaxSizeInMegabytes(2048L) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing-topic"); - - final Response response = client.createTopicWithResponse(topicName, expected, null); - assertEquals(201, response.getStatusCode()); - - final TopicProperties actual = response.getValue(); - - assertEquals(topicName, actual.getName()); - assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); - assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); - - final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); - assertEquals(0, runtimeProperties.getSubscriptionCount()); - assertEquals(0, runtimeProperties.getSizeInBytes()); - assertNotNull(runtimeProperties.getCreatedAt()); - } - - @Test - void createTopicExistingName() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 3); - final CreateTopicOptions expected = new CreateTopicOptions() - .setMaxSizeInMegabytes(2048L) - .setDuplicateDetectionRequired(true) - .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) - .setUserMetadata("some-metadata-for-testing-topic"); - - // Act & Assert - assertThrows(ResourceExistsException.class, - () -> client.createTopicWithResponse(topicName, expected, Context.NONE)); - } - - @Test - void createSubscription() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String forwardToTopic = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); - final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() - .setMaxDeliveryCount(7) - .setLockDuration(Duration.ofSeconds(45)) - .setUserMetadata("some-metadata-for-testing-subscriptions") - .setForwardTo(forwardToTopic) - .setForwardDeadLetteredMessagesTo(forwardToTopic); - - final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); - assertEquals(topicName, actual.getTopicName()); - assertEquals(subscriptionName, actual.getSubscriptionName()); - - assertEquals(expected.getLockDuration(), actual.getLockDuration()); - assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); - assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); - - assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); - assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); - - // URLs are redacted so they will not match. - if (!interceptorManager.isPlaybackMode()) { - assertEquals(expected.getForwardTo(), actual.getForwardTo()); - assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); - } - } - - @Test - void createRule() { - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = testResourceNamer.randomName("rule", 5); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); - final CreateRuleOptions options = new CreateRuleOptions() - .setAction(action) - .setFilter(new FalseRuleFilter()); - - final RuleProperties actual = client.createRule(topicName, ruleName, subscriptionName, options); - assertNotNull(actual); - assertEquals(ruleName, actual.getName()); - assertNotNull(actual.getAction()); - - assertTrue(actual.getAction() instanceof SqlRuleAction); - assertEquals(action.getSqlExpression(), ((SqlRuleAction) actual.getAction()).getSqlExpression()); - - assertNotNull(actual.getFilter()); - assertTrue(actual.getFilter() instanceof FalseRuleFilter); - } - - @Test - void createRuleDefaults() { - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = testResourceNamer.randomName("rule", 7); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - - final RuleProperties rule = client.createRule(topicName, subscriptionName, ruleName); - assertEquals(ruleName, rule.getName()); - assertTrue(rule.getFilter() instanceof TrueRuleFilter); - assertTrue(rule.getAction() instanceof EmptyRuleAction); - } - - @Test - void createRuleResponse() { - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = testResourceNamer.randomName("rule", 10); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - - final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); - filter.getParameters().put("@MyParameter", "My-Parameter-Value"); - - final CreateRuleOptions options = new CreateRuleOptions() - .setAction(new EmptyRuleAction()) - .setFilter(filter); - - final Response response = client.createRuleWithResponse(topicName, subscriptionName, - ruleName, options, null); - assertEquals(201, response.getStatusCode()); - - final RuleProperties contents = response.getValue(); - assertNotNull(contents); - assertEquals(ruleName, contents.getName()); - - assertNotNull(contents.getFilter()); - assertTrue(contents.getFilter() instanceof SqlRuleFilter); - - final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); - assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); - - assertNotNull(contents.getAction()); - assertTrue(contents.getAction() instanceof EmptyRuleAction); - } - - @Test - void createQueueExistingName() { - final String queueName = getEntityName(getQueueBaseName(), 5); - final CreateQueueOptions options = new CreateQueueOptions(); - final ServiceBusAdministrationClient client = getClient(); - - ResourceExistsException exception = assertThrows(ResourceExistsException.class, - () -> client.createQueue(queueName, options), - "Queue exists exception not thrown when creating a queue with existing name"); - } - - @Test - void createSubscriptionExistingName() { - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - final ServiceBusAdministrationClient client = getClient(); - - ResourceExistsException exception = assertThrows(ResourceExistsException.class, - () -> client.createSubscription(topicName, subscriptionName), - "Queue exists exception not thrown when creating a queue with existing name"); - } - - @Test - void createSubscriptionWithForwarding() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 3); - final String subscriptionName = testResourceNamer.randomName("sub", 50); - final String forwardToTopic = getEntityName(getTopicBaseName(), 4); - final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() - .setForwardTo(forwardToTopic) - .setForwardDeadLetteredMessagesTo(forwardToTopic); - - // Act - final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); - - // Assert - assertEquals(topicName, actual.getTopicName()); - assertEquals(subscriptionName, actual.getSubscriptionName()); - - // URLs are redacted so they will not match. - if (!interceptorManager.isPlaybackMode()) { - assertEquals(expected.getForwardTo(), actual.getForwardTo()); - assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); - } - } - - //endregion - - @Test - void updateRuleResponse() { - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = testResourceNamer.randomName("rule", 15); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); - final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); - - final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName); - assertNotNull(existingRule); - - existingRule.setAction(expectedAction).setFilter(expectedFilter); - - final RuleProperties rule = client.updateRule(topicName, subscriptionName, existingRule); - assertNotNull(rule); - assertEquals(ruleName, rule.getName()); - - assertTrue(rule.getFilter() instanceof SqlRuleFilter); - assertEquals(expectedFilter.getSqlExpression(), - ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); - - assertTrue(rule.getAction() instanceof SqlRuleAction); - assertEquals(expectedAction.getSqlExpression(), - ((SqlRuleAction) rule.getAction()).getSqlExpression()); - } - - //region Get and exists tests - - @Test - void getNamespace() { - final ServiceBusAdministrationClient client = getClient(); - - final NamespaceProperties namespaceProperties = client.getNamespaceProperties(); - assertEquals(NamespaceType.MESSAGING, namespaceProperties.getNamespaceType()); - if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); - assertEquals(split[0], namespaceProperties.getName()); - } - } - - @Test - void getQueue() { - final ServiceBusAdministrationClient client = getClient(); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - final QueueProperties queueProperties = client.getQueue(queueName); - assertEquals(queueName, queueProperties.getName()); - - assertFalse(queueProperties.isPartitioningEnabled()); - assertFalse(queueProperties.isSessionRequired()); - assertNotNull(queueProperties.getLockDuration()); - - final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueProperties); - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - } - - @Test - void getQueueDoesNotExist() { - final ServiceBusAdministrationClient client = getClient(); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); - - assertThrows(ResourceNotFoundException.class, () -> client.getQueue(queueName), - "Queue exists! But should not. Incorrect getQueue behavior"); - } - - @Test - void getQueueExists() { - final ServiceBusAdministrationClient client = getClient(); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); - - assertTrue(client.getQueueExists(queueName)); - } - - @Test - void getQueueExistsFalse() { - final ServiceBusAdministrationClient client = getClient(); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); - - assertFalse(client.getQueueExists(queueName)); - } - - @Test - void getQueueRuntimeProperties() { - final ServiceBusAdministrationClient client = getClient(); - final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - final QueueRuntimeProperties runtimeProperties = client.getQueueRuntimeProperties(queueName); - assertEquals(queueName, runtimeProperties.getName()); - - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - } - - @Test - void getTopic() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - final TopicProperties topicProperties = client.getTopic(topicName); - assertEquals(topicName, topicProperties.getName()); - - assertTrue(topicProperties.isBatchedOperationsEnabled()); - assertFalse(topicProperties.isDuplicateDetectionRequired()); - assertNotNull(topicProperties.getDuplicateDetectionHistoryTimeWindow()); - assertNotNull(topicProperties.getDefaultMessageTimeToLive()); - assertFalse(topicProperties.isPartitioningEnabled()); - - final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicProperties); - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - } - - @Test - void getTopicDoesNotExist() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = testResourceNamer.randomName("topic", 10); - - assertThrows(ResourceNotFoundException.class, () -> client.getTopic(topicName), - "Topic exists! But should not. Incorrect getTopic behavior"); - } - - @Test - void getTopicExists() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - - assertTrue(client.getTopicExists(topicName)); - } - - @Test - void getTopicExistsFalse() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = testResourceNamer.randomName(getTopicBaseName(), 10); - - assertFalse(client.getTopicExists(topicName)); - } - - @Test - void getTopicRuntimeProperties() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - final TopicRuntimeProperties runtimeProperties = client.getTopicRuntimeProperties(topicName); - assertEquals(topicName, runtimeProperties.getName()); - - assertTrue(runtimeProperties.getSubscriptionCount() >= 1); - - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getAccessedAt())); - assertEquals(0, runtimeProperties.getScheduledMessageCount()); - } - - @Test - void getSubscription() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - final SubscriptionProperties properties = client.getSubscription(topicName, subscriptionName); - assertEquals(topicName, properties.getTopicName()); - assertEquals(subscriptionName, properties.getSubscriptionName()); - - assertFalse(properties.isSessionRequired()); - assertNotNull(properties.getLockDuration()); - - final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(properties); - assertNotNull(runtimeProperties.getCreatedAt()); - assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); - assertNotNull(runtimeProperties.getAccessedAt()); - } - - @Test - void getSubscriptionDoesNotExist() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); - - assertThrows(ResourceNotFoundException.class, () -> client.getSubscription(topicName, subscriptionName), - "Subscription exists! But should not. Incorrect getSubscription behavior"); - } - - @Test - void getSubscriptionExists() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - - assertTrue(client.getSubscriptionExists(topicName, subscriptionName)); - } - - @Test - void getSubscriptionExistsFalse() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 1); - final String subscriptionName = "subscription-session-not-exist"; - - // Act - boolean response = client.getSubscriptionExists(topicName, subscriptionName); - - // Assert - assertFalse(response); - } - - @Test - void getSubscriptionRuntimeProperties() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); - - final SubscriptionRuntimeProperties properties = client.getSubscriptionRuntimeProperties(topicName, subscriptionName); - assertEquals(topicName, properties.getTopicName()); - assertEquals(subscriptionName, properties.getSubscriptionName()); - - assertTrue(properties.getTotalMessageCount() >= 0); - assertEquals(0, properties.getActiveMessageCount()); - assertEquals(0, properties.getTransferDeadLetterMessageCount()); - assertEquals(0, properties.getTransferMessageCount()); - assertTrue(properties.getDeadLetterMessageCount() >= 0); - - assertNotNull(properties.getCreatedAt()); - assertTrue(nowUtc.isAfter(properties.getCreatedAt())); - assertNotNull(properties.getAccessedAt()); - } - - @Test - void getSubscriptionRuntimePropertiesUnauthorizedClient() { - final String connectionString = interceptorManager.isPlaybackMode() - ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" - : TestUtils.getConnectionString(false); - - final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", - "SharedAccessKey=fake-key-"); - - final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() - .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .connectionString(connectionStringUpdated); - - if (interceptorManager.isPlaybackMode()) { - builder.httpClient(interceptorManager.getPlaybackClient()); - } else if (!interceptorManager.isLiveMode()) { - builder.addPolicy(interceptorManager.getRecordPolicy()); - } - - final ServiceBusAdministrationClient client = builder.buildClient(); - - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); - - ClientAuthenticationException exception = assertThrows(ClientAuthenticationException.class, - () -> client.getSubscriptionRuntimeProperties(topicName, subscriptionName), - "Subscription runtime properties accessible by unauthorized client! This should not be possible."); - } - - @Test - void getRule() { - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = "$Default"; - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - - final Response response = client.getRuleWithResponse(topicName, subscriptionName, ruleName, null); - assertEquals(200, response.getStatusCode()); - - final RuleProperties contents = response.getValue(); - - assertNotNull(contents); - assertEquals(ruleName, contents.getName()); - assertNotNull(contents.getFilter()); - assertTrue(contents.getFilter() instanceof SqlRuleFilter); - - assertNotNull(contents.getAction()); - assertTrue(contents.getAction() instanceof EmptyRuleAction); - } - - @Test - void getRuleDoesNotExist() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = "does-not-exist-rule"; - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - assertThrows(ResourceNotFoundException.class, - () -> client.getRuleWithResponse(topicName, subscriptionName, ruleName, Context.NONE)); - } - - //endregion - - //region Delete tests - - @Test - void deleteQueue() { - final ServiceBusAdministrationClient client = getClient(); - final String queueName = testResourceNamer.randomName("queue", 10); - - client.createQueue(queueName); - client.deleteQueue(queueName); - } - - - @Test - void deleteQueueDoesNotExist() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String queueName = testResourceNamer.randomName("queue", 10); - - // Act & Assert - assertThrows(ResourceNotFoundException.class, () -> client.deleteQueue(queueName)); - } - - @Test - void deleteRule() { - final ServiceBusAdministrationClient client = getClient(); - final String ruleName = getEntityName(getRuleBaseName(), 9); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - client.createRule(topicName, subscriptionName, ruleName); - - client.deleteRule(topicName, subscriptionName, ruleName); - } - - @Test - void deleteRuleDoesNotExist() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String ruleName = testResourceNamer.randomName("rule-", 11); - final String topicName = getEntityName(getTopicBaseName(), 13); - final String subscriptionName = getSubscriptionBaseName(); - - // Act & Assert - assertThrows(ResourceNotFoundException.class, () -> client.deleteRule(topicName, subscriptionName, ruleName)); - } - - @Test - void deleteSubscription() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); - - client.createSubscription(topicName, subscriptionName); - - client.deleteSubscription(topicName, subscriptionName); - } - - @Test - void deleteSubscriptionDoesNotExist() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String topicName = testResourceNamer.randomName("topic", 10); - final String subscriptionName = testResourceNamer.randomName("sub", 7); - - // The topic exists but the subscription does not. - client.createTopic(topicName); - - // Act & Assert - assertThrows(ResourceNotFoundException.class, () -> client.deleteSubscription(topicName, subscriptionName)); - } - - @Test - void deleteTopic() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = testResourceNamer.randomName("topic", 10); - - client.createTopic(topicName); - client.deleteTopic(topicName); - } - - @Test - void deleteTopicDoesNotExist() { - // Arrange - final ServiceBusAdministrationClient client = getClient(); - final String topicName = testResourceNamer.randomName("topic", 10); - - // Act & Assert - assertThrows(ResourceNotFoundException.class, () -> client.deleteTopic(topicName)); - } - - //endregion - - //region List tests - - @Test - void listQueues() { - final ServiceBusAdministrationClient client = getClient(); - - PagedIterable queueProperties = client.listQueues(); - queueProperties.forEach(queueDescription -> { - assertNotNull(queueDescription.getName()); - assertTrue(queueDescription.getMaxDeliveryCount() > 0); - assertSame(queueDescription.getStatus(), EntityStatus.ACTIVE); - }); - assertTrue(queueProperties.stream().findAny().isPresent()); - } - - @Test - void listTopics() { - final ServiceBusAdministrationClient client = getClient(); - - PagedIterable topics = client.listTopics(); - topics.forEach(topicProperties -> { - assertNotNull(topicProperties.getName()); - assertTrue(topicProperties.isBatchedOperationsEnabled()); - assertFalse(topicProperties.isPartitioningEnabled()); - }); - assertTrue(topics.stream().count() > 1); - } - - @Test - void listSubscriptions() { - final ServiceBusAdministrationClient client = getClient(); - final String topicName = getEntityName(getTopicBaseName(), 2); - - PagedIterable subscriptionProperties = client.listSubscriptions(topicName); - subscriptionProperties.forEach(subscription -> { - assertEquals(topicName, subscription.getTopicName()); - assertNotNull(subscription.getSubscriptionName()); - }); - assertTrue(subscriptionProperties.stream().findAny().isPresent()); - } - - @Test - void listRules() { - final ServiceBusAdministrationClient client = getClient(); - - final String ruleName = "$Default"; - final String topicName = getEntityName(getTopicBaseName(), 2); - final String subscriptionName = getSubscriptionBaseName(); - - PagedIterable ruleProperties = client.listRules(topicName, subscriptionName); - - assertTrue(ruleProperties.stream().findAny().isPresent()); - Optional ruleOptional = ruleProperties.stream() - .filter(rule1 -> rule1.getName().equals(ruleName)).findFirst(); - assertTrue(ruleOptional.isPresent()); - RuleProperties rule = ruleOptional.get(); - - assertEquals(ruleName, rule.getName()); - assertNotNull(rule.getFilter()); - assertTrue(rule.getFilter() instanceof SqlRuleFilter); - assertNotNull(rule.getAction()); - assertTrue(rule.getAction() instanceof EmptyRuleAction); - } +// @Test +// void createQueueWithForwarding() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = testResourceNamer.randomName("test", 10); +// final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); +// final CreateQueueOptions expected = new CreateQueueOptions() +// .setForwardTo(forwardToEntityName) +// .setForwardDeadLetteredMessagesTo(forwardToEntityName); +// +// // Act +// final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); +// final QueueProperties actual = response.getValue(); +// +// // Assert +// assertEquals(queueName, actual.getName()); +// +// // The URLs will be fake in playback mode. +// if (!interceptorManager.isPlaybackMode()) { +// assertEquals(expected.getForwardTo(), actual.getForwardTo()); +// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); +// } +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); +// assertNotNull(runtimeProperties.getCreatedAt()); +// } +// +// @Test +// void createQueueAuthorizationRules() { +// // Arrange +// final String keyName = "test-rule"; +// final List accessRights = Collections.singletonList(AccessRights.SEND); +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = testResourceNamer.randomName("test", 10); +// final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() +// ? new SharedAccessAuthorizationRule(keyName, "REDACTED", +// "REDACTED", accessRights) +// : new SharedAccessAuthorizationRule(keyName, accessRights); +// +// final CreateQueueOptions expected = new CreateQueueOptions() +// .setMaxSizeInMegabytes(1024) +// .setMaxDeliveryCount(7) +// .setLockDuration(Duration.ofSeconds(45)) +// .setSessionRequired(true) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing"); +// +// expected.getAuthorizationRules().add(rule); +// +// // Act +// final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); +// final QueueProperties actual = response.getValue(); +// +// // Assert +// assertEquals(queueName, actual.getName()); +// +// assertEquals(expected.getLockDuration(), actual.getLockDuration()); +// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); +// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// +// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); +// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); +// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); +// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); +// assertEquals(0, runtimeProperties.getTotalMessageCount()); +// assertEquals(0, runtimeProperties.getSizeInBytes()); +// assertNotNull(runtimeProperties.getCreatedAt()); +// +// assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); +// } +// +// @Test +// void createTopicWithResponse() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = testResourceNamer.randomName("test", 10); +// final CreateTopicOptions expected = new CreateTopicOptions() +// .setMaxSizeInMegabytes(2048L) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing-topic"); +// +// final Response response = client.createTopicWithResponse(topicName, expected, null); +// assertEquals(201, response.getStatusCode()); +// +// final TopicProperties actual = response.getValue(); +// +// assertEquals(topicName, actual.getName()); +// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); +// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); +// +// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); +// assertEquals(0, runtimeProperties.getSubscriptionCount()); +// assertEquals(0, runtimeProperties.getSizeInBytes()); +// assertNotNull(runtimeProperties.getCreatedAt()); +// } +// +// @Test +// void createTopicExistingName() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 3); +// final CreateTopicOptions expected = new CreateTopicOptions() +// .setMaxSizeInMegabytes(2048L) +// .setDuplicateDetectionRequired(true) +// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) +// .setUserMetadata("some-metadata-for-testing-topic"); +// +// // Act & Assert +// assertThrows(ResourceExistsException.class, +// () -> client.createTopicWithResponse(topicName, expected, Context.NONE)); +// } +// +// @Test +// void createSubscription() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String forwardToTopic = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); +// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() +// .setMaxDeliveryCount(7) +// .setLockDuration(Duration.ofSeconds(45)) +// .setUserMetadata("some-metadata-for-testing-subscriptions") +// .setForwardTo(forwardToTopic) +// .setForwardDeadLetteredMessagesTo(forwardToTopic); +// +// final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); +// assertEquals(topicName, actual.getTopicName()); +// assertEquals(subscriptionName, actual.getSubscriptionName()); +// +// assertEquals(expected.getLockDuration(), actual.getLockDuration()); +// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); +// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); +// +// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); +// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); +// +// // URLs are redacted so they will not match. +// if (!interceptorManager.isPlaybackMode()) { +// assertEquals(expected.getForwardTo(), actual.getForwardTo()); +// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); +// } +// } +// +// @Test +// void createRule() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = testResourceNamer.randomName("rule", 5); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); +// final CreateRuleOptions options = new CreateRuleOptions() +// .setAction(action) +// .setFilter(new FalseRuleFilter()); +// +// final RuleProperties actual = client.createRule(topicName, ruleName, subscriptionName, options); +// assertNotNull(actual); +// assertEquals(ruleName, actual.getName()); +// assertNotNull(actual.getAction()); +// +// assertTrue(actual.getAction() instanceof SqlRuleAction); +// assertEquals(action.getSqlExpression(), ((SqlRuleAction) actual.getAction()).getSqlExpression()); +// +// assertNotNull(actual.getFilter()); +// assertTrue(actual.getFilter() instanceof FalseRuleFilter); +// } +// +// @Test +// void createRuleDefaults() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = testResourceNamer.randomName("rule", 7); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// +// final RuleProperties rule = client.createRule(topicName, subscriptionName, ruleName); +// assertEquals(ruleName, rule.getName()); +// assertTrue(rule.getFilter() instanceof TrueRuleFilter); +// assertTrue(rule.getAction() instanceof EmptyRuleAction); +// } +// +// @Test +// void createRuleResponse() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = testResourceNamer.randomName("rule", 10); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// +// final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); +// filter.getParameters().put("@MyParameter", "My-Parameter-Value"); +// +// final CreateRuleOptions options = new CreateRuleOptions() +// .setAction(new EmptyRuleAction()) +// .setFilter(filter); +// +// final Response response = client.createRuleWithResponse(topicName, subscriptionName, +// ruleName, options, null); +// assertEquals(201, response.getStatusCode()); +// +// final RuleProperties contents = response.getValue(); +// assertNotNull(contents); +// assertEquals(ruleName, contents.getName()); +// +// assertNotNull(contents.getFilter()); +// assertTrue(contents.getFilter() instanceof SqlRuleFilter); +// +// final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); +// assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); +// +// assertNotNull(contents.getAction()); +// assertTrue(contents.getAction() instanceof EmptyRuleAction); +// } +// +// @Test +// void createQueueExistingName() { +// final String queueName = getEntityName(getQueueBaseName(), 5); +// final CreateQueueOptions options = new CreateQueueOptions(); +// final ServiceBusAdministrationClient client = getClient(); +// +// ResourceExistsException exception = assertThrows(ResourceExistsException.class, +// () -> client.createQueue(queueName, options), +// "Queue exists exception not thrown when creating a queue with existing name"); +// } +// +// @Test +// void createSubscriptionExistingName() { +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// final ServiceBusAdministrationClient client = getClient(); +// +// ResourceExistsException exception = assertThrows(ResourceExistsException.class, +// () -> client.createSubscription(topicName, subscriptionName), +// "Queue exists exception not thrown when creating a queue with existing name"); +// } +// +// @Test +// void createSubscriptionWithForwarding() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 3); +// final String subscriptionName = testResourceNamer.randomName("sub", 50); +// final String forwardToTopic = getEntityName(getTopicBaseName(), 4); +// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() +// .setForwardTo(forwardToTopic) +// .setForwardDeadLetteredMessagesTo(forwardToTopic); +// +// // Act +// final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); +// +// // Assert +// assertEquals(topicName, actual.getTopicName()); +// assertEquals(subscriptionName, actual.getSubscriptionName()); +// +// // URLs are redacted so they will not match. +// if (!interceptorManager.isPlaybackMode()) { +// assertEquals(expected.getForwardTo(), actual.getForwardTo()); +// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); +// } +// } +// +// //endregion +// +// @Test +// void updateRuleResponse() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = testResourceNamer.randomName("rule", 15); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); +// final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); +// +// final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName); +// assertNotNull(existingRule); +// +// existingRule.setAction(expectedAction).setFilter(expectedFilter); +// +// final RuleProperties rule = client.updateRule(topicName, subscriptionName, existingRule); +// assertNotNull(rule); +// assertEquals(ruleName, rule.getName()); +// +// assertTrue(rule.getFilter() instanceof SqlRuleFilter); +// assertEquals(expectedFilter.getSqlExpression(), +// ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); +// +// assertTrue(rule.getAction() instanceof SqlRuleAction); +// assertEquals(expectedAction.getSqlExpression(), +// ((SqlRuleAction) rule.getAction()).getSqlExpression()); +// } +// +// //region Get and exists tests +// +// @Test +// void getNamespace() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final NamespaceProperties namespaceProperties = client.getNamespaceProperties(); +// assertEquals(NamespaceType.MESSAGING, namespaceProperties.getNamespaceType()); +// if (!interceptorManager.isPlaybackMode()) { +// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); +// assertEquals(split[0], namespaceProperties.getName()); +// } +// } +// +// @Test +// void getQueue() { +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// final QueueProperties queueProperties = client.getQueue(queueName); +// assertEquals(queueName, queueProperties.getName()); +// +// assertFalse(queueProperties.isPartitioningEnabled()); +// assertFalse(queueProperties.isSessionRequired()); +// assertNotNull(queueProperties.getLockDuration()); +// +// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueProperties); +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// } +// +// @Test +// void getQueueDoesNotExist() { +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); +// +// assertThrows(ResourceNotFoundException.class, () -> client.getQueue(queueName), +// "Queue exists! But should not. Incorrect getQueue behavior"); +// } +// +// @Test +// void getQueueExists() { +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); +// +// assertTrue(client.getQueueExists(queueName)); +// } +// +// @Test +// void getQueueExistsFalse() { +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); +// +// assertFalse(client.getQueueExists(queueName)); +// } +// +// @Test +// void getQueueRuntimeProperties() { +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// final QueueRuntimeProperties runtimeProperties = client.getQueueRuntimeProperties(queueName); +// assertEquals(queueName, runtimeProperties.getName()); +// +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// } +// +// @Test +// void getTopic() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// final TopicProperties topicProperties = client.getTopic(topicName); +// assertEquals(topicName, topicProperties.getName()); +// +// assertTrue(topicProperties.isBatchedOperationsEnabled()); +// assertFalse(topicProperties.isDuplicateDetectionRequired()); +// assertNotNull(topicProperties.getDuplicateDetectionHistoryTimeWindow()); +// assertNotNull(topicProperties.getDefaultMessageTimeToLive()); +// assertFalse(topicProperties.isPartitioningEnabled()); +// +// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicProperties); +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// } +// +// @Test +// void getTopicDoesNotExist() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = testResourceNamer.randomName("topic", 10); +// +// assertThrows(ResourceNotFoundException.class, () -> client.getTopic(topicName), +// "Topic exists! But should not. Incorrect getTopic behavior"); +// } +// +// @Test +// void getTopicExists() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// +// assertTrue(client.getTopicExists(topicName)); +// } +// +// @Test +// void getTopicExistsFalse() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = testResourceNamer.randomName(getTopicBaseName(), 10); +// +// assertFalse(client.getTopicExists(topicName)); +// } +// +// @Test +// void getTopicRuntimeProperties() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// final TopicRuntimeProperties runtimeProperties = client.getTopicRuntimeProperties(topicName); +// assertEquals(topicName, runtimeProperties.getName()); +// +// assertTrue(runtimeProperties.getSubscriptionCount() >= 1); +// +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getAccessedAt())); +// assertEquals(0, runtimeProperties.getScheduledMessageCount()); +// } +// +// @Test +// void getSubscription() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// final SubscriptionProperties properties = client.getSubscription(topicName, subscriptionName); +// assertEquals(topicName, properties.getTopicName()); +// assertEquals(subscriptionName, properties.getSubscriptionName()); +// +// assertFalse(properties.isSessionRequired()); +// assertNotNull(properties.getLockDuration()); +// +// final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(properties); +// assertNotNull(runtimeProperties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); +// assertNotNull(runtimeProperties.getAccessedAt()); +// } +// +// @Test +// void getSubscriptionDoesNotExist() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); +// +// assertThrows(ResourceNotFoundException.class, () -> client.getSubscription(topicName, subscriptionName), +// "Subscription exists! But should not. Incorrect getSubscription behavior"); +// } +// +// @Test +// void getSubscriptionExists() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// +// assertTrue(client.getSubscriptionExists(topicName, subscriptionName)); +// } +// +// @Test +// void getSubscriptionExistsFalse() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 1); +// final String subscriptionName = "subscription-session-not-exist"; +// +// // Act +// boolean response = client.getSubscriptionExists(topicName, subscriptionName); +// +// // Assert +// assertFalse(response); +// } +// +// @Test +// void getSubscriptionRuntimeProperties() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); +// +// final SubscriptionRuntimeProperties properties = client.getSubscriptionRuntimeProperties(topicName, subscriptionName); +// assertEquals(topicName, properties.getTopicName()); +// assertEquals(subscriptionName, properties.getSubscriptionName()); +// +// assertTrue(properties.getTotalMessageCount() >= 0); +// assertEquals(0, properties.getActiveMessageCount()); +// assertEquals(0, properties.getTransferDeadLetterMessageCount()); +// assertEquals(0, properties.getTransferMessageCount()); +// assertTrue(properties.getDeadLetterMessageCount() >= 0); +// +// assertNotNull(properties.getCreatedAt()); +// assertTrue(nowUtc.isAfter(properties.getCreatedAt())); +// assertNotNull(properties.getAccessedAt()); +// } +// +// @Test +// void getSubscriptionRuntimePropertiesUnauthorizedClient() { +// final String connectionString = interceptorManager.isPlaybackMode() +// ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" +// : TestUtils.getConnectionString(false); +// +// final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", +// "SharedAccessKey=fake-key-"); +// +// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() +// .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) +// .connectionString(connectionStringUpdated); +// +// if (interceptorManager.isPlaybackMode()) { +// builder.httpClient(interceptorManager.getPlaybackClient()); +// } else if (!interceptorManager.isLiveMode()) { +// builder.addPolicy(interceptorManager.getRecordPolicy()); +// } +// +// final ServiceBusAdministrationClient client = builder.buildClient(); +// +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); +// +// ClientAuthenticationException exception = assertThrows(ClientAuthenticationException.class, +// () -> client.getSubscriptionRuntimeProperties(topicName, subscriptionName), +// "Subscription runtime properties accessible by unauthorized client! This should not be possible."); +// } +// +// @Test +// void getRule() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = "$Default"; +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// +// final Response response = client.getRuleWithResponse(topicName, subscriptionName, ruleName, null); +// assertEquals(200, response.getStatusCode()); +// +// final RuleProperties contents = response.getValue(); +// +// assertNotNull(contents); +// assertEquals(ruleName, contents.getName()); +// assertNotNull(contents.getFilter()); +// assertTrue(contents.getFilter() instanceof SqlRuleFilter); +// +// assertNotNull(contents.getAction()); +// assertTrue(contents.getAction() instanceof EmptyRuleAction); +// } +// +// @Test +// void getRuleDoesNotExist() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = "does-not-exist-rule"; +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// assertThrows(ResourceNotFoundException.class, +// () -> client.getRuleWithResponse(topicName, subscriptionName, ruleName, Context.NONE)); +// } +// +// //endregion +// +// //region Delete tests +// +// @Test +// void deleteQueue() { +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = testResourceNamer.randomName("queue", 10); +// +// client.createQueue(queueName); +// client.deleteQueue(queueName); +// } +// +// +// @Test +// void deleteQueueDoesNotExist() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String queueName = testResourceNamer.randomName("queue", 10); +// +// // Act & Assert +// assertThrows(ResourceNotFoundException.class, () -> client.deleteQueue(queueName)); +// } +// +// @Test +// void deleteRule() { +// final ServiceBusAdministrationClient client = getClient(); +// final String ruleName = getEntityName(getRuleBaseName(), 9); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// client.createRule(topicName, subscriptionName, ruleName); +// +// client.deleteRule(topicName, subscriptionName, ruleName); +// } +// +// @Test +// void deleteRuleDoesNotExist() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String ruleName = testResourceNamer.randomName("rule-", 11); +// final String topicName = getEntityName(getTopicBaseName(), 13); +// final String subscriptionName = getSubscriptionBaseName(); +// +// // Act & Assert +// assertThrows(ResourceNotFoundException.class, () -> client.deleteRule(topicName, subscriptionName, ruleName)); +// } +// +// @Test +// void deleteSubscription() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); +// +// client.createSubscription(topicName, subscriptionName); +// +// client.deleteSubscription(topicName, subscriptionName); +// } +// +// @Test +// void deleteSubscriptionDoesNotExist() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = testResourceNamer.randomName("topic", 10); +// final String subscriptionName = testResourceNamer.randomName("sub", 7); +// +// // The topic exists but the subscription does not. +// client.createTopic(topicName); +// +// // Act & Assert +// assertThrows(ResourceNotFoundException.class, () -> client.deleteSubscription(topicName, subscriptionName)); +// } +// +// @Test +// void deleteTopic() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = testResourceNamer.randomName("topic", 10); +// +// client.createTopic(topicName); +// client.deleteTopic(topicName); +// } +// +// @Test +// void deleteTopicDoesNotExist() { +// // Arrange +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = testResourceNamer.randomName("topic", 10); +// +// // Act & Assert +// assertThrows(ResourceNotFoundException.class, () -> client.deleteTopic(topicName)); +// } +// +// //endregion +// +// //region List tests +// +// @Test +// void listQueues() { +// final ServiceBusAdministrationClient client = getClient(); +// +// PagedIterable queueProperties = client.listQueues(); +// queueProperties.forEach(queueDescription -> { +// assertNotNull(queueDescription.getName()); +// assertTrue(queueDescription.getMaxDeliveryCount() > 0); +// assertSame(queueDescription.getStatus(), EntityStatus.ACTIVE); +// }); +// assertTrue(queueProperties.stream().findAny().isPresent()); +// } +// +// @Test +// void listTopics() { +// final ServiceBusAdministrationClient client = getClient(); +// +// PagedIterable topics = client.listTopics(); +// topics.forEach(topicProperties -> { +// assertNotNull(topicProperties.getName()); +// assertTrue(topicProperties.isBatchedOperationsEnabled()); +// assertFalse(topicProperties.isPartitioningEnabled()); +// }); +// assertTrue(topics.stream().count() > 1); +// } +// +// @Test +// void listSubscriptions() { +// final ServiceBusAdministrationClient client = getClient(); +// final String topicName = getEntityName(getTopicBaseName(), 2); +// +// PagedIterable subscriptionProperties = client.listSubscriptions(topicName); +// subscriptionProperties.forEach(subscription -> { +// assertEquals(topicName, subscription.getTopicName()); +// assertNotNull(subscription.getSubscriptionName()); +// }); +// assertTrue(subscriptionProperties.stream().findAny().isPresent()); +// } +// +// @Test +// void listRules() { +// final ServiceBusAdministrationClient client = getClient(); +// +// final String ruleName = "$Default"; +// final String topicName = getEntityName(getTopicBaseName(), 2); +// final String subscriptionName = getSubscriptionBaseName(); +// +// PagedIterable ruleProperties = client.listRules(topicName, subscriptionName); +// +// assertTrue(ruleProperties.stream().findAny().isPresent()); +// Optional ruleOptional = ruleProperties.stream() +// .filter(rule1 -> rule1.getName().equals(ruleName)).findFirst(); +// assertTrue(ruleOptional.isPresent()); +// RuleProperties rule = ruleOptional.get(); +// +// assertEquals(ruleName, rule.getName()); +// assertNotNull(rule.getFilter()); +// assertTrue(rule.getFilter() instanceof SqlRuleFilter); +// assertNotNull(rule.getAction()); +// assertTrue(rule.getAction() instanceof EmptyRuleAction); +// } //endregion private ServiceBusAdministrationClient getClient() { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .credential(getTestTokenCredential(interceptorManager)) + .credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)) .retryOptions(new RetryOptions(new FixedDelayOptions(1, TIMEOUT))); if (interceptorManager.isPlaybackMode()) { diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index cf3fe3c25a60..c3a442dbada6 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -102,30 +102,6 @@ "principalId": "[parameters('testApplicationOid')]" } }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2018-01-01-preview", - "name": "[guid(concat('dataReceiverRoleId', parameters('baseName')))]", - "dependsOn": [ - "[concat('Microsoft.ServiceBus/namespaces/', variables('namespaceName'))]" - ], - "properties": { - "roleDefinitionId": "[variables('serviceBusDataReceiverRoleId')]", - "principalId": "[parameters('testApplicationOid')]" - } - }, - { - "type": "Microsoft.Authorization/roleAssignments", - "apiVersion": "2018-01-01-preview", - "name": "[guid(concat('dataSenderRoleId', parameters('baseName')))]", - "dependsOn": [ - "[concat('Microsoft.ServiceBus/namespaces/', variables('namespaceName'))]" - ], - "properties": { - "roleDefinitionId": "[variables('serviceBusDataSenderRoleId')]", - "principalId": "[parameters('testApplicationOid')]" - } - }, { "type": "Microsoft.ServiceBus/namespaces/topics", "apiVersion": "2021-01-01-preview", From 47272995de8c1700294164604703a509b033958f Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 09:11:52 -0700 Subject: [PATCH 03/29] try enable admin tests --- ...inistrationAsyncClientIntegrationTest.java | 2313 ++++++++--------- ...usAdministrationClientIntegrationTest.java | 1534 +++++------ 2 files changed, 1913 insertions(+), 1934 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 9d0dfcf116e8..d197a65758e9 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -3,16 +3,80 @@ package com.azure.messaging.servicebus.administration; +//import com.azure.core.credential.AccessToken; +//import com.azure.core.credential.AzureSasCredential; +import com.azure.core.credential.TokenCredential; +import com.azure.core.exception.ClientAuthenticationException; +import com.azure.core.exception.ResourceExistsException; +import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.http.HttpClient; +import com.azure.core.http.HttpResponse; +import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; +import com.azure.core.http.policy.HttpLogDetailLevel; +import com.azure.core.http.policy.HttpLogOptions; +import com.azure.core.test.InterceptorManager; +import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.models.CustomMatcher; import com.azure.core.test.models.TestProxyRequestMatcher; import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; +import com.azure.core.test.utils.MockTokenCredential; +import com.azure.identity.AzurePowerShellCredentialBuilder; +import com.azure.identity.DefaultAzureCredentialBuilder; +import com.azure.messaging.servicebus.TestUtils; +import com.azure.messaging.servicebus.administration.models.AccessRights; +import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; +import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; +import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; +import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; +import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; +import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; +//import com.azure.messaging.servicebus.administration.models.NamespaceProperties; +import com.azure.messaging.servicebus.administration.models.NamespaceType; +import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; +import com.azure.messaging.servicebus.administration.models.RuleProperties; +import com.azure.messaging.servicebus.administration.models.SharedAccessAuthorizationRule; +import com.azure.messaging.servicebus.administration.models.SqlRuleAction; +import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; +import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; +import com.azure.messaging.servicebus.administration.models.TopicProperties; +import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; +import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +import org.junit.jupiter.api.Tag; +//import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.time.Clock; import java.time.Duration; +import java.time.OffsetDateTime; import java.util.Arrays; import java.util.Collections; import java.util.List; +//import java.util.regex.Matcher; +//import java.util.regex.Pattern; +import java.util.stream.Stream; + +import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; +//import static com.azure.messaging.servicebus.TestUtils.getConnectionString; +import static com.azure.messaging.servicebus.TestUtils.getEntityName; +import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; +import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; +import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +//import static org.junit.jupiter.api.Assumptions.assumeTrue; -class ServiceBusAdministrationAsyncClientIntegrationTest { +/** + * Tests {@link ServiceBusAdministrationAsyncClient}. + */ +@Tag("integration") +class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBase { private static final Duration TIMEOUT = Duration.ofSeconds(20); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); @@ -38,111 +102,11 @@ class ServiceBusAdministrationAsyncClientIntegrationTest { TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); } -} -// -//import com.azure.core.credential.AzureSasCredential; -//import com.azure.core.credential.TokenCredential; -//import com.azure.core.exception.ClientAuthenticationException; -//import com.azure.core.exception.ResourceExistsException; -//import com.azure.core.exception.ResourceNotFoundException; -//import com.azure.core.http.HttpClient; -//import com.azure.core.http.HttpResponse; -//import com.azure.core.http.netty.NettyAsyncHttpClientBuilder; -//import com.azure.core.http.policy.HttpLogDetailLevel; -//import com.azure.core.http.policy.HttpLogOptions; -//import com.azure.core.test.InterceptorManager; -//import com.azure.core.test.TestProxyTestBase; -//import com.azure.core.test.models.CustomMatcher; -//import com.azure.core.test.models.TestProxyRequestMatcher; -//import com.azure.core.test.models.TestProxySanitizer; -//import com.azure.core.test.models.TestProxySanitizerType; -//import com.azure.core.test.utils.MockTokenCredential; -//import com.azure.identity.AzurePowerShellCredentialBuilder; -//import com.azure.identity.DefaultAzureCredentialBuilder; -//import com.azure.messaging.servicebus.TestUtils; -//import com.azure.messaging.servicebus.administration.models.AccessRights; -//import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; -//import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; -//import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; -//import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; -//import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; -//import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; -//import com.azure.messaging.servicebus.administration.models.NamespaceProperties; -//import com.azure.messaging.servicebus.administration.models.NamespaceType; -//import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; -//import com.azure.messaging.servicebus.administration.models.RuleProperties; -//import com.azure.messaging.servicebus.administration.models.SharedAccessAuthorizationRule; -//import com.azure.messaging.servicebus.administration.models.SqlRuleAction; -//import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; -//import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; -//import com.azure.messaging.servicebus.administration.models.TopicProperties; -//import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; -//import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; -//import org.junit.jupiter.api.Tag; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.Arguments; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.core.publisher.Mono; -//import reactor.test.StepVerifier; -// -//import java.time.Clock; -//import java.time.Duration; -//import java.time.OffsetDateTime; -//import java.util.Arrays; -//import java.util.Collections; -//import java.util.List; -//import java.util.regex.Matcher; -//import java.util.regex.Pattern; -//import java.util.stream.Stream; -// -//import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; -//import static com.azure.messaging.servicebus.TestUtils.getConnectionString; -//import static com.azure.messaging.servicebus.TestUtils.getEntityName; -//import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; -//import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; -//import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertFalse; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assumptions.assumeTrue; -// -///** -// * Tests {@link ServiceBusAdministrationAsyncClient}. -// */ -//@Tag("integration") -//class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBase { -// private static final Duration TIMEOUT = Duration.ofSeconds(20); -// private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); -// -// /** -// * Sanitizer to remove header values for ServiceBusDlqSupplementaryAuthorization and -// * ServiceBusSupplementaryAuthorization. -// */ -// static final TestProxySanitizer AUTHORIZATION_HEADER; -// -// static final List TEST_PROXY_SANITIZERS; -// -// static final List TEST_PROXY_REQUEST_MATCHERS; -// -// static { -// AUTHORIZATION_HEADER = new TestProxySanitizer("SupplementaryAuthorization", null, -// "SharedAccessSignature sr=https%3A%2F%2Ffoo.servicebus.windows.net&sig=dummyValue%3D&se=1687267490&skn=dummyKey", -// TestProxySanitizerType.HEADER); -// TEST_PROXY_SANITIZERS = Collections.singletonList(AUTHORIZATION_HEADER); -// -// final List skippedHeaders = Arrays.asList("ServiceBusDlqSupplementaryAuthorization", -// "ServiceBusSupplementaryAuthorization"); -// final CustomMatcher customMatcher = new CustomMatcher().setExcludedHeaders(skippedHeaders); -// -// TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); -// } -// -// public static Stream createHttpClients() { -// return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); -// } -// + + public static Stream createHttpClients() { + return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); + } + // /** // * Test to connect to the service bus with an azure identity TokenCredential. // * com.azure.identity.ClientSecretCredential is used in this test. @@ -154,7 +118,13 @@ class ServiceBusAdministrationAsyncClientIntegrationTest { // void azureIdentityCredentials(HttpClient httpClient) { // // final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); -// final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); +// final TokenCredential tokenCredential; +// if (interceptorManager.isPlaybackMode()) { +// tokenCredential = request -> Mono.fromCallable(() -> +// new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); +// } else { +// tokenCredential = new DefaultAzureCredentialBuilder().build(); +// } // // final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); // @@ -217,1067 +187,1068 @@ class ServiceBusAdministrationAsyncClientIntegrationTest { // .expectComplete() // .verify(DEFAULT_TIMEOUT); // } -// -// //region Create tests -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createQueue(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("test", 10); -// final CreateQueueOptions expected = new CreateQueueOptions() -// .setMaxSizeInMegabytes(1024) -// .setMaxDeliveryCount(7) -// .setLockDuration(Duration.ofSeconds(45)) -// .setSessionRequired(true) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing"); -// -// // Act & Assert -// StepVerifier.create(client.createQueue(queueName, expected)) -// .assertNext(actual -> { -// assertEquals(queueName, actual.getName()); -// -// assertEquals(expected.getLockDuration(), actual.getLockDuration()); -// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); -// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// -// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); -// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); -// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); -// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); -// assertEquals(0, runtimeProperties.getTotalMessageCount()); -// assertEquals(0, runtimeProperties.getSizeInBytes()); -// assertNotNull(runtimeProperties.getCreatedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createQueueExistingName(HttpClient httpClient) { -// // Arrange -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); -// final CreateQueueOptions options = new CreateQueueOptions(); -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // Act & Assert -// StepVerifier.create(client.createQueue(queueName, options)) -// .expectError(ResourceExistsException.class) -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createQueueWithForwarding(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("test", 10); -// final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); -// final CreateQueueOptions expected = new CreateQueueOptions() -// .setForwardTo(forwardToEntityName) -// .setForwardDeadLetteredMessagesTo(forwardToEntityName); -// -// // Act & Assert -// StepVerifier.create(client.createQueue(queueName, expected)) -// .assertNext(actual -> { -// assertEquals(queueName, actual.getName()); -// -// // The URLs will be fake in playback mode. -// if (!interceptorManager.isPlaybackMode()) { -// assertEquals(expected.getForwardTo(), actual.getForwardTo()); -// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); -// } -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); -// assertNotNull(runtimeProperties.getCreatedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createQueueAuthorizationRules(HttpClient httpClient) { -// // Arrange -// final String keyName = "test-rule"; -// final List accessRights = Collections.singletonList(AccessRights.SEND); -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("test", 10); -// final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() -// ? new SharedAccessAuthorizationRule(keyName, "REDACTED", -// "REDACTED", accessRights) -// : new SharedAccessAuthorizationRule(keyName, accessRights); -// -// final CreateQueueOptions expected = new CreateQueueOptions() -// .setMaxSizeInMegabytes(1024) -// .setMaxDeliveryCount(7) -// .setLockDuration(Duration.ofSeconds(45)) -// .setSessionRequired(true) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing"); -// -// expected.getAuthorizationRules().add(rule); -// -// // Act & Assert -// StepVerifier.create(client.createQueue(queueName, expected)) -// .assertNext(actual -> { -// assertEquals(queueName, actual.getName()); -// -// assertEquals(expected.getLockDuration(), actual.getLockDuration()); -// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); -// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// -// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); -// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); -// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); -// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); -// assertEquals(0, runtimeProperties.getTotalMessageCount()); -// assertEquals(0, runtimeProperties.getSizeInBytes()); -// assertNotNull(runtimeProperties.getCreatedAt()); -// -// assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createRule(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// final String ruleName = testResourceNamer.randomName("rule", 10); -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); -// final CreateRuleOptions options = new CreateRuleOptions() -// .setAction(action) -// .setFilter(new FalseRuleFilter()); -// -// // Act & Assert -// StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName, options)) -// .assertNext(contents -> { -// -// assertNotNull(contents); -// assertEquals(ruleName, contents.getName()); -// -// assertNotNull(contents.getAction()); -// assertTrue(contents.getAction() instanceof SqlRuleAction); -// assertEquals(action.getSqlExpression(), ((SqlRuleAction) contents.getAction()).getSqlExpression()); -// -// assertNotNull(contents.getFilter()); -// assertTrue(contents.getFilter() instanceof FalseRuleFilter); -// -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createRuleDefaults(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// final String ruleName = testResourceNamer.randomName("rule", 10); -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName)) -// .assertNext(contents -> { -// assertEquals(ruleName, contents.getName()); -// assertTrue(contents.getFilter() instanceof TrueRuleFilter); -// assertTrue(contents.getAction() instanceof EmptyRuleAction); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createRuleResponse(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// final String ruleName = testResourceNamer.randomName("rule", 10); -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); -// filter.getParameters().put("@MyParameter", "My-Parameter-Value"); -// -// final CreateRuleOptions options = new CreateRuleOptions() -// .setAction(new EmptyRuleAction()) -// .setFilter(filter); -// -// // Act & Assert -// StepVerifier.create(client.createRuleWithResponse(topicName, subscriptionName, ruleName, options)) -// .assertNext(response -> { -// assertEquals(201, response.getStatusCode()); -// -// final RuleProperties contents = response.getValue(); -// -// assertNotNull(contents); -// assertEquals(ruleName, contents.getName()); -// -// assertNotNull(contents.getFilter()); -// assertTrue(contents.getFilter() instanceof SqlRuleFilter); -// -// final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); -// assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); -// -// assertNotNull(contents.getAction()); -// assertTrue(contents.getAction() instanceof EmptyRuleAction); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createSubscription(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 0); -// final String subscriptionName = testResourceNamer.randomName("sub", 10); -// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() -// .setMaxDeliveryCount(7) -// .setLockDuration(Duration.ofSeconds(45)) -// .setUserMetadata("some-metadata-for-testing-subscriptions"); -// -// // Act & Assert -// StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) -// .assertNext(actual -> { -// assertEquals(topicName, actual.getTopicName()); -// assertEquals(subscriptionName, actual.getSubscriptionName()); -// -// assertEquals(expected.getLockDuration(), actual.getLockDuration()); -// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// -// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); -// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createSubscriptionWithRule(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 0); -// final String subscriptionName = testResourceNamer.randomName("sub", 10); -// final CreateSubscriptionOptions subscriptionOptions = new CreateSubscriptionOptions() -// .setMaxDeliveryCount(7) -// .setLockDuration(Duration.ofSeconds(45)) -// .setUserMetadata("some-metadata-for-testing-subscriptions"); -// -// final String ruleName = testResourceNamer.randomName("rule", 10); -// final CreateRuleOptions ruleOptions = new CreateRuleOptions(new SqlRuleFilter("color='red'")); -// // Act & Assert -// StepVerifier.create(client.createSubscription(topicName, subscriptionName, ruleName, subscriptionOptions, ruleOptions) -// .flatMap(s -> client.getRule(topicName, subscriptionName, ruleName))) -// .assertNext(rule -> { -// assertEquals(ruleName, rule.getName()); -// assertTrue(rule.getFilter() instanceof SqlRuleFilter); -// assertEquals("color='red'", ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createSubscriptionExistingName(HttpClient httpClient) { -// // Arrange -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = getSessionSubscriptionBaseName(); -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // Act & Assert -// StepVerifier.create(client.createSubscription(topicName, subscriptionName)) -// .expectError(ResourceExistsException.class) -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createSubscriptionWithForwarding(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 3); -// final String subscriptionName = testResourceNamer.randomName("sub", 50); -// final String forwardToTopic = getEntityName(getTopicBaseName(), 4); -// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() -// .setForwardTo(forwardToTopic) -// .setForwardDeadLetteredMessagesTo(forwardToTopic); -// -// // Act & Assert -// StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) -// .assertNext(actual -> { -// assertEquals(topicName, actual.getTopicName()); -// assertEquals(subscriptionName, actual.getSubscriptionName()); -// -// // URLs are redacted so they will not match. -// if (!interceptorManager.isPlaybackMode()) { -// assertEquals(expected.getForwardTo(), actual.getForwardTo()); -// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); -// } -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createTopicWithResponse(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("test", 10); -// final CreateTopicOptions expected = new CreateTopicOptions() -// .setMaxSizeInMegabytes(2048L) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing-topic"); -// -// // Act & Assert -// StepVerifier.create(client.createTopicWithResponse(topicName, expected)) -// .assertNext(response -> { -// assertEquals(201, response.getStatusCode()); -// -// // Assert values on a topic. -// final TopicProperties actual = response.getValue(); -// -// assertEquals(topicName, actual.getName()); -// -// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// -// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); -// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); -// -// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); -// assertEquals(0, runtimeProperties.getSubscriptionCount()); -// assertEquals(0, runtimeProperties.getSizeInBytes()); -// assertNotNull(runtimeProperties.getCreatedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void createTopicExistingName(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 3); -// final CreateTopicOptions expected = new CreateTopicOptions() -// .setMaxSizeInMegabytes(2048L) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing-topic"); -// -// // Act & Assert -// StepVerifier.create(client.createTopicWithResponse(topicName, expected)) -// .expectError(ResourceExistsException.class) -// .verify(DEFAULT_TIMEOUT); -// } -// -// //endregion -// -// //region Delete tests -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteQueue(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("sub", 10); -// -// client.createQueue(queueName) -// .onErrorResume(ResourceExistsException.class, e -> Mono.empty()) -// .block(TIMEOUT); -// -// // Act & Assert -// StepVerifier.create(client.deleteQueue(queueName)) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteQueueDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("queue", 10); -// -// // Act & Assert -// StepVerifier.create(client.deleteQueue(queueName)) -// .expectError(ResourceNotFoundException.class) -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteRule(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String ruleName = testResourceNamer.randomName("rule-", 11); -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); -// -// // Act & Assert -// StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteRuleDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String ruleName = testResourceNamer.randomName("rule-", 11); -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) -// .expectError(ResourceNotFoundException.class) -// .verify(TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteSubscription(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("topic", 10); -// final String subscriptionName = testResourceNamer.randomName("sub", 7); -// -// client.createTopic(topicName).block(TIMEOUT); -// client.createSubscription(topicName, subscriptionName).block(TIMEOUT); -// -// // Act & Assert -// StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteSubscriptionDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("topic", 10); -// final String subscriptionName = testResourceNamer.randomName("sub", 7); -// -// // The topic exists but the subscription does not. -// client.createTopic(topicName).block(TIMEOUT); -// -// // Act & Assert -// StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) -// .expectError(ResourceNotFoundException.class) -// .verify(TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteTopic(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("topic", 10); -// -// client.createTopic(topicName).block(TIMEOUT); -// -// // Act & Assert -// StepVerifier.create(client.deleteTopic(topicName)) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void deleteTopicDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("topic", 10); -// -// // Act & Assert -// StepVerifier.create(client.deleteTopic(topicName)) -// .expectError(ResourceNotFoundException.class) -// .verify(TIMEOUT); -// } -// -// //endregion -// -// //region Get and exists tests -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getQueue(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// // Act & Assert -// StepVerifier.create(client.getQueue(queueName)) -// .assertNext(queueDescription -> { -// assertEquals(queueName, queueDescription.getName()); -// -// assertFalse(queueDescription.isPartitioningEnabled()); -// assertFalse(queueDescription.isSessionRequired()); -// assertNotNull(queueDescription.getLockDuration()); -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueDescription); -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getNamespace(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // Act & Assert -// StepVerifier.create(client.getNamespaceProperties()) -// .assertNext(properties -> { -// assertEquals(NamespaceType.MESSAGING, properties.getNamespaceType()); -// if (!interceptorManager.isPlaybackMode()) { -// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); -// assertEquals(split[0], properties.getName()); -// } -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getQueueDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("exist", 10); -// -// // Act & Assert -// StepVerifier.create(client.getQueue(queueName)) -// .expectError(ResourceNotFoundException.class) -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getQueueExists(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); -// -// // Act & Assert -// StepVerifier.create(client.getQueueExists(queueName)) -// .expectNext(true) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getQueueExistsFalse(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = testResourceNamer.randomName("exist", 10); -// -// // Act & Assert -// StepVerifier.create(client.getQueueExists(queueName)) -// .expectNext(false) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getQueueRuntimeProperties(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// // Act & Assert -// StepVerifier.create(client.getQueueRuntimeProperties(queueName)) -// .assertNext(RuntimeProperties -> { -// assertEquals(queueName, RuntimeProperties.getName()); -// -// assertNotNull(RuntimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); -// assertNotNull(RuntimeProperties.getAccessedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getRule(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // There is a single default rule created. -// final String ruleName = "$Default"; -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) -// .assertNext(response -> { -// assertEquals(200, response.getStatusCode()); -// -// final RuleProperties contents = response.getValue(); -// -// assertNotNull(contents); -// assertEquals(ruleName, contents.getName()); -// assertNotNull(contents.getFilter()); -// assertTrue(contents.getFilter() instanceof TrueRuleFilter); -// -// assertNotNull(contents.getAction()); -// assertTrue(contents.getAction() instanceof EmptyRuleAction); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getRuleDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// final String ruleName = "does-not-exist-rule"; -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) -// .expectError(ResourceNotFoundException.class) -// .verify(TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getSubscription(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = getSessionSubscriptionBaseName(); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// // Act & Assert -// StepVerifier.create(client.getSubscription(topicName, subscriptionName)) -// .assertNext(description -> { -// assertEquals(topicName, description.getTopicName()); -// assertEquals(subscriptionName, description.getSubscriptionName()); -// -// assertTrue(description.isSessionRequired()); -// assertNotNull(description.getLockDuration()); -// -// final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(description); -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getSubscriptionDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = "subscription-session-not-exist"; -// -// // Act & Assert -// StepVerifier.create(client.getSubscription(topicName, subscriptionName)) -// .expectError(ResourceNotFoundException.class) -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getSubscriptionExists(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = getSessionSubscriptionBaseName(); -// -// // Act & Assert -// StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) -// .expectNext(true) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getSubscriptionExistsFalse(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = "subscription-session-not-exist"; -// -// // Act & Assert -// StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) -// .expectNext(false) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getSubscriptionRuntimeProperties(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = getSessionSubscriptionBaseName(); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// // Act & Assert -// StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) -// .assertNext(description -> { -// assertEquals(topicName, description.getTopicName()); -// assertEquals(subscriptionName, description.getSubscriptionName()); -// -// assertTrue(description.getTotalMessageCount() >= 0); -// assertEquals(0, description.getActiveMessageCount()); -// assertEquals(0, description.getTransferDeadLetterMessageCount()); -// assertEquals(0, description.getTransferMessageCount()); -// assertTrue(description.getDeadLetterMessageCount() >= 0); -// -// assertNotNull(description.getCreatedAt()); -// assertTrue(nowUtc.isAfter(description.getCreatedAt())); -// assertNotNull(description.getAccessedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getTopic(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// // Act & Assert -// StepVerifier.create(client.getTopic(topicName)) -// .assertNext(topicDescription -> { -// assertEquals(topicName, topicDescription.getName()); -// -// assertTrue(topicDescription.isBatchedOperationsEnabled()); -// assertFalse(topicDescription.isDuplicateDetectionRequired()); -// assertNotNull(topicDescription.getDuplicateDetectionHistoryTimeWindow()); -// assertNotNull(topicDescription.getDefaultMessageTimeToLive()); -// assertFalse(topicDescription.isPartitioningEnabled()); -// -// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicDescription); -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getTopicDoesNotExist(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("exists", 10); -// -// // Act & Assert -// StepVerifier.create(client.getTopic(topicName)) -// .consumeErrorWith(error -> { -// assertTrue(error instanceof ResourceNotFoundException); -// -// final ResourceNotFoundException notFoundError = (ResourceNotFoundException) error; -// final HttpResponse response = notFoundError.getResponse(); -// -// assertNotNull(response); -// assertEquals(200, response.getStatusCode()); -// StepVerifier.create(response.getBody()) -// .verifyComplete(); -// }) -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getTopicExists(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// -// // Act & Assert -// StepVerifier.create(client.getTopicExists(topicName)) -// .expectNext(true) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getTopicExistsFalse(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = testResourceNamer.randomName("exists", 10); -// -// // Act & Assert -// StepVerifier.create(client.getTopicExists(topicName)) -// .expectNext(false) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getTopicRuntimeProperties(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// // Act & Assert -// StepVerifier.create(client.getTopicRuntimeProperties(topicName)) -// .assertNext(RuntimeProperties -> { -// assertEquals(topicName, RuntimeProperties.getName()); -// -// assertTrue(RuntimeProperties.getSubscriptionCount() > 1); -// -// assertNotNull(RuntimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); -// assertNotNull(RuntimeProperties.getAccessedAt()); -// assertTrue(nowUtc.isAfter(RuntimeProperties.getAccessedAt())); -// assertEquals(0, RuntimeProperties.getScheduledMessageCount()); -// -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { -// // Arrange -// final String connectionString = interceptorManager.isPlaybackMode() -// ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" -// : TestUtils.getConnectionString(false); -// -// final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", -// "SharedAccessKey=fake-key-"); -// -// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() -// .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) -// .connectionString(connectionStringUpdated); -// -// if (interceptorManager.isPlaybackMode()) { -// builder.httpClient(interceptorManager.getPlaybackClient()); -// } else if (interceptorManager.isLiveMode()) { -// builder.httpClient(httpClient); -// } else { -// builder.httpClient(httpClient) -// .addPolicy(interceptorManager.getRecordPolicy()); -// } -// -// final ServiceBusAdministrationAsyncClient client = builder.buildAsyncClient(); -// -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); -// -// // Act & Assert -// StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) -// .expectErrorMatches(throwable -> throwable instanceof ClientAuthenticationException) -// .verify(DEFAULT_TIMEOUT); -// } -// -// //endregion -// -// //region List tests -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void listRules(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // There is a single default rule created. -// final String ruleName = "$Default"; -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// StepVerifier.create(client.listRules(topicName, subscriptionName)) -// .assertNext(response -> { -// assertEquals(ruleName, response.getName()); -// assertNotNull(response.getFilter()); -// assertTrue(response.getFilter() instanceof TrueRuleFilter); -// -// assertNotNull(response.getAction()); -// assertTrue(response.getAction() instanceof EmptyRuleAction); -// }) -// .thenCancel() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void listQueues(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // Act & Assert -// StepVerifier.create(client.listQueues()) -// .assertNext(queueDescription -> { -// assertNotNull(queueDescription.getName()); -// assertTrue(queueDescription.isBatchedOperationsEnabled()); -// assertFalse(queueDescription.isDuplicateDetectionRequired()); -// assertFalse(queueDescription.isPartitioningEnabled()); -// }) -// .expectNextCount(9) -// .thenCancel() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void listSubscriptions(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// -// // Act & Assert -// StepVerifier.create(client.listSubscriptions(topicName)) -// .assertNext(subscription -> { -// assertEquals(topicName, subscription.getTopicName()); -// assertNotNull(subscription.getSubscriptionName()); -// }) -// .expectNextCount(1) -// .thenCancel() -// .verify(DEFAULT_TIMEOUT); -// } -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void listTopics(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// // Act & Assert -// StepVerifier.create(client.listTopics()) -// .assertNext(topics -> { -// assertNotNull(topics.getName()); -// assertTrue(topics.isBatchedOperationsEnabled()); -// assertFalse(topics.isPartitioningEnabled()); -// }) -// .expectNextCount(2) -// .thenCancel() -// .verify(DEFAULT_TIMEOUT); -// } -// -// //endregion -// -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void updateRuleResponse(HttpClient httpClient) { -// // Arrange -// final ServiceBusAdministrationAsyncClient client = createClient(httpClient); -// -// final String ruleName = testResourceNamer.randomName("rule", 15); -// final String topicName = getEntityName(getTopicBaseName(), 12); -// final String subscriptionName = getSubscriptionBaseName(); -// final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); -// final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); -// -// final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); -// assertNotNull(existingRule); -// -// existingRule.setAction(expectedAction).setFilter(expectedFilter); -// -// // Act & Assert -// StepVerifier.create(client.updateRule(topicName, subscriptionName, existingRule)) -// .assertNext(contents -> { -// assertNotNull(contents); -// assertEquals(ruleName, contents.getName()); -// -// assertTrue(contents.getFilter() instanceof SqlRuleFilter); -// assertEquals(expectedFilter.getSqlExpression(), -// ((SqlRuleFilter) contents.getFilter()).getSqlExpression()); -// -// assertTrue(contents.getAction() instanceof SqlRuleAction); -// assertEquals(expectedAction.getSqlExpression(), -// ((SqlRuleAction) contents.getAction()).getSqlExpression()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { -// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() -// .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) -// .credential(getTestTokenCredential(interceptorManager)); -// -// if (interceptorManager.isPlaybackMode()) { -// builder.httpClient(interceptorManager.getPlaybackClient()); -// } else if (interceptorManager.isLiveMode()) { -// builder.httpClient(httpClient); -// } else { -// builder.httpClient(httpClient).addPolicy(interceptorManager.getRecordPolicy()); -// } -// -// if (!interceptorManager.isLiveMode()) { -// interceptorManager.addSanitizers(TEST_PROXY_SANITIZERS); -// interceptorManager.addMatchers(TEST_PROXY_REQUEST_MATCHERS); -// } -// -// return builder.buildAsyncClient(); -// } -// -// /** -// * Retrieve the appropriate TokenCredential based on the test mode. -// * -// * @param interceptorManager the interceptor manager -// * @return The appropriate token credential -// */ -// private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { -// if (interceptorManager.isLiveMode()) { -// return new AzurePowerShellCredentialBuilder().build(); -// } else if (interceptorManager.isRecordMode()) { -// return new DefaultAzureCredentialBuilder().build(); -// } else { -// return new MockTokenCredential(); -// } -// } -//} + + //region Create tests + + @ParameterizedTest + @MethodSource("createHttpClients") + void createQueue(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("test", 10); + final CreateQueueOptions expected = new CreateQueueOptions() + .setMaxSizeInMegabytes(1024) + .setMaxDeliveryCount(7) + .setLockDuration(Duration.ofSeconds(45)) + .setSessionRequired(true) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing"); + + // Act & Assert + StepVerifier.create(client.createQueue(queueName, expected)) + .assertNext(actual -> { + assertEquals(queueName, actual.getName()); + + assertEquals(expected.getLockDuration(), actual.getLockDuration()); + assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); + assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + + assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); + assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); + assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); + assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); + assertEquals(0, runtimeProperties.getTotalMessageCount()); + assertEquals(0, runtimeProperties.getSizeInBytes()); + assertNotNull(runtimeProperties.getCreatedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createQueueExistingName(HttpClient httpClient) { + // Arrange + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); + final CreateQueueOptions options = new CreateQueueOptions(); + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // Act & Assert + StepVerifier.create(client.createQueue(queueName, options)) + .expectError(ResourceExistsException.class) + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createQueueWithForwarding(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("test", 10); + final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); + final CreateQueueOptions expected = new CreateQueueOptions() + .setForwardTo(forwardToEntityName) + .setForwardDeadLetteredMessagesTo(forwardToEntityName); + + // Act & Assert + StepVerifier.create(client.createQueue(queueName, expected)) + .assertNext(actual -> { + assertEquals(queueName, actual.getName()); + + // The URLs will be fake in playback mode. + if (!interceptorManager.isPlaybackMode()) { + assertEquals(expected.getForwardTo(), actual.getForwardTo()); + assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); + } + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); + assertNotNull(runtimeProperties.getCreatedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createQueueAuthorizationRules(HttpClient httpClient) { + // Arrange + final String keyName = "test-rule"; + final List accessRights = Collections.singletonList(AccessRights.SEND); + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("test", 10); + final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() + ? new SharedAccessAuthorizationRule(keyName, "REDACTED", + "REDACTED", accessRights) + : new SharedAccessAuthorizationRule(keyName, accessRights); + + final CreateQueueOptions expected = new CreateQueueOptions() + .setMaxSizeInMegabytes(1024) + .setMaxDeliveryCount(7) + .setLockDuration(Duration.ofSeconds(45)) + .setSessionRequired(true) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing"); + + expected.getAuthorizationRules().add(rule); + + // Act & Assert + StepVerifier.create(client.createQueue(queueName, expected)) + .assertNext(actual -> { + assertEquals(queueName, actual.getName()); + + assertEquals(expected.getLockDuration(), actual.getLockDuration()); + assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); + assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + + assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); + assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); + assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); + assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); + assertEquals(0, runtimeProperties.getTotalMessageCount()); + assertEquals(0, runtimeProperties.getSizeInBytes()); + assertNotNull(runtimeProperties.getCreatedAt()); + + assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createRule(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + final String ruleName = testResourceNamer.randomName("rule", 10); + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); + final CreateRuleOptions options = new CreateRuleOptions() + .setAction(action) + .setFilter(new FalseRuleFilter()); + + // Act & Assert + StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName, options)) + .assertNext(contents -> { + + assertNotNull(contents); + assertEquals(ruleName, contents.getName()); + + assertNotNull(contents.getAction()); + assertTrue(contents.getAction() instanceof SqlRuleAction); + assertEquals(action.getSqlExpression(), ((SqlRuleAction) contents.getAction()).getSqlExpression()); + + assertNotNull(contents.getFilter()); + assertTrue(contents.getFilter() instanceof FalseRuleFilter); + + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createRuleDefaults(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + final String ruleName = testResourceNamer.randomName("rule", 10); + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + StepVerifier.create(client.createRule(topicName, subscriptionName, ruleName)) + .assertNext(contents -> { + assertEquals(ruleName, contents.getName()); + assertTrue(contents.getFilter() instanceof TrueRuleFilter); + assertTrue(contents.getAction() instanceof EmptyRuleAction); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createRuleResponse(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + final String ruleName = testResourceNamer.randomName("rule", 10); + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); + filter.getParameters().put("@MyParameter", "My-Parameter-Value"); + + final CreateRuleOptions options = new CreateRuleOptions() + .setAction(new EmptyRuleAction()) + .setFilter(filter); + + // Act & Assert + StepVerifier.create(client.createRuleWithResponse(topicName, subscriptionName, ruleName, options)) + .assertNext(response -> { + assertEquals(201, response.getStatusCode()); + + final RuleProperties contents = response.getValue(); + + assertNotNull(contents); + assertEquals(ruleName, contents.getName()); + + assertNotNull(contents.getFilter()); + assertTrue(contents.getFilter() instanceof SqlRuleFilter); + + final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); + assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); + + assertNotNull(contents.getAction()); + assertTrue(contents.getAction() instanceof EmptyRuleAction); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createSubscription(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 0); + final String subscriptionName = testResourceNamer.randomName("sub", 10); + final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() + .setMaxDeliveryCount(7) + .setLockDuration(Duration.ofSeconds(45)) + .setUserMetadata("some-metadata-for-testing-subscriptions"); + + // Act & Assert + StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) + .assertNext(actual -> { + assertEquals(topicName, actual.getTopicName()); + assertEquals(subscriptionName, actual.getSubscriptionName()); + + assertEquals(expected.getLockDuration(), actual.getLockDuration()); + assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + + assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); + assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createSubscriptionWithRule(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 0); + final String subscriptionName = testResourceNamer.randomName("sub", 10); + final CreateSubscriptionOptions subscriptionOptions = new CreateSubscriptionOptions() + .setMaxDeliveryCount(7) + .setLockDuration(Duration.ofSeconds(45)) + .setUserMetadata("some-metadata-for-testing-subscriptions"); + + final String ruleName = testResourceNamer.randomName("rule", 10); + final CreateRuleOptions ruleOptions = new CreateRuleOptions(new SqlRuleFilter("color='red'")); + // Act & Assert + StepVerifier.create(client.createSubscription(topicName, subscriptionName, ruleName, subscriptionOptions, ruleOptions) + .flatMap(s -> client.getRule(topicName, subscriptionName, ruleName))) + .assertNext(rule -> { + assertEquals(ruleName, rule.getName()); + assertTrue(rule.getFilter() instanceof SqlRuleFilter); + assertEquals("color='red'", ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createSubscriptionExistingName(HttpClient httpClient) { + // Arrange + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = getSessionSubscriptionBaseName(); + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // Act & Assert + StepVerifier.create(client.createSubscription(topicName, subscriptionName)) + .expectError(ResourceExistsException.class) + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createSubscriptionWithForwarding(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 3); + final String subscriptionName = testResourceNamer.randomName("sub", 50); + final String forwardToTopic = getEntityName(getTopicBaseName(), 4); + final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() + .setForwardTo(forwardToTopic) + .setForwardDeadLetteredMessagesTo(forwardToTopic); + + // Act & Assert + StepVerifier.create(client.createSubscription(topicName, subscriptionName, expected)) + .assertNext(actual -> { + assertEquals(topicName, actual.getTopicName()); + assertEquals(subscriptionName, actual.getSubscriptionName()); + + // URLs are redacted so they will not match. + if (!interceptorManager.isPlaybackMode()) { + assertEquals(expected.getForwardTo(), actual.getForwardTo()); + assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); + } + }) + .expectComplete() + .verify(TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createTopicWithResponse(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("test", 10); + final CreateTopicOptions expected = new CreateTopicOptions() + .setMaxSizeInMegabytes(2048L) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing-topic"); + + // Act & Assert + StepVerifier.create(client.createTopicWithResponse(topicName, expected)) + .assertNext(response -> { + assertEquals(201, response.getStatusCode()); + + // Assert values on a topic. + final TopicProperties actual = response.getValue(); + + assertEquals(topicName, actual.getName()); + + assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + + assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); + assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); + + final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); + assertEquals(0, runtimeProperties.getSubscriptionCount()); + assertEquals(0, runtimeProperties.getSizeInBytes()); + assertNotNull(runtimeProperties.getCreatedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void createTopicExistingName(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 3); + final CreateTopicOptions expected = new CreateTopicOptions() + .setMaxSizeInMegabytes(2048L) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing-topic"); + + // Act & Assert + StepVerifier.create(client.createTopicWithResponse(topicName, expected)) + .expectError(ResourceExistsException.class) + .verify(DEFAULT_TIMEOUT); + } + + //endregion + + //region Delete tests + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteQueue(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("sub", 10); + + client.createQueue(queueName) + .onErrorResume(ResourceExistsException.class, e -> Mono.empty()) + .block(TIMEOUT); + + // Act & Assert + StepVerifier.create(client.deleteQueue(queueName)) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteQueueDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("queue", 10); + + // Act & Assert + StepVerifier.create(client.deleteQueue(queueName)) + .expectError(ResourceNotFoundException.class) + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteRule(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String ruleName = testResourceNamer.randomName("rule-", 11); + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); + + // Act & Assert + StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteRuleDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String ruleName = testResourceNamer.randomName("rule-", 11); + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + StepVerifier.create(client.deleteRule(topicName, subscriptionName, ruleName)) + .expectError(ResourceNotFoundException.class) + .verify(TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteSubscription(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("topic", 10); + final String subscriptionName = testResourceNamer.randomName("sub", 7); + + client.createTopic(topicName).block(TIMEOUT); + client.createSubscription(topicName, subscriptionName).block(TIMEOUT); + + // Act & Assert + StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteSubscriptionDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("topic", 10); + final String subscriptionName = testResourceNamer.randomName("sub", 7); + + // The topic exists but the subscription does not. + client.createTopic(topicName).block(TIMEOUT); + + // Act & Assert + StepVerifier.create(client.deleteSubscription(topicName, subscriptionName)) + .expectError(ResourceNotFoundException.class) + .verify(TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteTopic(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("topic", 10); + + client.createTopic(topicName).block(TIMEOUT); + + // Act & Assert + StepVerifier.create(client.deleteTopic(topicName)) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void deleteTopicDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("topic", 10); + + // Act & Assert + StepVerifier.create(client.deleteTopic(topicName)) + .expectError(ResourceNotFoundException.class) + .verify(TIMEOUT); + } + + //endregion + + //region Get and exists tests + + @ParameterizedTest + @MethodSource("createHttpClients") + void getQueue(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + // Act & Assert + StepVerifier.create(client.getQueue(queueName)) + .assertNext(queueDescription -> { + assertEquals(queueName, queueDescription.getName()); + + assertFalse(queueDescription.isPartitioningEnabled()); + assertFalse(queueDescription.isSessionRequired()); + assertNotNull(queueDescription.getLockDuration()); + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueDescription); + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getNamespace(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // Act & Assert + StepVerifier.create(client.getNamespaceProperties()) + .assertNext(properties -> { + assertEquals(NamespaceType.MESSAGING, properties.getNamespaceType()); + if (!interceptorManager.isPlaybackMode()) { + final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); + assertEquals(split[0], properties.getName()); + } + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getQueueDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("exist", 10); + + // Act & Assert + StepVerifier.create(client.getQueue(queueName)) + .expectError(ResourceNotFoundException.class) + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getQueueExists(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); + + // Act & Assert + StepVerifier.create(client.getQueueExists(queueName)) + .expectNext(true) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getQueueExistsFalse(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = testResourceNamer.randomName("exist", 10); + + // Act & Assert + StepVerifier.create(client.getQueueExists(queueName)) + .expectNext(false) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getQueueRuntimeProperties(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 2); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + // Act & Assert + StepVerifier.create(client.getQueueRuntimeProperties(queueName)) + .assertNext(RuntimeProperties -> { + assertEquals(queueName, RuntimeProperties.getName()); + + assertNotNull(RuntimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); + assertNotNull(RuntimeProperties.getAccessedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getRule(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // There is a single default rule created. + final String ruleName = "$Default"; + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) + .assertNext(response -> { + assertEquals(200, response.getStatusCode()); + + final RuleProperties contents = response.getValue(); + + assertNotNull(contents); + assertEquals(ruleName, contents.getName()); + assertNotNull(contents.getFilter()); + assertTrue(contents.getFilter() instanceof TrueRuleFilter); + + assertNotNull(contents.getAction()); + assertTrue(contents.getAction() instanceof EmptyRuleAction); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getRuleDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + final String ruleName = "does-not-exist-rule"; + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + StepVerifier.create(client.getRuleWithResponse(topicName, subscriptionName, ruleName)) + .expectError(ResourceNotFoundException.class) + .verify(TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getSubscription(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = getSessionSubscriptionBaseName(); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + // Act & Assert + StepVerifier.create(client.getSubscription(topicName, subscriptionName)) + .assertNext(description -> { + assertEquals(topicName, description.getTopicName()); + assertEquals(subscriptionName, description.getSubscriptionName()); + + assertTrue(description.isSessionRequired()); + assertNotNull(description.getLockDuration()); + + final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(description); + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getSubscriptionDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = "subscription-session-not-exist"; + + // Act & Assert + StepVerifier.create(client.getSubscription(topicName, subscriptionName)) + .expectError(ResourceNotFoundException.class) + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getSubscriptionExists(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = getSessionSubscriptionBaseName(); + + // Act & Assert + StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) + .expectNext(true) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getSubscriptionExistsFalse(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = "subscription-session-not-exist"; + + // Act & Assert + StepVerifier.create(client.getSubscriptionExists(topicName, subscriptionName)) + .expectNext(false) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getSubscriptionRuntimeProperties(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = getSessionSubscriptionBaseName(); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + // Act & Assert + StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) + .assertNext(description -> { + assertEquals(topicName, description.getTopicName()); + assertEquals(subscriptionName, description.getSubscriptionName()); + + assertTrue(description.getTotalMessageCount() >= 0); + assertEquals(0, description.getActiveMessageCount()); + assertEquals(0, description.getTransferDeadLetterMessageCount()); + assertEquals(0, description.getTransferMessageCount()); + assertTrue(description.getDeadLetterMessageCount() >= 0); + + assertNotNull(description.getCreatedAt()); + assertTrue(nowUtc.isAfter(description.getCreatedAt())); + assertNotNull(description.getAccessedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getTopic(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + // Act & Assert + StepVerifier.create(client.getTopic(topicName)) + .assertNext(topicDescription -> { + assertEquals(topicName, topicDescription.getName()); + + assertTrue(topicDescription.isBatchedOperationsEnabled()); + assertFalse(topicDescription.isDuplicateDetectionRequired()); + assertNotNull(topicDescription.getDuplicateDetectionHistoryTimeWindow()); + assertNotNull(topicDescription.getDefaultMessageTimeToLive()); + assertFalse(topicDescription.isPartitioningEnabled()); + + final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicDescription); + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getTopicDoesNotExist(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("exists", 10); + + // Act & Assert + StepVerifier.create(client.getTopic(topicName)) + .consumeErrorWith(error -> { + assertTrue(error instanceof ResourceNotFoundException); + + final ResourceNotFoundException notFoundError = (ResourceNotFoundException) error; + final HttpResponse response = notFoundError.getResponse(); + + assertNotNull(response); + assertEquals(200, response.getStatusCode()); + StepVerifier.create(response.getBody()) + .verifyComplete(); + }) + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getTopicExists(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + + // Act & Assert + StepVerifier.create(client.getTopicExists(topicName)) + .expectNext(true) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getTopicExistsFalse(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = testResourceNamer.randomName("exists", 10); + + // Act & Assert + StepVerifier.create(client.getTopicExists(topicName)) + .expectNext(false) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getTopicRuntimeProperties(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + // Act & Assert + StepVerifier.create(client.getTopicRuntimeProperties(topicName)) + .assertNext(RuntimeProperties -> { + assertEquals(topicName, RuntimeProperties.getName()); + + assertTrue(RuntimeProperties.getSubscriptionCount() > 1); + + assertNotNull(RuntimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(RuntimeProperties.getCreatedAt())); + assertNotNull(RuntimeProperties.getAccessedAt()); + assertTrue(nowUtc.isAfter(RuntimeProperties.getAccessedAt())); + assertEquals(0, RuntimeProperties.getScheduledMessageCount()); + + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { + // Arrange + final String connectionString = interceptorManager.isPlaybackMode() + ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" + : TestUtils.getConnectionString(false); + + final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", + "SharedAccessKey=fake-key-"); + + final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() + .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) + .connectionString(connectionStringUpdated); + + if (interceptorManager.isPlaybackMode()) { + builder.httpClient(interceptorManager.getPlaybackClient()); + } else if (interceptorManager.isLiveMode()) { + builder.httpClient(httpClient); + } else { + builder.httpClient(httpClient) + .addPolicy(interceptorManager.getRecordPolicy()); + } + + final ServiceBusAdministrationAsyncClient client = builder.buildAsyncClient(); + + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); + + // Act & Assert + StepVerifier.create(client.getSubscriptionRuntimeProperties(topicName, subscriptionName)) + .expectErrorMatches(throwable -> throwable instanceof ClientAuthenticationException) + .verify(DEFAULT_TIMEOUT); + } + + //endregion + + //region List tests + + @ParameterizedTest + @MethodSource("createHttpClients") + void listRules(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // There is a single default rule created. + final String ruleName = "$Default"; + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + StepVerifier.create(client.listRules(topicName, subscriptionName)) + .assertNext(response -> { + assertEquals(ruleName, response.getName()); + assertNotNull(response.getFilter()); + assertTrue(response.getFilter() instanceof TrueRuleFilter); + + assertNotNull(response.getAction()); + assertTrue(response.getAction() instanceof EmptyRuleAction); + }) + .thenCancel() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void listQueues(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // Act & Assert + StepVerifier.create(client.listQueues()) + .assertNext(queueDescription -> { + assertNotNull(queueDescription.getName()); + assertTrue(queueDescription.isBatchedOperationsEnabled()); + assertFalse(queueDescription.isDuplicateDetectionRequired()); + assertFalse(queueDescription.isPartitioningEnabled()); + }) + .expectNextCount(9) + .thenCancel() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void listSubscriptions(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + final String topicName = getEntityName(getTopicBaseName(), 1); + + // Act & Assert + StepVerifier.create(client.listSubscriptions(topicName)) + .assertNext(subscription -> { + assertEquals(topicName, subscription.getTopicName()); + assertNotNull(subscription.getSubscriptionName()); + }) + .expectNextCount(1) + .thenCancel() + .verify(DEFAULT_TIMEOUT); + } + + @ParameterizedTest + @MethodSource("createHttpClients") + void listTopics(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + // Act & Assert + StepVerifier.create(client.listTopics()) + .assertNext(topics -> { + assertNotNull(topics.getName()); + assertTrue(topics.isBatchedOperationsEnabled()); + assertFalse(topics.isPartitioningEnabled()); + }) + .expectNextCount(2) + .thenCancel() + .verify(DEFAULT_TIMEOUT); + } + + //endregion + + @ParameterizedTest + @MethodSource("createHttpClients") + void updateRuleResponse(HttpClient httpClient) { + // Arrange + final ServiceBusAdministrationAsyncClient client = createClient(httpClient); + + final String ruleName = testResourceNamer.randomName("rule", 15); + final String topicName = getEntityName(getTopicBaseName(), 12); + final String subscriptionName = getSubscriptionBaseName(); + final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); + final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); + + final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName).block(TIMEOUT); + assertNotNull(existingRule); + + existingRule.setAction(expectedAction).setFilter(expectedFilter); + + // Act & Assert + StepVerifier.create(client.updateRule(topicName, subscriptionName, existingRule)) + .assertNext(contents -> { + assertNotNull(contents); + assertEquals(ruleName, contents.getName()); + + assertTrue(contents.getFilter() instanceof SqlRuleFilter); + assertEquals(expectedFilter.getSqlExpression(), + ((SqlRuleFilter) contents.getFilter()).getSqlExpression()); + + assertTrue(contents.getAction() instanceof SqlRuleAction); + assertEquals(expectedAction.getSqlExpression(), + ((SqlRuleAction) contents.getAction()).getSqlExpression()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() + .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) + .credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)); + + if (interceptorManager.isPlaybackMode()) { + builder.httpClient(interceptorManager.getPlaybackClient()); + } else if (interceptorManager.isLiveMode()) { + builder.httpClient(httpClient); + } else { + builder.httpClient(httpClient).addPolicy(interceptorManager.getRecordPolicy()); + } + + if (!interceptorManager.isLiveMode()) { + interceptorManager.addSanitizers(TEST_PROXY_SANITIZERS); + interceptorManager.addMatchers(TEST_PROXY_REQUEST_MATCHERS); + } + + return builder.buildAsyncClient(); + } + + /** + * Retrieve the appropriate TokenCredential based on the test mode. + * + * @param interceptorManager the interceptor manager + * @return The appropriate token credential + */ + private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { + if (interceptorManager.isLiveMode()) { + return new AzurePowerShellCredentialBuilder().build(); + } else if (interceptorManager.isRecordMode()) { + return new DefaultAzureCredentialBuilder().build(); + } else { + return new MockTokenCredential(); + } + } +} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 65a26fcbe3c1..17238526d052 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -3,56 +3,58 @@ package com.azure.messaging.servicebus.administration; +//import com.azure.core.credential.AccessToken; //import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; -//import com.azure.core.exception.ClientAuthenticationException; -//import com.azure.core.exception.ResourceExistsException; -//import com.azure.core.exception.ResourceNotFoundException; +import com.azure.core.exception.ClientAuthenticationException; +import com.azure.core.exception.ResourceExistsException; +import com.azure.core.exception.ResourceNotFoundException; import com.azure.core.http.policy.FixedDelayOptions; import com.azure.core.http.policy.HttpLogDetailLevel; import com.azure.core.http.policy.HttpLogOptions; import com.azure.core.http.policy.RetryOptions; -//import com.azure.core.http.rest.PagedIterable; -//import com.azure.core.http.rest.Response; +import com.azure.core.http.rest.PagedIterable; +import com.azure.core.http.rest.Response; import com.azure.core.test.InterceptorManager; import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.utils.MockTokenCredential; -//import com.azure.core.util.Context; +import com.azure.core.util.Context; import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; -//import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; -//import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; -//import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; -//import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; -//import com.azure.messaging.servicebus.administration.models.EntityStatus; -//import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; -//import com.azure.messaging.servicebus.administration.models.NamespaceProperties; -//import com.azure.messaging.servicebus.administration.models.NamespaceType; +import com.azure.messaging.servicebus.administration.models.CreateRuleOptions; +import com.azure.messaging.servicebus.administration.models.CreateSubscriptionOptions; +import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; +import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; +import com.azure.messaging.servicebus.administration.models.EntityStatus; +import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; +import com.azure.messaging.servicebus.administration.models.NamespaceProperties; +import com.azure.messaging.servicebus.administration.models.NamespaceType; import com.azure.messaging.servicebus.administration.models.QueueProperties; import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; -//import com.azure.messaging.servicebus.administration.models.RuleProperties; +import com.azure.messaging.servicebus.administration.models.RuleProperties; import com.azure.messaging.servicebus.administration.models.SharedAccessAuthorizationRule; -//import com.azure.messaging.servicebus.administration.models.SqlRuleAction; -//import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; -//import com.azure.messaging.servicebus.administration.models.SubscriptionProperties; -//import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; -//import com.azure.messaging.servicebus.administration.models.TopicProperties; -//import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; -//import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +import com.azure.messaging.servicebus.administration.models.SqlRuleAction; +import com.azure.messaging.servicebus.administration.models.SqlRuleFilter; +import com.azure.messaging.servicebus.administration.models.SubscriptionProperties; +import com.azure.messaging.servicebus.administration.models.SubscriptionRuntimeProperties; +import com.azure.messaging.servicebus.administration.models.TopicProperties; +import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; +import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; +//import reactor.core.publisher.Mono; -//import java.time.Clock; +import java.time.Clock; import java.time.Duration; -//import java.time.OffsetDateTime; +import java.time.OffsetDateTime; import java.util.Collections; import java.util.List; -//import java.util.Optional; +import java.util.Optional; //import java.util.regex.Matcher; //import java.util.regex.Pattern; @@ -60,15 +62,15 @@ //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getQueueBaseName; -//import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; -//import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; -//import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; +import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; +import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; +import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertSame; -//import static org.junit.jupiter.api.Assertions.assertThrows; -//import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; //import static org.junit.jupiter.api.Assumptions.assumeTrue; /** @@ -89,7 +91,13 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest // void azureIdentityCredentials() { // // Arrange // final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); -// final TokenCredential tokenCredential = getTestTokenCredential(interceptorManager); +// final TokenCredential tokenCredential; +// if (interceptorManager.isPlaybackMode()) { +// tokenCredential = request -> Mono.fromCallable(() -> +// new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); +// } else { +// tokenCredential = new DefaultAzureCredentialBuilder().build(); +// } // // final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); // @@ -114,7 +122,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest // assertEquals(split[0], properties.getName()); // } // } -// + // /** // * Test to connect to the service bus with an azure sas credential. // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below @@ -193,735 +201,735 @@ void createQueue() { assertNotNull(runtimeProperties.getCreatedAt()); } -// @Test -// void createQueueWithForwarding() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = testResourceNamer.randomName("test", 10); -// final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); -// final CreateQueueOptions expected = new CreateQueueOptions() -// .setForwardTo(forwardToEntityName) -// .setForwardDeadLetteredMessagesTo(forwardToEntityName); -// -// // Act -// final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); -// final QueueProperties actual = response.getValue(); -// -// // Assert -// assertEquals(queueName, actual.getName()); -// -// // The URLs will be fake in playback mode. -// if (!interceptorManager.isPlaybackMode()) { -// assertEquals(expected.getForwardTo(), actual.getForwardTo()); -// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); -// } -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); -// assertNotNull(runtimeProperties.getCreatedAt()); -// } -// -// @Test -// void createQueueAuthorizationRules() { -// // Arrange -// final String keyName = "test-rule"; -// final List accessRights = Collections.singletonList(AccessRights.SEND); -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = testResourceNamer.randomName("test", 10); -// final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() -// ? new SharedAccessAuthorizationRule(keyName, "REDACTED", -// "REDACTED", accessRights) -// : new SharedAccessAuthorizationRule(keyName, accessRights); -// -// final CreateQueueOptions expected = new CreateQueueOptions() -// .setMaxSizeInMegabytes(1024) -// .setMaxDeliveryCount(7) -// .setLockDuration(Duration.ofSeconds(45)) -// .setSessionRequired(true) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing"); -// -// expected.getAuthorizationRules().add(rule); -// -// // Act -// final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); -// final QueueProperties actual = response.getValue(); -// -// // Assert -// assertEquals(queueName, actual.getName()); -// -// assertEquals(expected.getLockDuration(), actual.getLockDuration()); -// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); -// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// -// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); -// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); -// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); -// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); -// assertEquals(0, runtimeProperties.getTotalMessageCount()); -// assertEquals(0, runtimeProperties.getSizeInBytes()); -// assertNotNull(runtimeProperties.getCreatedAt()); -// -// assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); -// } -// -// @Test -// void createTopicWithResponse() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = testResourceNamer.randomName("test", 10); -// final CreateTopicOptions expected = new CreateTopicOptions() -// .setMaxSizeInMegabytes(2048L) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing-topic"); -// -// final Response response = client.createTopicWithResponse(topicName, expected, null); -// assertEquals(201, response.getStatusCode()); -// -// final TopicProperties actual = response.getValue(); -// -// assertEquals(topicName, actual.getName()); -// assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); -// assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); -// -// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); -// assertEquals(0, runtimeProperties.getSubscriptionCount()); -// assertEquals(0, runtimeProperties.getSizeInBytes()); -// assertNotNull(runtimeProperties.getCreatedAt()); -// } -// -// @Test -// void createTopicExistingName() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 3); -// final CreateTopicOptions expected = new CreateTopicOptions() -// .setMaxSizeInMegabytes(2048L) -// .setDuplicateDetectionRequired(true) -// .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) -// .setUserMetadata("some-metadata-for-testing-topic"); -// -// // Act & Assert -// assertThrows(ResourceExistsException.class, -// () -> client.createTopicWithResponse(topicName, expected, Context.NONE)); -// } -// -// @Test -// void createSubscription() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String forwardToTopic = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); -// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() -// .setMaxDeliveryCount(7) -// .setLockDuration(Duration.ofSeconds(45)) -// .setUserMetadata("some-metadata-for-testing-subscriptions") -// .setForwardTo(forwardToTopic) -// .setForwardDeadLetteredMessagesTo(forwardToTopic); -// -// final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); -// assertEquals(topicName, actual.getTopicName()); -// assertEquals(subscriptionName, actual.getSubscriptionName()); -// -// assertEquals(expected.getLockDuration(), actual.getLockDuration()); -// assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); -// assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); -// -// assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); -// assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); -// -// // URLs are redacted so they will not match. -// if (!interceptorManager.isPlaybackMode()) { -// assertEquals(expected.getForwardTo(), actual.getForwardTo()); -// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); -// } -// } -// -// @Test -// void createRule() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = testResourceNamer.randomName("rule", 5); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); -// final CreateRuleOptions options = new CreateRuleOptions() -// .setAction(action) -// .setFilter(new FalseRuleFilter()); -// -// final RuleProperties actual = client.createRule(topicName, ruleName, subscriptionName, options); -// assertNotNull(actual); -// assertEquals(ruleName, actual.getName()); -// assertNotNull(actual.getAction()); -// -// assertTrue(actual.getAction() instanceof SqlRuleAction); -// assertEquals(action.getSqlExpression(), ((SqlRuleAction) actual.getAction()).getSqlExpression()); -// -// assertNotNull(actual.getFilter()); -// assertTrue(actual.getFilter() instanceof FalseRuleFilter); -// } -// -// @Test -// void createRuleDefaults() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = testResourceNamer.randomName("rule", 7); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// -// final RuleProperties rule = client.createRule(topicName, subscriptionName, ruleName); -// assertEquals(ruleName, rule.getName()); -// assertTrue(rule.getFilter() instanceof TrueRuleFilter); -// assertTrue(rule.getAction() instanceof EmptyRuleAction); -// } -// -// @Test -// void createRuleResponse() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = testResourceNamer.randomName("rule", 10); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// -// final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); -// filter.getParameters().put("@MyParameter", "My-Parameter-Value"); -// -// final CreateRuleOptions options = new CreateRuleOptions() -// .setAction(new EmptyRuleAction()) -// .setFilter(filter); -// -// final Response response = client.createRuleWithResponse(topicName, subscriptionName, -// ruleName, options, null); -// assertEquals(201, response.getStatusCode()); -// -// final RuleProperties contents = response.getValue(); -// assertNotNull(contents); -// assertEquals(ruleName, contents.getName()); -// -// assertNotNull(contents.getFilter()); -// assertTrue(contents.getFilter() instanceof SqlRuleFilter); -// -// final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); -// assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); -// -// assertNotNull(contents.getAction()); -// assertTrue(contents.getAction() instanceof EmptyRuleAction); -// } -// -// @Test -// void createQueueExistingName() { -// final String queueName = getEntityName(getQueueBaseName(), 5); -// final CreateQueueOptions options = new CreateQueueOptions(); -// final ServiceBusAdministrationClient client = getClient(); -// -// ResourceExistsException exception = assertThrows(ResourceExistsException.class, -// () -> client.createQueue(queueName, options), -// "Queue exists exception not thrown when creating a queue with existing name"); -// } -// -// @Test -// void createSubscriptionExistingName() { -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// final ServiceBusAdministrationClient client = getClient(); -// -// ResourceExistsException exception = assertThrows(ResourceExistsException.class, -// () -> client.createSubscription(topicName, subscriptionName), -// "Queue exists exception not thrown when creating a queue with existing name"); -// } -// -// @Test -// void createSubscriptionWithForwarding() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 3); -// final String subscriptionName = testResourceNamer.randomName("sub", 50); -// final String forwardToTopic = getEntityName(getTopicBaseName(), 4); -// final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() -// .setForwardTo(forwardToTopic) -// .setForwardDeadLetteredMessagesTo(forwardToTopic); -// -// // Act -// final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); -// -// // Assert -// assertEquals(topicName, actual.getTopicName()); -// assertEquals(subscriptionName, actual.getSubscriptionName()); -// -// // URLs are redacted so they will not match. -// if (!interceptorManager.isPlaybackMode()) { -// assertEquals(expected.getForwardTo(), actual.getForwardTo()); -// assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); -// } -// } -// -// //endregion -// -// @Test -// void updateRuleResponse() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = testResourceNamer.randomName("rule", 15); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); -// final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); -// -// final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName); -// assertNotNull(existingRule); -// -// existingRule.setAction(expectedAction).setFilter(expectedFilter); -// -// final RuleProperties rule = client.updateRule(topicName, subscriptionName, existingRule); -// assertNotNull(rule); -// assertEquals(ruleName, rule.getName()); -// -// assertTrue(rule.getFilter() instanceof SqlRuleFilter); -// assertEquals(expectedFilter.getSqlExpression(), -// ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); -// -// assertTrue(rule.getAction() instanceof SqlRuleAction); -// assertEquals(expectedAction.getSqlExpression(), -// ((SqlRuleAction) rule.getAction()).getSqlExpression()); -// } -// -// //region Get and exists tests -// -// @Test -// void getNamespace() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final NamespaceProperties namespaceProperties = client.getNamespaceProperties(); -// assertEquals(NamespaceType.MESSAGING, namespaceProperties.getNamespaceType()); -// if (!interceptorManager.isPlaybackMode()) { -// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); -// assertEquals(split[0], namespaceProperties.getName()); -// } -// } -// -// @Test -// void getQueue() { -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// final QueueProperties queueProperties = client.getQueue(queueName); -// assertEquals(queueName, queueProperties.getName()); -// -// assertFalse(queueProperties.isPartitioningEnabled()); -// assertFalse(queueProperties.isSessionRequired()); -// assertNotNull(queueProperties.getLockDuration()); -// -// final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueProperties); -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// } -// -// @Test -// void getQueueDoesNotExist() { -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); -// -// assertThrows(ResourceNotFoundException.class, () -> client.getQueue(queueName), -// "Queue exists! But should not. Incorrect getQueue behavior"); -// } -// -// @Test -// void getQueueExists() { -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); -// -// assertTrue(client.getQueueExists(queueName)); -// } -// -// @Test -// void getQueueExistsFalse() { -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); -// -// assertFalse(client.getQueueExists(queueName)); -// } -// -// @Test -// void getQueueRuntimeProperties() { -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// final QueueRuntimeProperties runtimeProperties = client.getQueueRuntimeProperties(queueName); -// assertEquals(queueName, runtimeProperties.getName()); -// -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// } -// -// @Test -// void getTopic() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// final TopicProperties topicProperties = client.getTopic(topicName); -// assertEquals(topicName, topicProperties.getName()); -// -// assertTrue(topicProperties.isBatchedOperationsEnabled()); -// assertFalse(topicProperties.isDuplicateDetectionRequired()); -// assertNotNull(topicProperties.getDuplicateDetectionHistoryTimeWindow()); -// assertNotNull(topicProperties.getDefaultMessageTimeToLive()); -// assertFalse(topicProperties.isPartitioningEnabled()); -// -// final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicProperties); -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// } -// -// @Test -// void getTopicDoesNotExist() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = testResourceNamer.randomName("topic", 10); -// -// assertThrows(ResourceNotFoundException.class, () -> client.getTopic(topicName), -// "Topic exists! But should not. Incorrect getTopic behavior"); -// } -// -// @Test -// void getTopicExists() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// -// assertTrue(client.getTopicExists(topicName)); -// } -// -// @Test -// void getTopicExistsFalse() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = testResourceNamer.randomName(getTopicBaseName(), 10); -// -// assertFalse(client.getTopicExists(topicName)); -// } -// -// @Test -// void getTopicRuntimeProperties() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// final TopicRuntimeProperties runtimeProperties = client.getTopicRuntimeProperties(topicName); -// assertEquals(topicName, runtimeProperties.getName()); -// -// assertTrue(runtimeProperties.getSubscriptionCount() >= 1); -// -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getAccessedAt())); -// assertEquals(0, runtimeProperties.getScheduledMessageCount()); -// } -// -// @Test -// void getSubscription() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// final SubscriptionProperties properties = client.getSubscription(topicName, subscriptionName); -// assertEquals(topicName, properties.getTopicName()); -// assertEquals(subscriptionName, properties.getSubscriptionName()); -// -// assertFalse(properties.isSessionRequired()); -// assertNotNull(properties.getLockDuration()); -// -// final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(properties); -// assertNotNull(runtimeProperties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); -// assertNotNull(runtimeProperties.getAccessedAt()); -// } -// -// @Test -// void getSubscriptionDoesNotExist() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); -// -// assertThrows(ResourceNotFoundException.class, () -> client.getSubscription(topicName, subscriptionName), -// "Subscription exists! But should not. Incorrect getSubscription behavior"); -// } -// -// @Test -// void getSubscriptionExists() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// -// assertTrue(client.getSubscriptionExists(topicName, subscriptionName)); -// } -// -// @Test -// void getSubscriptionExistsFalse() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 1); -// final String subscriptionName = "subscription-session-not-exist"; -// -// // Act -// boolean response = client.getSubscriptionExists(topicName, subscriptionName); -// -// // Assert -// assertFalse(response); -// } -// -// @Test -// void getSubscriptionRuntimeProperties() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); -// -// final SubscriptionRuntimeProperties properties = client.getSubscriptionRuntimeProperties(topicName, subscriptionName); -// assertEquals(topicName, properties.getTopicName()); -// assertEquals(subscriptionName, properties.getSubscriptionName()); -// -// assertTrue(properties.getTotalMessageCount() >= 0); -// assertEquals(0, properties.getActiveMessageCount()); -// assertEquals(0, properties.getTransferDeadLetterMessageCount()); -// assertEquals(0, properties.getTransferMessageCount()); -// assertTrue(properties.getDeadLetterMessageCount() >= 0); -// -// assertNotNull(properties.getCreatedAt()); -// assertTrue(nowUtc.isAfter(properties.getCreatedAt())); -// assertNotNull(properties.getAccessedAt()); -// } -// -// @Test -// void getSubscriptionRuntimePropertiesUnauthorizedClient() { -// final String connectionString = interceptorManager.isPlaybackMode() -// ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" -// : TestUtils.getConnectionString(false); -// -// final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", -// "SharedAccessKey=fake-key-"); -// -// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() -// .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) -// .connectionString(connectionStringUpdated); -// -// if (interceptorManager.isPlaybackMode()) { -// builder.httpClient(interceptorManager.getPlaybackClient()); -// } else if (!interceptorManager.isLiveMode()) { -// builder.addPolicy(interceptorManager.getRecordPolicy()); -// } -// -// final ServiceBusAdministrationClient client = builder.buildClient(); -// -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); -// -// ClientAuthenticationException exception = assertThrows(ClientAuthenticationException.class, -// () -> client.getSubscriptionRuntimeProperties(topicName, subscriptionName), -// "Subscription runtime properties accessible by unauthorized client! This should not be possible."); -// } -// -// @Test -// void getRule() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = "$Default"; -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// -// final Response response = client.getRuleWithResponse(topicName, subscriptionName, ruleName, null); -// assertEquals(200, response.getStatusCode()); -// -// final RuleProperties contents = response.getValue(); -// -// assertNotNull(contents); -// assertEquals(ruleName, contents.getName()); -// assertNotNull(contents.getFilter()); -// assertTrue(contents.getFilter() instanceof SqlRuleFilter); -// -// assertNotNull(contents.getAction()); -// assertTrue(contents.getAction() instanceof EmptyRuleAction); -// } -// -// @Test -// void getRuleDoesNotExist() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = "does-not-exist-rule"; -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// assertThrows(ResourceNotFoundException.class, -// () -> client.getRuleWithResponse(topicName, subscriptionName, ruleName, Context.NONE)); -// } -// -// //endregion -// -// //region Delete tests -// -// @Test -// void deleteQueue() { -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = testResourceNamer.randomName("queue", 10); -// -// client.createQueue(queueName); -// client.deleteQueue(queueName); -// } -// -// -// @Test -// void deleteQueueDoesNotExist() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String queueName = testResourceNamer.randomName("queue", 10); -// -// // Act & Assert -// assertThrows(ResourceNotFoundException.class, () -> client.deleteQueue(queueName)); -// } -// -// @Test -// void deleteRule() { -// final ServiceBusAdministrationClient client = getClient(); -// final String ruleName = getEntityName(getRuleBaseName(), 9); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// client.createRule(topicName, subscriptionName, ruleName); -// -// client.deleteRule(topicName, subscriptionName, ruleName); -// } -// -// @Test -// void deleteRuleDoesNotExist() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String ruleName = testResourceNamer.randomName("rule-", 11); -// final String topicName = getEntityName(getTopicBaseName(), 13); -// final String subscriptionName = getSubscriptionBaseName(); -// -// // Act & Assert -// assertThrows(ResourceNotFoundException.class, () -> client.deleteRule(topicName, subscriptionName, ruleName)); -// } -// -// @Test -// void deleteSubscription() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); -// -// client.createSubscription(topicName, subscriptionName); -// -// client.deleteSubscription(topicName, subscriptionName); -// } -// -// @Test -// void deleteSubscriptionDoesNotExist() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = testResourceNamer.randomName("topic", 10); -// final String subscriptionName = testResourceNamer.randomName("sub", 7); -// -// // The topic exists but the subscription does not. -// client.createTopic(topicName); -// -// // Act & Assert -// assertThrows(ResourceNotFoundException.class, () -> client.deleteSubscription(topicName, subscriptionName)); -// } -// -// @Test -// void deleteTopic() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = testResourceNamer.randomName("topic", 10); -// -// client.createTopic(topicName); -// client.deleteTopic(topicName); -// } -// -// @Test -// void deleteTopicDoesNotExist() { -// // Arrange -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = testResourceNamer.randomName("topic", 10); -// -// // Act & Assert -// assertThrows(ResourceNotFoundException.class, () -> client.deleteTopic(topicName)); -// } -// -// //endregion -// -// //region List tests -// -// @Test -// void listQueues() { -// final ServiceBusAdministrationClient client = getClient(); -// -// PagedIterable queueProperties = client.listQueues(); -// queueProperties.forEach(queueDescription -> { -// assertNotNull(queueDescription.getName()); -// assertTrue(queueDescription.getMaxDeliveryCount() > 0); -// assertSame(queueDescription.getStatus(), EntityStatus.ACTIVE); -// }); -// assertTrue(queueProperties.stream().findAny().isPresent()); -// } -// -// @Test -// void listTopics() { -// final ServiceBusAdministrationClient client = getClient(); -// -// PagedIterable topics = client.listTopics(); -// topics.forEach(topicProperties -> { -// assertNotNull(topicProperties.getName()); -// assertTrue(topicProperties.isBatchedOperationsEnabled()); -// assertFalse(topicProperties.isPartitioningEnabled()); -// }); -// assertTrue(topics.stream().count() > 1); -// } -// -// @Test -// void listSubscriptions() { -// final ServiceBusAdministrationClient client = getClient(); -// final String topicName = getEntityName(getTopicBaseName(), 2); -// -// PagedIterable subscriptionProperties = client.listSubscriptions(topicName); -// subscriptionProperties.forEach(subscription -> { -// assertEquals(topicName, subscription.getTopicName()); -// assertNotNull(subscription.getSubscriptionName()); -// }); -// assertTrue(subscriptionProperties.stream().findAny().isPresent()); -// } -// -// @Test -// void listRules() { -// final ServiceBusAdministrationClient client = getClient(); -// -// final String ruleName = "$Default"; -// final String topicName = getEntityName(getTopicBaseName(), 2); -// final String subscriptionName = getSubscriptionBaseName(); -// -// PagedIterable ruleProperties = client.listRules(topicName, subscriptionName); -// -// assertTrue(ruleProperties.stream().findAny().isPresent()); -// Optional ruleOptional = ruleProperties.stream() -// .filter(rule1 -> rule1.getName().equals(ruleName)).findFirst(); -// assertTrue(ruleOptional.isPresent()); -// RuleProperties rule = ruleOptional.get(); -// -// assertEquals(ruleName, rule.getName()); -// assertNotNull(rule.getFilter()); -// assertTrue(rule.getFilter() instanceof SqlRuleFilter); -// assertNotNull(rule.getAction()); -// assertTrue(rule.getAction() instanceof EmptyRuleAction); -// } + @Test + void createQueueWithForwarding() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String queueName = testResourceNamer.randomName("test", 10); + final String forwardToEntityName = getEntityName(TestUtils.getQueueBaseName(), 5); + final CreateQueueOptions expected = new CreateQueueOptions() + .setForwardTo(forwardToEntityName) + .setForwardDeadLetteredMessagesTo(forwardToEntityName); + + // Act + final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); + final QueueProperties actual = response.getValue(); + + // Assert + assertEquals(queueName, actual.getName()); + + // The URLs will be fake in playback mode. + if (!interceptorManager.isPlaybackMode()) { + assertEquals(expected.getForwardTo(), actual.getForwardTo()); + assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); + } + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); + assertNotNull(runtimeProperties.getCreatedAt()); + } + + @Test + void createQueueAuthorizationRules() { + // Arrange + final String keyName = "test-rule"; + final List accessRights = Collections.singletonList(AccessRights.SEND); + final ServiceBusAdministrationClient client = getClient(); + final String queueName = testResourceNamer.randomName("test", 10); + final SharedAccessAuthorizationRule rule = interceptorManager.isPlaybackMode() + ? new SharedAccessAuthorizationRule(keyName, "REDACTED", + "REDACTED", accessRights) + : new SharedAccessAuthorizationRule(keyName, accessRights); + + final CreateQueueOptions expected = new CreateQueueOptions() + .setMaxSizeInMegabytes(1024) + .setMaxDeliveryCount(7) + .setLockDuration(Duration.ofSeconds(45)) + .setSessionRequired(true) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing"); + + expected.getAuthorizationRules().add(rule); + + // Act + final Response response = client.createQueueWithResponse(queueName, expected, Context.NONE); + final QueueProperties actual = response.getValue(); + + // Assert + assertEquals(queueName, actual.getName()); + + assertEquals(expected.getLockDuration(), actual.getLockDuration()); + assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); + assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + + assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); + assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); + assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); + assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(actual); + assertEquals(0, runtimeProperties.getTotalMessageCount()); + assertEquals(0, runtimeProperties.getSizeInBytes()); + assertNotNull(runtimeProperties.getCreatedAt()); + + assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); + } + + @Test + void createTopicWithResponse() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = testResourceNamer.randomName("test", 10); + final CreateTopicOptions expected = new CreateTopicOptions() + .setMaxSizeInMegabytes(2048L) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing-topic"); + + final Response response = client.createTopicWithResponse(topicName, expected, null); + assertEquals(201, response.getStatusCode()); + + final TopicProperties actual = response.getValue(); + + assertEquals(topicName, actual.getName()); + assertEquals(expected.getMaxSizeInMegabytes(), actual.getMaxSizeInMegabytes()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + assertEquals(expected.isPartitioningEnabled(), actual.isPartitioningEnabled()); + assertEquals(expected.isDuplicateDetectionRequired(), actual.isDuplicateDetectionRequired()); + + final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(actual); + assertEquals(0, runtimeProperties.getSubscriptionCount()); + assertEquals(0, runtimeProperties.getSizeInBytes()); + assertNotNull(runtimeProperties.getCreatedAt()); + } + + @Test + void createTopicExistingName() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 3); + final CreateTopicOptions expected = new CreateTopicOptions() + .setMaxSizeInMegabytes(2048L) + .setDuplicateDetectionRequired(true) + .setDuplicateDetectionHistoryTimeWindow(Duration.ofMinutes(2)) + .setUserMetadata("some-metadata-for-testing-topic"); + + // Act & Assert + assertThrows(ResourceExistsException.class, + () -> client.createTopicWithResponse(topicName, expected, Context.NONE)); + } + + @Test + void createSubscription() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String forwardToTopic = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); + final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() + .setMaxDeliveryCount(7) + .setLockDuration(Duration.ofSeconds(45)) + .setUserMetadata("some-metadata-for-testing-subscriptions") + .setForwardTo(forwardToTopic) + .setForwardDeadLetteredMessagesTo(forwardToTopic); + + final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); + assertEquals(topicName, actual.getTopicName()); + assertEquals(subscriptionName, actual.getSubscriptionName()); + + assertEquals(expected.getLockDuration(), actual.getLockDuration()); + assertEquals(expected.getMaxDeliveryCount(), actual.getMaxDeliveryCount()); + assertEquals(expected.getUserMetadata(), actual.getUserMetadata()); + + assertEquals(expected.isDeadLetteringOnMessageExpiration(), actual.isDeadLetteringOnMessageExpiration()); + assertEquals(expected.isSessionRequired(), actual.isSessionRequired()); + + // URLs are redacted so they will not match. + if (!interceptorManager.isPlaybackMode()) { + assertEquals(expected.getForwardTo(), actual.getForwardTo()); + assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); + } + } + + @Test + void createRule() { + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = testResourceNamer.randomName("rule", 5); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + final SqlRuleAction action = new SqlRuleAction("SET Label = 'test'"); + final CreateRuleOptions options = new CreateRuleOptions() + .setAction(action) + .setFilter(new FalseRuleFilter()); + + final RuleProperties actual = client.createRule(topicName, ruleName, subscriptionName, options); + assertNotNull(actual); + assertEquals(ruleName, actual.getName()); + assertNotNull(actual.getAction()); + + assertTrue(actual.getAction() instanceof SqlRuleAction); + assertEquals(action.getSqlExpression(), ((SqlRuleAction) actual.getAction()).getSqlExpression()); + + assertNotNull(actual.getFilter()); + assertTrue(actual.getFilter() instanceof FalseRuleFilter); + } + + @Test + void createRuleDefaults() { + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = testResourceNamer.randomName("rule", 7); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + + final RuleProperties rule = client.createRule(topicName, subscriptionName, ruleName); + assertEquals(ruleName, rule.getName()); + assertTrue(rule.getFilter() instanceof TrueRuleFilter); + assertTrue(rule.getAction() instanceof EmptyRuleAction); + } + + @Test + void createRuleResponse() { + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = testResourceNamer.randomName("rule", 10); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + + final SqlRuleFilter filter = new SqlRuleFilter("sys.To=@MyParameter OR sys.MessageId IS NULL"); + filter.getParameters().put("@MyParameter", "My-Parameter-Value"); + + final CreateRuleOptions options = new CreateRuleOptions() + .setAction(new EmptyRuleAction()) + .setFilter(filter); + + final Response response = client.createRuleWithResponse(topicName, subscriptionName, + ruleName, options, null); + assertEquals(201, response.getStatusCode()); + + final RuleProperties contents = response.getValue(); + assertNotNull(contents); + assertEquals(ruleName, contents.getName()); + + assertNotNull(contents.getFilter()); + assertTrue(contents.getFilter() instanceof SqlRuleFilter); + + final SqlRuleFilter actualFilter = (SqlRuleFilter) contents.getFilter(); + assertEquals(filter.getSqlExpression(), actualFilter.getSqlExpression()); + + assertNotNull(contents.getAction()); + assertTrue(contents.getAction() instanceof EmptyRuleAction); + } + + @Test + void createQueueExistingName() { + final String queueName = getEntityName(getQueueBaseName(), 5); + final CreateQueueOptions options = new CreateQueueOptions(); + final ServiceBusAdministrationClient client = getClient(); + + ResourceExistsException exception = assertThrows(ResourceExistsException.class, + () -> client.createQueue(queueName, options), + "Queue exists exception not thrown when creating a queue with existing name"); + } + + @Test + void createSubscriptionExistingName() { + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + final ServiceBusAdministrationClient client = getClient(); + + ResourceExistsException exception = assertThrows(ResourceExistsException.class, + () -> client.createSubscription(topicName, subscriptionName), + "Queue exists exception not thrown when creating a queue with existing name"); + } + + @Test + void createSubscriptionWithForwarding() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 3); + final String subscriptionName = testResourceNamer.randomName("sub", 50); + final String forwardToTopic = getEntityName(getTopicBaseName(), 4); + final CreateSubscriptionOptions expected = new CreateSubscriptionOptions() + .setForwardTo(forwardToTopic) + .setForwardDeadLetteredMessagesTo(forwardToTopic); + + // Act + final SubscriptionProperties actual = client.createSubscription(topicName, subscriptionName, expected); + + // Assert + assertEquals(topicName, actual.getTopicName()); + assertEquals(subscriptionName, actual.getSubscriptionName()); + + // URLs are redacted so they will not match. + if (!interceptorManager.isPlaybackMode()) { + assertEquals(expected.getForwardTo(), actual.getForwardTo()); + assertEquals(expected.getForwardDeadLetteredMessagesTo(), actual.getForwardDeadLetteredMessagesTo()); + } + } + + //endregion + + @Test + void updateRuleResponse() { + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = testResourceNamer.randomName("rule", 15); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + final SqlRuleAction expectedAction = new SqlRuleAction("SET MessageId = 'matching-id'"); + final SqlRuleFilter expectedFilter = new SqlRuleFilter("sys.To = 'telemetry-event'"); + + final RuleProperties existingRule = client.createRule(topicName, subscriptionName, ruleName); + assertNotNull(existingRule); + + existingRule.setAction(expectedAction).setFilter(expectedFilter); + + final RuleProperties rule = client.updateRule(topicName, subscriptionName, existingRule); + assertNotNull(rule); + assertEquals(ruleName, rule.getName()); + + assertTrue(rule.getFilter() instanceof SqlRuleFilter); + assertEquals(expectedFilter.getSqlExpression(), + ((SqlRuleFilter) rule.getFilter()).getSqlExpression()); + + assertTrue(rule.getAction() instanceof SqlRuleAction); + assertEquals(expectedAction.getSqlExpression(), + ((SqlRuleAction) rule.getAction()).getSqlExpression()); + } + + //region Get and exists tests + + @Test + void getNamespace() { + final ServiceBusAdministrationClient client = getClient(); + + final NamespaceProperties namespaceProperties = client.getNamespaceProperties(); + assertEquals(NamespaceType.MESSAGING, namespaceProperties.getNamespaceType()); + if (!interceptorManager.isPlaybackMode()) { + final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); + assertEquals(split[0], namespaceProperties.getName()); + } + } + + @Test + void getQueue() { + final ServiceBusAdministrationClient client = getClient(); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + final QueueProperties queueProperties = client.getQueue(queueName); + assertEquals(queueName, queueProperties.getName()); + + assertFalse(queueProperties.isPartitioningEnabled()); + assertFalse(queueProperties.isSessionRequired()); + assertNotNull(queueProperties.getLockDuration()); + + final QueueRuntimeProperties runtimeProperties = new QueueRuntimeProperties(queueProperties); + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + } + + @Test + void getQueueDoesNotExist() { + final ServiceBusAdministrationClient client = getClient(); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); + + assertThrows(ResourceNotFoundException.class, () -> client.getQueue(queueName), + "Queue exists! But should not. Incorrect getQueue behavior"); + } + + @Test + void getQueueExists() { + final ServiceBusAdministrationClient client = getClient(); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); + + assertTrue(client.getQueueExists(queueName)); + } + + @Test + void getQueueExistsFalse() { + final ServiceBusAdministrationClient client = getClient(); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); + + assertFalse(client.getQueueExists(queueName)); + } + + @Test + void getQueueRuntimeProperties() { + final ServiceBusAdministrationClient client = getClient(); + final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + final QueueRuntimeProperties runtimeProperties = client.getQueueRuntimeProperties(queueName); + assertEquals(queueName, runtimeProperties.getName()); + + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + } + + @Test + void getTopic() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + final TopicProperties topicProperties = client.getTopic(topicName); + assertEquals(topicName, topicProperties.getName()); + + assertTrue(topicProperties.isBatchedOperationsEnabled()); + assertFalse(topicProperties.isDuplicateDetectionRequired()); + assertNotNull(topicProperties.getDuplicateDetectionHistoryTimeWindow()); + assertNotNull(topicProperties.getDefaultMessageTimeToLive()); + assertFalse(topicProperties.isPartitioningEnabled()); + + final TopicRuntimeProperties runtimeProperties = new TopicRuntimeProperties(topicProperties); + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + } + + @Test + void getTopicDoesNotExist() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = testResourceNamer.randomName("topic", 10); + + assertThrows(ResourceNotFoundException.class, () -> client.getTopic(topicName), + "Topic exists! But should not. Incorrect getTopic behavior"); + } + + @Test + void getTopicExists() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + + assertTrue(client.getTopicExists(topicName)); + } + + @Test + void getTopicExistsFalse() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = testResourceNamer.randomName(getTopicBaseName(), 10); + + assertFalse(client.getTopicExists(topicName)); + } + + @Test + void getTopicRuntimeProperties() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + final TopicRuntimeProperties runtimeProperties = client.getTopicRuntimeProperties(topicName); + assertEquals(topicName, runtimeProperties.getName()); + + assertTrue(runtimeProperties.getSubscriptionCount() >= 1); + + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getAccessedAt())); + assertEquals(0, runtimeProperties.getScheduledMessageCount()); + } + + @Test + void getSubscription() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + final SubscriptionProperties properties = client.getSubscription(topicName, subscriptionName); + assertEquals(topicName, properties.getTopicName()); + assertEquals(subscriptionName, properties.getSubscriptionName()); + + assertFalse(properties.isSessionRequired()); + assertNotNull(properties.getLockDuration()); + + final SubscriptionRuntimeProperties runtimeProperties = new SubscriptionRuntimeProperties(properties); + assertNotNull(runtimeProperties.getCreatedAt()); + assertTrue(nowUtc.isAfter(runtimeProperties.getCreatedAt())); + assertNotNull(runtimeProperties.getAccessedAt()); + } + + @Test + void getSubscriptionDoesNotExist() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); + + assertThrows(ResourceNotFoundException.class, () -> client.getSubscription(topicName, subscriptionName), + "Subscription exists! But should not. Incorrect getSubscription behavior"); + } + + @Test + void getSubscriptionExists() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + + assertTrue(client.getSubscriptionExists(topicName, subscriptionName)); + } + + @Test + void getSubscriptionExistsFalse() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 1); + final String subscriptionName = "subscription-session-not-exist"; + + // Act + boolean response = client.getSubscriptionExists(topicName, subscriptionName); + + // Assert + assertFalse(response); + } + + @Test + void getSubscriptionRuntimeProperties() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + final OffsetDateTime nowUtc = OffsetDateTime.now(Clock.systemUTC()); + + final SubscriptionRuntimeProperties properties = client.getSubscriptionRuntimeProperties(topicName, subscriptionName); + assertEquals(topicName, properties.getTopicName()); + assertEquals(subscriptionName, properties.getSubscriptionName()); + + assertTrue(properties.getTotalMessageCount() >= 0); + assertEquals(0, properties.getActiveMessageCount()); + assertEquals(0, properties.getTransferDeadLetterMessageCount()); + assertEquals(0, properties.getTransferMessageCount()); + assertTrue(properties.getDeadLetterMessageCount() >= 0); + + assertNotNull(properties.getCreatedAt()); + assertTrue(nowUtc.isAfter(properties.getCreatedAt())); + assertNotNull(properties.getAccessedAt()); + } + + @Test + void getSubscriptionRuntimePropertiesUnauthorizedClient() { + final String connectionString = interceptorManager.isPlaybackMode() + ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" + : TestUtils.getConnectionString(false); + + final String connectionStringUpdated = connectionString.replace("SharedAccessKey=", + "SharedAccessKey=fake-key-"); + + final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() + .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) + .connectionString(connectionStringUpdated); + + if (interceptorManager.isPlaybackMode()) { + builder.httpClient(interceptorManager.getPlaybackClient()); + } else if (!interceptorManager.isLiveMode()) { + builder.addPolicy(interceptorManager.getRecordPolicy()); + } + + final ServiceBusAdministrationClient client = builder.buildClient(); + + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getEntityName(getSubscriptionBaseName(), 2); + + ClientAuthenticationException exception = assertThrows(ClientAuthenticationException.class, + () -> client.getSubscriptionRuntimeProperties(topicName, subscriptionName), + "Subscription runtime properties accessible by unauthorized client! This should not be possible."); + } + + @Test + void getRule() { + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = "$Default"; + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + + final Response response = client.getRuleWithResponse(topicName, subscriptionName, ruleName, null); + assertEquals(200, response.getStatusCode()); + + final RuleProperties contents = response.getValue(); + + assertNotNull(contents); + assertEquals(ruleName, contents.getName()); + assertNotNull(contents.getFilter()); + assertTrue(contents.getFilter() instanceof SqlRuleFilter); + + assertNotNull(contents.getAction()); + assertTrue(contents.getAction() instanceof EmptyRuleAction); + } + + @Test + void getRuleDoesNotExist() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = "does-not-exist-rule"; + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + assertThrows(ResourceNotFoundException.class, + () -> client.getRuleWithResponse(topicName, subscriptionName, ruleName, Context.NONE)); + } + + //endregion + + //region Delete tests + + @Test + void deleteQueue() { + final ServiceBusAdministrationClient client = getClient(); + final String queueName = testResourceNamer.randomName("queue", 10); + + client.createQueue(queueName); + client.deleteQueue(queueName); + } + + + @Test + void deleteQueueDoesNotExist() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String queueName = testResourceNamer.randomName("queue", 10); + + // Act & Assert + assertThrows(ResourceNotFoundException.class, () -> client.deleteQueue(queueName)); + } + + @Test + void deleteRule() { + final ServiceBusAdministrationClient client = getClient(); + final String ruleName = getEntityName(getRuleBaseName(), 9); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + client.createRule(topicName, subscriptionName, ruleName); + + client.deleteRule(topicName, subscriptionName, ruleName); + } + + @Test + void deleteRuleDoesNotExist() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String ruleName = testResourceNamer.randomName("rule-", 11); + final String topicName = getEntityName(getTopicBaseName(), 13); + final String subscriptionName = getSubscriptionBaseName(); + + // Act & Assert + assertThrows(ResourceNotFoundException.class, () -> client.deleteRule(topicName, subscriptionName, ruleName)); + } + + @Test + void deleteSubscription() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = testResourceNamer.randomName(getSubscriptionBaseName(), 10); + + client.createSubscription(topicName, subscriptionName); + + client.deleteSubscription(topicName, subscriptionName); + } + + @Test + void deleteSubscriptionDoesNotExist() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String topicName = testResourceNamer.randomName("topic", 10); + final String subscriptionName = testResourceNamer.randomName("sub", 7); + + // The topic exists but the subscription does not. + client.createTopic(topicName); + + // Act & Assert + assertThrows(ResourceNotFoundException.class, () -> client.deleteSubscription(topicName, subscriptionName)); + } + + @Test + void deleteTopic() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = testResourceNamer.randomName("topic", 10); + + client.createTopic(topicName); + client.deleteTopic(topicName); + } + + @Test + void deleteTopicDoesNotExist() { + // Arrange + final ServiceBusAdministrationClient client = getClient(); + final String topicName = testResourceNamer.randomName("topic", 10); + + // Act & Assert + assertThrows(ResourceNotFoundException.class, () -> client.deleteTopic(topicName)); + } + + //endregion + + //region List tests + + @Test + void listQueues() { + final ServiceBusAdministrationClient client = getClient(); + + PagedIterable queueProperties = client.listQueues(); + queueProperties.forEach(queueDescription -> { + assertNotNull(queueDescription.getName()); + assertTrue(queueDescription.getMaxDeliveryCount() > 0); + assertSame(queueDescription.getStatus(), EntityStatus.ACTIVE); + }); + assertTrue(queueProperties.stream().findAny().isPresent()); + } + + @Test + void listTopics() { + final ServiceBusAdministrationClient client = getClient(); + + PagedIterable topics = client.listTopics(); + topics.forEach(topicProperties -> { + assertNotNull(topicProperties.getName()); + assertTrue(topicProperties.isBatchedOperationsEnabled()); + assertFalse(topicProperties.isPartitioningEnabled()); + }); + assertTrue(topics.stream().count() > 1); + } + + @Test + void listSubscriptions() { + final ServiceBusAdministrationClient client = getClient(); + final String topicName = getEntityName(getTopicBaseName(), 2); + + PagedIterable subscriptionProperties = client.listSubscriptions(topicName); + subscriptionProperties.forEach(subscription -> { + assertEquals(topicName, subscription.getTopicName()); + assertNotNull(subscription.getSubscriptionName()); + }); + assertTrue(subscriptionProperties.stream().findAny().isPresent()); + } + + @Test + void listRules() { + final ServiceBusAdministrationClient client = getClient(); + + final String ruleName = "$Default"; + final String topicName = getEntityName(getTopicBaseName(), 2); + final String subscriptionName = getSubscriptionBaseName(); + + PagedIterable ruleProperties = client.listRules(topicName, subscriptionName); + + assertTrue(ruleProperties.stream().findAny().isPresent()); + Optional ruleOptional = ruleProperties.stream() + .filter(rule1 -> rule1.getName().equals(ruleName)).findFirst(); + assertTrue(ruleOptional.isPresent()); + RuleProperties rule = ruleOptional.get(); + + assertEquals(ruleName, rule.getName()); + assertNotNull(rule.getFilter()); + assertTrue(rule.getFilter() instanceof SqlRuleFilter); + assertNotNull(rule.getAction()); + assertTrue(rule.getAction() instanceof EmptyRuleAction); + } //endregion From 73a11aa4d22efd821b0cba798bf17f60c1079c71 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 09:58:40 -0700 Subject: [PATCH 04/29] try removing the keys in tests.yml --- sdk/servicebus/tests.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sdk/servicebus/tests.yml b/sdk/servicebus/tests.yml index 74e5e7b206e7..9be1da120763 100644 --- a/sdk/servicebus/tests.yml +++ b/sdk/servicebus/tests.yml @@ -16,10 +16,6 @@ extends: SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources) EnvVars: AZURE_LOG_LEVEL: 1 - AZURE_CLIENT_ID: $(SERVICEBUS_CLIENT_ID) - AZURE_TENANT_ID: $(SERVICEBUS_TENANT_ID) - AZURE_CLIENT_SECRET: $(SERVICEBUS_CLIENT_SECRET) - AZURE_SUBSCRIPTION_ID: $(SERVICEBUS_SUBSCRIPTION_ID) AdditionalMatrixConfigs: - Name: version_overrides_tests Path: sdk/servicebus/version-overrides-matrix.json From ff2246f8134829b48520f997e9eacb608e7fd2d5 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 10:34:42 -0700 Subject: [PATCH 05/29] Enable ServiceBus[Sender|Receiver][Async]ClientIntegrationTest --- .../servicebus/IntegrationTestBase.java | 1 + ...BusReceiverAsyncClientIntegrationTest.java | 2864 ++++++++--------- ...rviceBusReceiverClientIntegrationTest.java | 1787 +++++----- ...ceBusSenderAsyncClientIntegrationTest.java | 1103 ++++--- ...ServiceBusSenderClientIntegrationTest.java | 409 ++- 5 files changed, 3061 insertions(+), 3103 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index a64999906790..6be95449ed5f 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -220,6 +220,7 @@ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { .scheduler(scheduler) .configuration(v1OrV2(true)); + System.out.println("Getting Builder using credentials : " + useCredentials); logger.info("Getting Builder using credentials : [{}] ", useCredentials); if (useCredentials) { final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index 4804a45c7ef6..7e649c5a82d0 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -4,74 +4,69 @@ package com.azure.messaging.servicebus; import com.azure.core.amqp.AmqpRetryOptions; -//import com.azure.core.amqp.models.AmqpAddress; -//import com.azure.core.amqp.models.AmqpAnnotatedMessage; -//import com.azure.core.amqp.models.AmqpMessageBody; -//import com.azure.core.amqp.models.AmqpMessageBodyType; -//import com.azure.core.amqp.models.AmqpMessageHeader; -//import com.azure.core.amqp.models.AmqpMessageId; -//import com.azure.core.amqp.models.AmqpMessageProperties; -//import com.azure.core.util.CoreUtils; -import com.azure.core.credential.AccessToken; -import com.azure.core.credential.TokenRequestContext; +import com.azure.core.amqp.models.AmqpAddress; +import com.azure.core.amqp.models.AmqpAnnotatedMessage; +import com.azure.core.amqp.models.AmqpMessageBody; +import com.azure.core.amqp.models.AmqpMessageBodyType; +import com.azure.core.amqp.models.AmqpMessageHeader; +import com.azure.core.amqp.models.AmqpMessageId; +import com.azure.core.amqp.models.AmqpMessageProperties; +import com.azure.core.util.CoreUtils; import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.implementation.DispositionStatus; -import com.azure.identity.AzurePowerShellCredential; -import com.azure.identity.AzurePowerShellCredentialBuilder; +import com.azure.messaging.servicebus.implementation.DispositionStatus; import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import com.azure.messaging.servicebus.models.AbandonOptions; -//import com.azure.messaging.servicebus.models.CompleteOptions; -//import com.azure.messaging.servicebus.models.DeadLetterOptions; -//import com.azure.messaging.servicebus.models.DeferOptions; -//import com.azure.messaging.servicebus.models.SubQueue; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.Disabled; -import com.azure.messaging.servicebus.implementation.ServiceBusConstants; +import com.azure.messaging.servicebus.models.AbandonOptions; +import com.azure.messaging.servicebus.models.CompleteOptions; +import com.azure.messaging.servicebus.models.DeadLetterOptions; +import com.azure.messaging.servicebus.models.DeferOptions; +import com.azure.messaging.servicebus.models.SubQueue; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.EnumSource; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.core.Disposable; -//import reactor.core.publisher.Flux; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -//import reactor.test.StepVerifier; +import reactor.test.StepVerifier; -//import java.nio.charset.Charset; +import java.nio.charset.Charset; import java.time.Duration; -//import java.time.OffsetDateTime; -//import java.util.ArrayList; -//import java.util.Collections; -//import java.util.Comparator; -//import java.util.HashMap; -//import java.util.HashSet; -//import java.util.List; -//import java.util.Map; -//import java.util.Set; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.UUID; -//import java.util.concurrent.CountDownLatch; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.concurrent.atomic.AtomicLong; -//import java.util.concurrent.atomic.AtomicReference; -//import java.util.function.Function; -// -//import static com.azure.messaging.servicebus.TestUtils.MESSAGE_POSITION_ID; -//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_AUTO_COMPLETE; -//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH_MESSAGES; -//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_MESSAGE; -//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_RECEIVE_AND_COMPLETE; -//import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessages; -//import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; -//import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; -//import static java.nio.charset.StandardCharsets.UTF_8; -//import static org.junit.jupiter.api.Assertions.assertArrayEquals; -//import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +import static com.azure.messaging.servicebus.TestUtils.MESSAGE_POSITION_ID; +import static com.azure.messaging.servicebus.TestUtils.USE_CASE_AUTO_COMPLETE; +import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH_MESSAGES; +import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_MESSAGE; +import static com.azure.messaging.servicebus.TestUtils.USE_CASE_RECEIVE_AND_COMPLETE; +import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessages; +import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; +import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * Integration tests for {@link ServiceBusReceiverAsyncClient} from queues or subscriptions. @@ -103,1408 +98,1379 @@ protected void afterTest() { sharedBuilder = null; } - /** + /** * Verifies that we can create multiple transaction using sender and receiver. */ @Test void createMultipleTransactionTest() { - final AzurePowerShellCredential cred = new AzurePowerShellCredentialBuilder().build(); + // Arrange + setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); + + // Assert & Act + StepVerifier.create(receiver.createTransaction()) + .assertNext(Assertions::assertNotNull) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(receiver.createTransaction()) + .assertNext(Assertions::assertNotNull) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can create transaction and complete. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Assert & Act + AtomicReference transaction = new AtomicReference<>(); + StepVerifier.create(receiver.createTransaction()) + .assertNext(txn -> { + transaction.set(txn); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(receiver.receiveMessages() + .flatMap(receivedMessage -> { + logMessage(receivedMessage, receiver.getEntityPath(), "received message"); + return receiver.complete(receivedMessage) + .doOnSuccess(m -> logMessage(receivedMessage, receiver.getEntityPath(), "completed message")) + .thenReturn(receivedMessage); + }).take(1)) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(receiver.rollbackTransaction(transaction.get())) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can do following using shared connection and on non session entity. 1. create transaction 2. + * receive and settle with transactionContext. 3. commit Rollback this transaction. + */ + @ParameterizedTest + @EnumSource(DispositionStatus.class) + void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { + + // Arrange + final MessagingEntityType entityType = MessagingEntityType.QUEUE; + setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_TRANSACTION_SENDRECEIVE_AND_COMPLETE, isSessionEnabled); + + final String messageId1 = UUID.randomUUID().toString(); + final ServiceBusMessage message1 = getMessage(messageId1, isSessionEnabled); + final String deadLetterReason = "test reason"; + + sendMessage(message1).block(TIMEOUT); + + // Assert & Act + AtomicReference transaction = new AtomicReference<>(); + StepVerifier.create(receiver.createTransaction()) + .assertNext(txn -> { + transaction.set(txn); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + assertNotNull(transaction.get()); + + // Assert & Act + final ServiceBusReceivedMessage message = receiver.receiveMessages() + .flatMap(receivedMessage -> { + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + final Mono operation; + switch (dispositionStatus) { + case COMPLETED: + operation = receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get())); + logMessage(receivedMessage, receiver.getEntityPath(), "completed messages"); + break; + case ABANDONED: + operation = receiver.abandon(receivedMessage, new AbandonOptions().setTransactionContext(transaction.get())); + logMessage(receivedMessage, receiver.getEntityPath(), "abandoned messages"); + break; + case SUSPENDED: + DeadLetterOptions deadLetterOptions = new DeadLetterOptions().setTransactionContext(transaction.get()) + .setDeadLetterReason(deadLetterReason); + operation = receiver.deadLetter(receivedMessage, deadLetterOptions); + logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered messages"); + break; + case DEFERRED: + operation = receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction.get())); + logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); + break; + case RELEASED: + operation = receiver.release(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "released messages"); + break; + default: + throw LOGGER.logExceptionAsError(new IllegalArgumentException( + "Disposition status not recognized for this test case: " + dispositionStatus)); + } + return operation + .thenReturn(receivedMessage); + }) + .blockFirst(TIMEOUT); + assertNotNull(message); + + StepVerifier.create(receiver.commitTransaction(transaction.get())) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can do following on different clients i.e. sender and receiver. 1. create transaction using + * sender 2. receive and complete with transactionContext. 3. Commit this transaction using sender. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + @Disabled + void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { + // Arrange + final boolean shareConnection = true; + final int entityIndex = 0; + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + .buildAsyncClient()); + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + .buildAsyncClient()); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(TIMEOUT); + + // Assert & Act + AtomicReference transaction = new AtomicReference<>(); + StepVerifier.create(sender.createTransaction()) + .assertNext(txn -> { + transaction.set(txn); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + assertNotNull(transaction.get()); + + // Assert & Act + final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); + assertNotNull(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "received message"); + StepVerifier.create(receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get()))) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(sender.commitTransaction(transaction.get())) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send and receive two messages. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int entityIndex = 0; + final boolean shareConnection = false; + final Duration shortWait = Duration.ofSeconds(3); + + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + .buildAsyncClient()); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + Mono.when(sendMessage(message), sendMessage(message)).block(); + + // Now create receiver + if (isSessionEnabled) { + assertNotNull(sessionId, "'sessionId' should have been set."); + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + .buildAsyncClient()); + this.receiver = toClose(sessionReceiver.acceptSession(sessionId).block()); + } else { + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + .buildAsyncClient()); + } + + // Assert & Act + StepVerifier.create(receiver.receiveMessages() + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .thenAwait(shortWait) // Give time for autoComplete to finish + .thenCancel() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send and receive a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int entityIndex = USE_CASE_AUTO_COMPLETE; + final boolean shareConnection = false; + + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + .buildAsyncClient()); + final String messageId = CoreUtils.randomUuid().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + StepVerifier.create(sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + + // Now create receiver + if (isSessionEnabled) { + assertNotNull(sessionId, "'sessionId' should have been set."); + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + .buildAsyncClient()); + this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); + } else { + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + .buildAsyncClient()); + } + + // Assert + StepVerifier.create(receiver.receiveMessages() + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) + .assertNext(receivedMessage -> { + logMessage(receivedMessage, receiver.getEntityPath(), "received message"); + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + }) + .expectNoEvent(Duration.ofSeconds(30)) + .thenCancel() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send and peek a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + @Disabled("Investigate: Could not emit tick 0 due to lack of requests (interval doesn't support small downstream requests that replenish slower than the ticks)))") + void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(); + + setReceiver(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); + + Mono peek = receiver.peekMessage() + .filter(m -> messageId.equals(m.getMessageId())) + .repeatWhenEmpty(10, i -> Flux.interval(Duration.ofSeconds(1))); + + // Assert & Act + StepVerifier.create(peek + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked and filtered message"))) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that an empty entity does not error when peeking. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); + + final int fromSequenceNumber = 1; + + // Assert & Act + StepVerifier.create(receiver.peekMessage(fromSequenceNumber) + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can schedule and receive a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); + final Duration shortDelay = Duration.ofSeconds(4); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(2); + + sender.scheduleMessage(message, scheduledEnqueueTime).block(); + + setReceiver(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); + + // Assert & Act + StepVerifier.create(Mono.delay(shortDelay).then(receiver.receiveMessages() + .filter(m -> messageId.equals(m.getMessageId())) + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) + .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).next())) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can cancel a scheduled message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); + final Duration delayDuration = Duration.ofSeconds(3); + + final Long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime).block(TIMEOUT); + logMessage(message, sender.getEntityPath(), "scheduled"); + + assertNotNull(sequenceNumber); + + Mono.delay(delayDuration) + .then(sender.cancelScheduledMessage(sequenceNumber)) + .block(TIMEOUT); + + logMessage(message, sender.getEntityPath(), "cancelled messaged with sequence number " + sequenceNumber); + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Assert & Act + StepVerifier.create(receiver.receiveMessages() + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) + .take(1)) + .thenAwait(Duration.ofSeconds(5)) + .thenCancel() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send and peek a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int entityIndex = 3; + + setSender(entityType, entityIndex, isSessionEnabled); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final CountDownLatch countDownLatch = new CountDownLatch(1); + + sendMessage(message).block(); + + setReceiver(entityType, entityIndex, isSessionEnabled); + + // Message are not always guaranteed, so try many times + final ServiceBusReceivedMessage peekMessage = receiver.peekMessage() + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) + .map(receivedMessage -> { + countDownLatch.countDown(); + return receivedMessage; + }) + .repeat(() -> countDownLatch.getCount() > 0) + .next() + .block(); + assertNotNull(peekMessage); + final long sequenceNumber = peekMessage.getSequenceNumber(); + + // Assert & Act try { - System.out.println("Using AzurePowerShellCredential"); - AccessToken c = cred.getToken(new TokenRequestContext().addScopes(ServiceBusConstants.AZURE_ACTIVE_DIRECTORY_SCOPE)).block(); - System.out.println("Expire At:" + c.getExpiresAt()); - } catch (Exception e) { - System.out.println("Error:" + e.getMessage()); - e.printStackTrace(); + StepVerifier.create(receiver.peekMessage(sequenceNumber) + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) + .assertNext(m -> { + assertEquals(sequenceNumber, m.getSequenceNumber()); + assertMessageEquals(m, messageId, isSessionEnabled); + }) + .expectComplete() + .verify(TIMEOUT); + } finally { + + // Cleanup + StepVerifier.create(receiver.receiveMessages() + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) + .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) + .expectNextCount(1) + .expectComplete() + .verify(TIMEOUT); } + } + /** + * Verifies that we can send and peek a batch of messages and the sequence number is tracked correctly. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + public void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange -// setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.createTransaction()) -// .assertNext(Assertions::assertNotNull) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(receiver.createTransaction()) -// .assertNext(Assertions::assertNotNull) -// .expectComplete() -// .verify(TIMEOUT); + setSender(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final List messages = getServiceBusMessages(10, messageId, CONTENTS_BYTES); + final Set receivedPositions = Collections.synchronizedSet(new HashSet<>()); + final List receivedMessages = Collections.synchronizedList(new ArrayList<>()); + + if (isSessionEnabled) { + messages.forEach(m -> m.setSessionId(sessionId)); + } + + StepVerifier.create(sender.sendMessages(messages) + .doOnSuccess(aVoid -> logMessages(messages, sender.getEntityPath(), "sent"))) + .expectComplete() + .verify(TIMEOUT); + + setReceiver(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); + + // Assert & Act + for (int i = 0; i < 5 && receivedPositions.size() < messages.size(); i++) { + peekMessages(messages.size(), messageId, receivedPositions) + .doOnNext(receivedMessage -> receivedMessages.add(receivedMessage)) + .blockLast(); + if (receivedPositions.size() < messages.size()) { + Thread.sleep(1000); + } + } + + assertEquals(receivedMessages.size(), messages.size()); + + final AtomicInteger messageCount = new AtomicInteger(); + + synchronized (receivedMessages) { + receivedMessages.stream() + .forEach(actualMessage -> { + final Object position = actualMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); + assertTrue(position instanceof Integer, "Did not contain correct position number: " + position); + + // messages are received in the same order as they were sent + assertEquals(messageCount.getAndIncrement(), position); + }); + } + } + + private Flux peekMessages(int count, String messageIdFilter, Set receivedPositions) { + return receiver.peekMessages(count) + // maxMessages are not always guaranteed, sometime, we get less than asked for, so we will try many times. + .filter(receivedMessage -> { + logMessage(receivedMessage, receiver.getEntityPath(), "peeked message"); + Integer position = (Integer) receivedMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); + boolean filtered = messageIdFilter.equals(receivedMessage.getMessageId()) && receivedPositions.add(position); + if (filtered) { + logMessage(receivedMessage, receiver.getEntityPath(), "filtered message, a few more to go"); + } + return filtered; + }); + } + + /** + * Verifies that we can send and peek a batch of messages. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void peekMessagesFromSequence(MessagingEntityType entityType) throws InterruptedException { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_MESSAGE_FROM_SEQUENCE, false); + + final AtomicInteger messageId = new AtomicInteger(); + final int maxMessages = 2; + final AtomicLong fromSequenceNumber = new AtomicLong(); + final CountDownLatch countdownLatch = new CountDownLatch(maxMessages); + fromSequenceNumber.set(1); + + final byte[] content = "peek-message-from-sequence".getBytes(Charset.defaultCharset()); + List messageIds = Collections.synchronizedList(new ArrayList<>()); + for (int i = 0; i < maxMessages; ++i) { + ServiceBusMessage message = getMessage(String.valueOf(i), isSessionEnabled, AmqpMessageBody.fromData(content)); + messageIds.add(String.valueOf(i)); + sendMessage(message).block(); + } + + // Assert & Act + + // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times + // https://github.com/Azure/azure-sdk-for-java/issues/21168 + List receivedMessages = Collections.synchronizedList(new ArrayList<>()); + Disposable subscription = receiver.peekMessages(maxMessages, fromSequenceNumber.get()) + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message")) + .filter(receivedMessage -> messageIds.contains(receivedMessage.getMessageId()) + && receivedMessages.parallelStream().noneMatch(mid -> + mid.equals(receivedMessage.getMessageId()))) + .sort(Comparator.comparing(ServiceBusReceivedMessage::getMessageId)) + .flatMap(receivedMessage -> { + Long previousSequenceNumber = fromSequenceNumber.get(); + fromSequenceNumber.set(receivedMessage.getSequenceNumber() + 1); + countdownLatch.countDown(); + receivedMessages.add(receivedMessage.getMessageId()); + assertEquals(String.valueOf(messageId.getAndIncrement()), receivedMessage.getMessageId(), + String.format("Message id did not match. Message payload: [%s], peek from Sequence Number [%s], " + + " received message Sequence Number [%s]", receivedMessage.getBody(), + previousSequenceNumber, receivedMessage.getSequenceNumber())); + return Mono.just(receivedMessage); + }) + .repeat(() -> countdownLatch.getCount() > 0) + .subscribe(); + toClose(subscription); + + assertTrue(countdownLatch.await(20, TimeUnit.SECONDS), "Failed peek messages from sequence."); + + StepVerifier.create(receiver.receiveMessages().take(maxMessages)) + .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) + .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that an empty entity does not error when peeking. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); + + final int maxMessages = 10; + final int fromSequenceNumber = 1; + + // Assert & Act + StepVerifier.create(receiver.peekMessages(maxMessages, fromSequenceNumber)) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can dead-letter a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int entityIndex = 0; + setSender(entityType, entityIndex, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(); + + setReceiver(entityType, entityIndex, isSessionEnabled); + + // Assert & Act + StepVerifier.create(receiver.receiveMessages() + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) + .flatMap(receivedMessage -> receiver.deadLetter(receivedMessage).thenReturn(receivedMessage)).take(1)) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .thenCancel() + .verify(TIMEOUT); + + } + + /** + * Verifies that we can send and receive a message AMQP Sequence andValue object. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; + final boolean shareConnection = false; + final Duration shortWait = Duration.ofSeconds(3); + final Long expectedLongValue = Long.parseLong("6"); + + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + .buildAsyncClient()); + + // Send value Object + String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromValue(expectedLongValue)); + sendMessage(message).block(TIMEOUT); + + // send SEQUENCE + messageId = UUID.randomUUID().toString(); + + List sequenceData = new ArrayList<>(); + sequenceData.add("A1"); + sequenceData.add(1L); + sequenceData.add(2); + + message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromSequence(sequenceData)); + sendMessage(message).block(TIMEOUT); + + // Now create receiver + if (isSessionEnabled) { + assertNotNull(sessionId, "'sessionId' should have been set."); + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + .buildAsyncClient()); + this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); + } else { + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + .buildAsyncClient()); + } + + // Assert + StepVerifier.create(receiver.receiveMessages()) + .assertNext(receivedMessage -> { + AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); + AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); + assertEquals(AmqpMessageBodyType.VALUE, type); + Object value = amqpAnnotatedMessage.getBody().getValue(); + assertTrue(value instanceof Long); + assertEquals(expectedLongValue.longValue(), ((Long) value).longValue()); + }) + .assertNext(receivedMessage -> { + AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); + AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); + assertEquals(AmqpMessageBodyType.SEQUENCE, type); + assertArrayEquals(sequenceData.toArray(), amqpAnnotatedMessage.getBody().getSequence().toArray()); + }) + .thenAwait(shortWait) // Give time for autoComplete to finish + .thenCancel() + .verify(TIMEOUT); + + if (!isSessionEnabled) { + StepVerifier.create(receiver.receiveMessages()) + .thenAwait(shortWait) + .thenCancel() + .verify(TIMEOUT); + } + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(TIMEOUT); + + setReceiver(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); + + // Assert & Act + StepVerifier.create(receiver.receiveMessages() + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) + .doOnNext(receivedMessage -> logMessage(receivedMessage, receiver.getEntityPath(), "received and filtered")) + .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can renew message lock on a non-session receiver. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void receiveAndRenewLock(MessagingEntityType entityType) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + + // Blocking here because it is not part of the scenario we want to test. + sendMessage(message).block(TIMEOUT); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); + + final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); + assertNotNull(receivedMessage); + assertNotNull(receivedMessage.getLockedUntil()); + + final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); + LOGGER.info("Received message. Seq: {}. lockedUntil: {}", receivedMessage.getSequenceNumber(), initialLock); + + // Assert & Act + try { + StepVerifier.create(Mono.delay(Duration.ofSeconds(7)) + .then(Mono.defer(() -> receiver.renewMessageLock(receivedMessage)))) + .assertNext(lockedUntil -> assertTrue(lockedUntil.isAfter(initialLock), + String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", + lockedUntil, initialLock))) + .expectComplete() + .verify(TIMEOUT); + } finally { + LOGGER.info("Completing message. Seq: {}.", receivedMessage.getSequenceNumber()); + + receiver.complete(receivedMessage) + .doOnNext(m -> logMessage(receivedMessage, receiver.getEntityPath(), "complete")) + .block(TIMEOUT); + } + } + + /** + * Receiver should receive the messages even if user is not "settling the messages" in PEEK LOCK mode and + * autoComplete is disabled. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int totalMessages = 5; + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Send messages + final String messageId = UUID.randomUUID().toString(); + final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); + if (isSessionEnabled) { + messages.forEach(m -> m.setSessionId(sessionId)); + } + sender.sendMessages(messages).block(TIMEOUT); + logMessages(messages, sender.getEntityPath(), "sent messages"); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Assert & Act + StepVerifier.create(receiver.receiveMessages().take(totalMessages)) + .expectNextCount(totalMessages) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Receiver should receive the messages if processing time larger than message lock duration and + * maxAutoLockRenewDuration is set to a large enough duration so user can complete in end. + * This test takes longer time. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final int totalMessages = 2; + // The lock timeout property set on the queue. + final Duration lockRenewTimeout = Duration.ofSeconds(15); + final ClientCreationOptions clientCreationOptions = new ClientCreationOptions().setMaxAutoLockRenewDuration(Duration.ofMinutes(1)); + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Send messages + final String messageId = UUID.randomUUID().toString(); + final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); + if (isSessionEnabled) { + messages.forEach(m -> m.setSessionId(sessionId)); + } + sender.sendMessages(messages).block(); + logMessages(messages, sender.getEntityPath(), "sent messages"); + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled, clientCreationOptions); + + // Assert & Act + StepVerifier.create(receiver.receiveMessages() + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) + .map(receivedMessage -> Mono.delay(lockRenewTimeout.plusSeconds(2)) + .then(receiver.complete(receivedMessage)).thenReturn(receivedMessage).block()).take(totalMessages)) + .expectNextCount(totalMessages) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that the lock can be automatically renewed. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final AtomicInteger lockRenewCount = new AtomicInteger(); + + setSender(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + // Send the message to verify. + sendMessage(message).block(); + + setReceiver(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); + + // Act & Assert + StepVerifier.create(receiver.receiveMessages().flatMap(received -> { + LOGGER.info("{}: lockToken[{}]. lockedUntil[{}]. now[{}]", received.getSequenceNumber(), + received.getLockToken(), received.getLockedUntil(), OffsetDateTime.now()); + + // Simulate some sort of long processing. + while (lockRenewCount.get() < 4) { + lockRenewCount.incrementAndGet(); + LOGGER.info("Iteration {}: Curren time {}.", lockRenewCount.get(), OffsetDateTime.now()); + try { + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException error) { + LOGGER.error("Error occurred while sleeping: " + error); + } + } + return receiver.complete(received).thenReturn(received); + })) + .assertNext(received -> assertTrue(lockRenewCount.get() > 0)) + .thenCancel() + .verify(TIMEOUT); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(TIMEOUT); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + StepVerifier.create(receiver.receiveMessages() + .flatMap(receivedMessage -> receiver.abandon(receivedMessage).thenReturn(receivedMessage)).take(1)) + .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) + .expectComplete() + .verify(TIMEOUT); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(TIMEOUT); + + setReceiver(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); + AtomicReference received = new AtomicReference(); + + // Act & Assert + StepVerifier.create(receiver.receiveMessages() + .flatMap(receivedMessage -> receiver.defer(receivedMessage).thenReturn(receivedMessage)).take(1)) + .assertNext(m -> { + received.set(m); + assertMessageEquals(m, messageId, isSessionEnabled); + }) + .expectComplete() + .verify(TIMEOUT); + + // TODO(Hemant): Identify if this is valid scenario (https://github.com/Azure/azure-sdk-for-java/issues/19673) + /*receiver.receiveDeferredMessage(received.get().getSequenceNumber()) + .flatMap(m -> receiver.complete(m)) + .block(TIMEOUT); + messagesPending.decrementAndGet(); + */ + } + + /** + * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") + @ParameterizedTest + void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFERRED_MESSAGE_BY_SEQUENCE_NUMBER, false); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + StepVerifier.create(sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create( + receiver.receiveMessages() + .flatMap(m -> receiver.defer(m).thenReturn(m)) + .flatMap(received -> { + logMessage(received, receiver.getEntityPath(), "received and deferred"); + return receiver + .receiveDeferredMessage(received.getSequenceNumber()) + .flatMap(deferred -> { + logMessage(deferred, receiver.getEntityPath(), "received deferred"); + + assertNotNull(deferred); + assertEquals(received.getSequenceNumber(), deferred.getSequenceNumber()); + + switch (dispositionStatus) { + case ABANDONED: + logMessage(deferred, receiver.getEntityPath(), "abandon"); + return receiver.abandon(deferred).thenReturn(deferred); + case SUSPENDED: + logMessage(deferred, receiver.getEntityPath(), "deadLetter"); + return receiver.deadLetter(deferred).thenReturn(deferred); + case COMPLETED: + logMessage(deferred, receiver.getEntityPath(), "complete"); + return receiver.complete(deferred).thenReturn(deferred); + default: + throw LOGGER.logExceptionAsError(new IllegalArgumentException( + "Disposition status not recognized for this test case: " + dispositionStatus)); + } + }); + }) + .take(1)) + .expectNextCount(1) + .expectComplete() + .verify(TIMEOUT); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) { + // Arrange + final boolean isSessionEnabled = true; + setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); + Map sentProperties = messageToSend.getApplicationProperties(); + sentProperties.put("NullProperty", null); + sentProperties.put("BooleanProperty", true); + sentProperties.put("ByteProperty", (byte) 1); + sentProperties.put("ShortProperty", (short) 2); + sentProperties.put("IntProperty", 3); + sentProperties.put("LongProperty", 4L); + sentProperties.put("FloatProperty", 5.5f); + sentProperties.put("DoubleProperty", 6.6f); + sentProperties.put("CharProperty", 'z'); + sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); + sentProperties.put("StringProperty", "string"); + + sendMessage(messageToSend).block(TIMEOUT); + + setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); + + // Assert & Act + StepVerifier.create(receiver.receiveMessages().flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + + final Map received = receivedMessage.getApplicationProperties(); + + assertEquals(sentProperties.size(), received.size()); + + for (Map.Entry sentEntry : sentProperties.entrySet()) { + if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { + assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) received.get(sentEntry.getKey())); + } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { + final Object expected = sentEntry.getValue(); + final Object actual = received.get(sentEntry.getKey()); + + assertEquals(expected, actual, String.format( + "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, + actual)); + } + } + }) + .thenCancel() + .verify(TIMEOUT); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void setAndGetSessionState(MessagingEntityType entityType) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, true); + + final byte[] sessionState = "Finished".getBytes(UTF_8); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage messageToSend = getMessage(messageId, true); + + sendMessage(messageToSend).block(Duration.ofSeconds(10)); + + // Act + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, true); + + StepVerifier.create(receiver.receiveMessages() + .flatMap(message -> { + LOGGER.info("SessionId: {}. LockToken: {}. LockedUntil: {}. Message received.", + message.getSessionId(), message.getLockToken(), message.getLockedUntil()); + assertMessageEquals(message, messageId, isSessionEnabled); + return receiver.abandon(message) + .then(receiver.setSessionState(sessionState)) + .then(receiver.getSessionState()); + }) + .take(1)) + .assertNext(state -> { + LOGGER.info("State received: {}", new String(state, UTF_8)); + assertArrayEquals(sessionState, state); + }) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can receive a message from dead letter queue. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + final Duration shortWait = Duration.ofSeconds(2); + final int entityIndex = 0; + + if (isSessionEnabled && sessionId == null) { + sessionId = UUID.randomUUID().toString(); + } + + setSender(entityType, entityIndex, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message).block(); + + setReceiver(entityType, entityIndex, isSessionEnabled); + + receiver.receiveMessages() + .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) + .map(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + receiver.deadLetter(receivedMessage).block(); + return receivedMessage; + }).next().block(OPERATION_TIMEOUT); + + final ServiceBusReceiverAsyncClient deadLetterReceiver; + switch (entityType) { + case QUEUE: + final String queueName = isSessionEnabled ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); + assertNotNull(queueName, "'queueName' cannot be null."); + + deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() + .queueName(queueName) + .subQueue(SubQueue.DEAD_LETTER_QUEUE) + .buildAsyncClient()); + break; + case SUBSCRIPTION: + final String topicName = getTopicName(entityIndex); + final String subscriptionName = isSessionEnabled ? getSessionSubscriptionBaseName() : getSubscriptionBaseName(); + assertNotNull(topicName, "'topicName' cannot be null."); + assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); + + deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() + .topicName(topicName) + .subscriptionName(subscriptionName) + .subQueue(SubQueue.DEAD_LETTER_QUEUE) + .buildAsyncClient()); + break; + default: + throw LOGGER.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); + } + + // Assert & Act + try { + deadLetterReceiver.receiveMessages() + .filter(serviceBusReceivedMessage -> messageId.equals(serviceBusReceivedMessage.getMessageId())) + .map(serviceBusReceivedMessage -> { + assertMessageEquals(serviceBusReceivedMessage, messageId, isSessionEnabled); + return serviceBusReceivedMessage; + }) + .next() + .block(OPERATION_TIMEOUT); + } finally { + // close dead letter receiver. + deadLetterReceiver.close(); + } + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { + testRenewLock(entityType, Duration.ZERO, (m) -> { + toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); + return Mono.empty(); + }); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void autoRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { + testRenewLock(entityType, Duration.ofSeconds(10), (m) -> Mono.empty()); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void autoAndManualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { + testRenewLock(entityType, Duration.ofSeconds(10), (m) -> { + toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); + return Mono.empty(); + }); + } + + private void testRenewLock(MessagingEntityType entityType, Duration lockRenewalDuration, Function> renewMono) throws InterruptedException { + setSender(entityType, TestUtils.USE_CASE_RENEW_LOCK, false); + setReceiver(entityType, TestUtils.USE_CASE_RENEW_LOCK, false, new ClientCreationOptions() + .setMaxAutoLockRenewDuration(lockRenewalDuration)); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + + StepVerifier.create(sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + + AtomicReference lockedUntil = new AtomicReference<>(null); + + CountDownLatch latch = new CountDownLatch(2); + receiver.receiveMessages() + .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) + .filter(m -> messageId.equals(m.getMessageId())) + .flatMap(receivedMessage -> { + latch.countDown(); + logMessage(receivedMessage, receiver.getEntityPath(), "filtered message"); + LOGGER.atInfo() + .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) + .addKeyValue("seqNo", receivedMessage.getSequenceNumber()) + .addKeyValue("deliveryCount", receivedMessage.getDeliveryCount()) + .addKeyValue("lockToken", receivedMessage.getLockToken()) + .addKeyValue("lockedUntil", receivedMessage.getLockedUntil()) + .log("message properties"); + assertNotNull(receivedMessage.getLockedUntil()); + // expect to receive the same message but only after lock renewal completes + if (lockedUntil.compareAndSet(null, receivedMessage.getLockedUntil())) { + return renewMono.apply(receivedMessage); + } else { + // TODO: why not not always bigger than lockeduntil? time skew with service? + assertEquals(OffsetDateTime.now().toEpochSecond(), lockedUntil.get().toEpochSecond(), 10); + return receiver.complete(receivedMessage); + } + }) + .subscribe(i -> { }, ex -> fail(ex)); + + assertTrue(latch.await(2, TimeUnit.MINUTES)); + } + + @Test + @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") + void receiveTwice() { + setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + + StepVerifier.create(sendMessage(message)).verifyComplete(); + StepVerifier.create(receiver.receiveMessages().take(1)) + .expectNextCount(1) + .expectComplete() + .verify(OPERATION_TIMEOUT); + + StepVerifier.create(sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + + // cannot subscribe to the same receiver - there was a subscription that is disposed now + StepVerifier.create(receiver.receiveMessages().take(1)) + .expectComplete() + .verify(OPERATION_TIMEOUT); + } + + @Test + @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") + void receiveActiveSubscription() { + setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + + StepVerifier.create(sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + toClose(receiver.receiveMessages().subscribe(m -> { })); + + // cannot subscribe to the same receiver - there is active subscription + StepVerifier.create(receiver.receiveMessages().take(1)) + .expectError() + .verify(OPERATION_TIMEOUT); + } + + /** + * Verifies that we can receive a message which have different section set (i.e header, footer, annotations, + * application properties etc). + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void receiveAndValidateProperties(MessagingEntityType entityType) { + // Arrange + final boolean isSessionEnabled = false; + final int totalMessages = 1; + final String subject = "subject"; + final Map footer = new HashMap<>(); + footer.put("footer-key-1", "footer-value-1"); + footer.put("footer-key-2", "footer-value-2"); + + final Map applicationProperties = new HashMap<>(); + applicationProperties.put("ap-key-1", "ap-value-1"); + applicationProperties.put("ap-key-2", "ap-value-2"); + + final Map deliveryAnnotation = new HashMap<>(); + deliveryAnnotation.put("delivery-annotations-key-1", "delivery-annotations-value-1"); + deliveryAnnotation.put("delivery-annotations-key-2", "delivery-annotations-value-2"); + + final String messageId = UUID.randomUUID().toString(); + final AmqpAnnotatedMessage expectedAmqpProperties = new AmqpAnnotatedMessage( + AmqpMessageBody.fromData(CONTENTS_BYTES)); + expectedAmqpProperties.getProperties().setSubject(subject); + expectedAmqpProperties.getProperties().setReplyToGroupId("r-gid"); + expectedAmqpProperties.getProperties().setReplyTo(new AmqpAddress("reply-to")); + expectedAmqpProperties.getProperties().setContentType("content-type"); + expectedAmqpProperties.getProperties().setCorrelationId(new AmqpMessageId("correlation-id")); + expectedAmqpProperties.getProperties().setTo(new AmqpAddress("to")); + expectedAmqpProperties.getProperties().setAbsoluteExpiryTime(OffsetDateTime.now().plusSeconds(60)); + expectedAmqpProperties.getProperties().setUserId("user-id-1".getBytes()); + expectedAmqpProperties.getProperties().setContentEncoding("string"); + expectedAmqpProperties.getProperties().setGroupSequence(2L); + expectedAmqpProperties.getProperties().setCreationTime(OffsetDateTime.now().plusSeconds(30)); + + expectedAmqpProperties.getHeader().setPriority((short) 2); + expectedAmqpProperties.getHeader().setFirstAcquirer(true); + expectedAmqpProperties.getHeader().setDurable(true); + + expectedAmqpProperties.getFooter().putAll(footer); + expectedAmqpProperties.getDeliveryAnnotations().putAll(deliveryAnnotation); + expectedAmqpProperties.getApplicationProperties().putAll(applicationProperties); + + final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + + final AmqpAnnotatedMessage amqpAnnotatedMessage = message.getRawAmqpMessage(); + amqpAnnotatedMessage.getMessageAnnotations().putAll(expectedAmqpProperties.getMessageAnnotations()); + amqpAnnotatedMessage.getApplicationProperties().putAll(expectedAmqpProperties.getApplicationProperties()); + amqpAnnotatedMessage.getDeliveryAnnotations().putAll(expectedAmqpProperties.getDeliveryAnnotations()); + amqpAnnotatedMessage.getFooter().putAll(expectedAmqpProperties.getFooter()); + + final AmqpMessageHeader header = amqpAnnotatedMessage.getHeader(); + header.setFirstAcquirer(expectedAmqpProperties.getHeader().isFirstAcquirer()); + header.setTimeToLive(expectedAmqpProperties.getHeader().getTimeToLive()); + header.setDurable(expectedAmqpProperties.getHeader().isDurable()); + header.setDeliveryCount(expectedAmqpProperties.getHeader().getDeliveryCount()); + header.setPriority(expectedAmqpProperties.getHeader().getPriority()); + + final AmqpMessageProperties amqpMessageProperties = amqpAnnotatedMessage.getProperties(); + amqpMessageProperties.setReplyTo((expectedAmqpProperties.getProperties().getReplyTo())); + amqpMessageProperties.setContentEncoding((expectedAmqpProperties.getProperties().getContentEncoding())); + amqpMessageProperties.setAbsoluteExpiryTime((expectedAmqpProperties.getProperties().getAbsoluteExpiryTime())); + amqpMessageProperties.setSubject((expectedAmqpProperties.getProperties().getSubject())); + amqpMessageProperties.setContentType(expectedAmqpProperties.getProperties().getContentType()); + amqpMessageProperties.setCorrelationId(expectedAmqpProperties.getProperties().getCorrelationId()); + amqpMessageProperties.setTo(expectedAmqpProperties.getProperties().getTo()); + amqpMessageProperties.setGroupSequence(expectedAmqpProperties.getProperties().getGroupSequence()); + amqpMessageProperties.setUserId(expectedAmqpProperties.getProperties().getUserId()); + amqpMessageProperties.setAbsoluteExpiryTime(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime()); + amqpMessageProperties.setCreationTime(expectedAmqpProperties.getProperties().getCreationTime()); + amqpMessageProperties.setReplyToGroupId(expectedAmqpProperties.getProperties().getReplyToGroupId()); + + setSender(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); + + // Send the message + sendMessage(message).block(TIMEOUT); + + setReceiver(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); + StepVerifier.create(receiver.receiveMessages()/*.take(totalMessages)*/) + .assertNext(received -> { + assertNotNull(received.getLockToken()); + AmqpAnnotatedMessage actual = received.getRawAmqpMessage(); + try { + assertArrayEquals(CONTENTS_BYTES, message.getBody().toBytes()); + assertEquals(expectedAmqpProperties.getHeader().getPriority(), actual.getHeader().getPriority()); + assertEquals(expectedAmqpProperties.getHeader().isFirstAcquirer(), actual.getHeader().isFirstAcquirer()); + assertEquals(expectedAmqpProperties.getHeader().isDurable(), actual.getHeader().isDurable()); + + assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); + assertEquals(expectedAmqpProperties.getProperties().getReplyToGroupId(), actual.getProperties().getReplyToGroupId()); + assertEquals(expectedAmqpProperties.getProperties().getReplyTo(), actual.getProperties().getReplyTo()); + assertEquals(expectedAmqpProperties.getProperties().getContentType(), actual.getProperties().getContentType()); + assertEquals(expectedAmqpProperties.getProperties().getCorrelationId(), actual.getProperties().getCorrelationId()); + assertEquals(expectedAmqpProperties.getProperties().getTo(), actual.getProperties().getTo()); + assertEquals(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime().toEpochSecond(), actual.getProperties().getAbsoluteExpiryTime().toEpochSecond()); + assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); + assertEquals(expectedAmqpProperties.getProperties().getContentEncoding(), actual.getProperties().getContentEncoding()); + assertEquals(expectedAmqpProperties.getProperties().getGroupSequence(), actual.getProperties().getGroupSequence()); + assertEquals(expectedAmqpProperties.getProperties().getCreationTime().toEpochSecond(), actual.getProperties().getCreationTime().toEpochSecond()); + assertArrayEquals(expectedAmqpProperties.getProperties().getUserId(), actual.getProperties().getUserId()); + + assertMapValues(expectedAmqpProperties.getDeliveryAnnotations(), actual.getDeliveryAnnotations()); + assertMapValues(expectedAmqpProperties.getMessageAnnotations(), actual.getMessageAnnotations()); + assertMapValues(expectedAmqpProperties.getApplicationProperties(), actual.getApplicationProperties()); + assertMapValues(expectedAmqpProperties.getFooter(), actual.getFooter()); + } finally { + receiver.complete(received).block(Duration.ofSeconds(15)); + logMessage(received, receiver.getEntityPath(), "completed message"); + } + }) + .thenCancel() + .verify(Duration.ofMinutes(2)); + } + + /** + * Verifies we can autocomplete for a queue. + * + * @param entityType Entity Type. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void autoComplete(MessagingEntityType entityType) { + // Arrange + final Duration shortWait = Duration.ofSeconds(2); + final int index = USE_CASE_AUTO_COMPLETE; + setSender(entityType, index, false); + + final int numberOfEvents = 3; + final String messageId = UUID.randomUUID().toString(); + final List messages = getServiceBusMessages(numberOfEvents, messageId); + + setReceiver(entityType, index, false); + + // Send messages. + StepVerifier.create(Flux.fromIterable(messages).flatMap(this::sendMessage)) + .verifyComplete(); + + final ServiceBusReceiverAsyncClient autoCompleteReceiver = + toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, index, false) + .buildAsyncClient()); + + Set sequenceNumbers = new HashSet<>(); + // Act + // Expecting that as we receive these messages, they'll be completed. + StepVerifier.create(autoCompleteReceiver.receiveMessages() + .filter(m -> messageId.equals(m.getMessageId())) + .doOnNext(m -> sequenceNumbers.add(m.getSequenceNumber()))) + .expectNextCount(numberOfEvents) + .thenAwait(shortWait) // Give time for autoComplete to finish + .thenCancel() + .verify(TIMEOUT); + + // Assert messages are completed. + for (Long sequenceNumber : sequenceNumbers) { + StepVerifier.create(autoCompleteReceiver.peekMessage(sequenceNumber)) + .verifyComplete(); + } + } + + /** + * Asserts the length and values with in the map. + */ + private void assertMapValues(Map expectedMap, Map actualMap) { + assertTrue(actualMap.size() >= expectedMap.size()); + for (String key : expectedMap.keySet()) { + assertEquals(expectedMap.get(key), actualMap.get(key), "Value is not equal for Key " + key); + } } -// /** -// * Verifies that we can create multiple transaction using sender and receiver. -// */ -// @Test -// void createMultipleTransactionTest() { -// // Arrange -// setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.createTransaction()) -// .assertNext(Assertions::assertNotNull) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(receiver.createTransaction()) -// .assertNext(Assertions::assertNotNull) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can create transaction and complete. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Assert & Act -// AtomicReference transaction = new AtomicReference<>(); -// StepVerifier.create(receiver.createTransaction()) -// .assertNext(txn -> { -// transaction.set(txn); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(receiver.receiveMessages() -// .flatMap(receivedMessage -> { -// logMessage(receivedMessage, receiver.getEntityPath(), "received message"); -// return receiver.complete(receivedMessage) -// .doOnSuccess(m -> logMessage(receivedMessage, receiver.getEntityPath(), "completed message")) -// .thenReturn(receivedMessage); -// }).take(1)) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(receiver.rollbackTransaction(transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can do following using shared connection and on non session entity. 1. create transaction 2. -// * receive and settle with transactionContext. 3. commit Rollback this transaction. -// */ -// @ParameterizedTest -// @EnumSource(DispositionStatus.class) -// void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { -// -// // Arrange -// final MessagingEntityType entityType = MessagingEntityType.QUEUE; -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_TRANSACTION_SENDRECEIVE_AND_COMPLETE, isSessionEnabled); -// -// final String messageId1 = UUID.randomUUID().toString(); -// final ServiceBusMessage message1 = getMessage(messageId1, isSessionEnabled); -// final String deadLetterReason = "test reason"; -// -// sendMessage(message1).block(TIMEOUT); -// -// // Assert & Act -// AtomicReference transaction = new AtomicReference<>(); -// StepVerifier.create(receiver.createTransaction()) -// .assertNext(txn -> { -// transaction.set(txn); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// assertNotNull(transaction.get()); -// -// // Assert & Act -// final ServiceBusReceivedMessage message = receiver.receiveMessages() -// .flatMap(receivedMessage -> { -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// final Mono operation; -// switch (dispositionStatus) { -// case COMPLETED: -// operation = receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get())); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed messages"); -// break; -// case ABANDONED: -// operation = receiver.abandon(receivedMessage, new AbandonOptions().setTransactionContext(transaction.get())); -// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned messages"); -// break; -// case SUSPENDED: -// DeadLetterOptions deadLetterOptions = new DeadLetterOptions().setTransactionContext(transaction.get()) -// .setDeadLetterReason(deadLetterReason); -// operation = receiver.deadLetter(receivedMessage, deadLetterOptions); -// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered messages"); -// break; -// case DEFERRED: -// operation = receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction.get())); -// logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); -// break; -// case RELEASED: -// operation = receiver.release(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "released messages"); -// break; -// default: -// throw LOGGER.logExceptionAsError(new IllegalArgumentException( -// "Disposition status not recognized for this test case: " + dispositionStatus)); -// } -// return operation -// .thenReturn(receivedMessage); -// }) -// .blockFirst(TIMEOUT); -// assertNotNull(message); -// -// StepVerifier.create(receiver.commitTransaction(transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can do following on different clients i.e. sender and receiver. 1. create transaction using -// * sender 2. receive and complete with transactionContext. 3. Commit this transaction using sender. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// @Disabled -// void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { -// // Arrange -// final boolean shareConnection = true; -// final int entityIndex = 0; -// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) -// .buildAsyncClient()); -// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) -// .buildAsyncClient()); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(TIMEOUT); -// -// // Assert & Act -// AtomicReference transaction = new AtomicReference<>(); -// StepVerifier.create(sender.createTransaction()) -// .assertNext(txn -> { -// transaction.set(txn); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// assertNotNull(transaction.get()); -// -// // Assert & Act -// final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); -// assertNotNull(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "received message"); -// StepVerifier.create(receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction.get()))) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(sender.commitTransaction(transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send and receive two messages. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int entityIndex = 0; -// final boolean shareConnection = false; -// final Duration shortWait = Duration.ofSeconds(3); -// -// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) -// .buildAsyncClient()); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// Mono.when(sendMessage(message), sendMessage(message)).block(); -// -// // Now create receiver -// if (isSessionEnabled) { -// assertNotNull(sessionId, "'sessionId' should have been set."); -// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) -// .buildAsyncClient()); -// this.receiver = toClose(sessionReceiver.acceptSession(sessionId).block()); -// } else { -// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) -// .buildAsyncClient()); -// } -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages() -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .thenAwait(shortWait) // Give time for autoComplete to finish -// .thenCancel() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send and receive a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int entityIndex = USE_CASE_AUTO_COMPLETE; -// final boolean shareConnection = false; -// -// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) -// .buildAsyncClient()); -// final String messageId = CoreUtils.randomUuid().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// StepVerifier.create(sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// -// // Now create receiver -// if (isSessionEnabled) { -// assertNotNull(sessionId, "'sessionId' should have been set."); -// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) -// .buildAsyncClient()); -// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); -// } else { -// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) -// .buildAsyncClient()); -// } -// -// // Assert -// StepVerifier.create(receiver.receiveMessages() -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId()))) -// .assertNext(receivedMessage -> { -// logMessage(receivedMessage, receiver.getEntityPath(), "received message"); -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// }) -// .expectNoEvent(Duration.ofSeconds(30)) -// .thenCancel() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send and peek a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(); -// -// setReceiver(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); -// -// Mono peek = receiver.peekMessage() -// .filter(m -> messageId.equals(m.getMessageId())) -// .repeatWhenEmpty(10, i -> Flux.interval(Duration.ofSeconds(1))); -// -// // Assert & Act -// StepVerifier.create(peek -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked and filtered message"))) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that an empty entity does not error when peeking. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); -// -// final int fromSequenceNumber = 1; -// -// // Assert & Act -// StepVerifier.create(receiver.peekMessage(fromSequenceNumber) -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can schedule and receive a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); -// final Duration shortDelay = Duration.ofSeconds(4); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(2); -// -// sender.scheduleMessage(message, scheduledEnqueueTime).block(); -// -// setReceiver(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(Mono.delay(shortDelay).then(receiver.receiveMessages() -// .filter(m -> messageId.equals(m.getMessageId())) -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) -// .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).next())) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can cancel a scheduled message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); -// final Duration delayDuration = Duration.ofSeconds(3); -// -// final Long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime).block(TIMEOUT); -// logMessage(message, sender.getEntityPath(), "scheduled"); -// -// assertNotNull(sequenceNumber); -// -// Mono.delay(delayDuration) -// .then(sender.cancelScheduledMessage(sequenceNumber)) -// .block(TIMEOUT); -// -// logMessage(message, sender.getEntityPath(), "cancelled messaged with sequence number " + sequenceNumber); -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages() -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) -// .take(1)) -// .thenAwait(Duration.ofSeconds(5)) -// .thenCancel() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send and peek a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int entityIndex = 3; -// -// setSender(entityType, entityIndex, isSessionEnabled); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final CountDownLatch countDownLatch = new CountDownLatch(1); -// -// sendMessage(message).block(); -// -// setReceiver(entityType, entityIndex, isSessionEnabled); -// -// // Message are not always guaranteed, so try many times -// final ServiceBusReceivedMessage peekMessage = receiver.peekMessage() -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) -// .map(receivedMessage -> { -// countDownLatch.countDown(); -// return receivedMessage; -// }) -// .repeat(() -> countDownLatch.getCount() > 0) -// .next() -// .block(); -// assertNotNull(peekMessage); -// final long sequenceNumber = peekMessage.getSequenceNumber(); -// -// // Assert & Act -// try { -// StepVerifier.create(receiver.peekMessage(sequenceNumber) -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message"))) -// .assertNext(m -> { -// assertEquals(sequenceNumber, m.getSequenceNumber()); -// assertMessageEquals(m, messageId, isSessionEnabled); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } finally { -// -// // Cleanup -// StepVerifier.create(receiver.receiveMessages() -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) -// .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) -// .expectNextCount(1) -// .expectComplete() -// .verify(TIMEOUT); -// } -// } -// -// /** -// * Verifies that we can send and peek a batch of messages and the sequence number is tracked correctly. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// public void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { -// // Arrange -// setSender(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final List messages = getServiceBusMessages(10, messageId, CONTENTS_BYTES); -// final Set receivedPositions = Collections.synchronizedSet(new HashSet<>()); -// final List receivedMessages = Collections.synchronizedList(new ArrayList<>()); -// -// if (isSessionEnabled) { -// messages.forEach(m -> m.setSessionId(sessionId)); -// } -// -// StepVerifier.create(sender.sendMessages(messages) -// .doOnSuccess(aVoid -> logMessages(messages, sender.getEntityPath(), "sent"))) -// .expectComplete() -// .verify(TIMEOUT); -// -// setReceiver(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); -// -// // Assert & Act -// for (int i = 0; i < 5 && receivedPositions.size() < messages.size(); i++) { -// peekMessages(messages.size(), messageId, receivedPositions) -// .doOnNext(receivedMessage -> receivedMessages.add(receivedMessage)) -// .blockLast(); -// if (receivedPositions.size() < messages.size()) { -// Thread.sleep(1000); -// } -// } -// -// assertEquals(receivedMessages.size(), messages.size()); -// -// final AtomicInteger messageCount = new AtomicInteger(); -// -// synchronized (receivedMessages) { -// receivedMessages.stream() -// .forEach(actualMessage -> { -// final Object position = actualMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); -// assertTrue(position instanceof Integer, "Did not contain correct position number: " + position); -// -// // messages are received in the same order as they were sent -// assertEquals(messageCount.getAndIncrement(), position); -// }); -// } -// } -// -// private Flux peekMessages(int count, String messageIdFilter, Set receivedPositions) { -// return receiver.peekMessages(count) -// // maxMessages are not always guaranteed, sometime, we get less than asked for, so we will try many times. -// .filter(receivedMessage -> { -// logMessage(receivedMessage, receiver.getEntityPath(), "peeked message"); -// Integer position = (Integer) receivedMessage.getApplicationProperties().get(MESSAGE_POSITION_ID); -// boolean filtered = messageIdFilter.equals(receivedMessage.getMessageId()) && receivedPositions.add(position); -// if (filtered) { -// logMessage(receivedMessage, receiver.getEntityPath(), "filtered message, a few more to go"); -// } -// return filtered; -// }); -// } -// -// /** -// * Verifies that we can send and peek a batch of messages. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void peekMessagesFromSequence(MessagingEntityType entityType) throws InterruptedException { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_MESSAGE_FROM_SEQUENCE, false); -// -// final AtomicInteger messageId = new AtomicInteger(); -// final int maxMessages = 2; -// final AtomicLong fromSequenceNumber = new AtomicLong(); -// final CountDownLatch countdownLatch = new CountDownLatch(maxMessages); -// fromSequenceNumber.set(1); -// -// final byte[] content = "peek-message-from-sequence".getBytes(Charset.defaultCharset()); -// List messageIds = Collections.synchronizedList(new ArrayList<>()); -// for (int i = 0; i < maxMessages; ++i) { -// ServiceBusMessage message = getMessage(String.valueOf(i), isSessionEnabled, AmqpMessageBody.fromData(content)); -// messageIds.add(String.valueOf(i)); -// sendMessage(message).block(); -// } -// -// // Assert & Act -// -// // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times -// // https://github.com/Azure/azure-sdk-for-java/issues/21168 -// List receivedMessages = Collections.synchronizedList(new ArrayList<>()); -// Disposable subscription = receiver.peekMessages(maxMessages, fromSequenceNumber.get()) -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "peeked message")) -// .filter(receivedMessage -> messageIds.contains(receivedMessage.getMessageId()) -// && receivedMessages.parallelStream().noneMatch(mid -> -// mid.equals(receivedMessage.getMessageId()))) -// .sort(Comparator.comparing(ServiceBusReceivedMessage::getMessageId)) -// .flatMap(receivedMessage -> { -// Long previousSequenceNumber = fromSequenceNumber.get(); -// fromSequenceNumber.set(receivedMessage.getSequenceNumber() + 1); -// countdownLatch.countDown(); -// receivedMessages.add(receivedMessage.getMessageId()); -// assertEquals(String.valueOf(messageId.getAndIncrement()), receivedMessage.getMessageId(), -// String.format("Message id did not match. Message payload: [%s], peek from Sequence Number [%s], " -// + " received message Sequence Number [%s]", receivedMessage.getBody(), -// previousSequenceNumber, receivedMessage.getSequenceNumber())); -// return Mono.just(receivedMessage); -// }) -// .repeat(() -> countdownLatch.getCount() > 0) -// .subscribe(); -// toClose(subscription); -// -// assertTrue(countdownLatch.await(20, TimeUnit.SECONDS), "Failed peek messages from sequence."); -// -// StepVerifier.create(receiver.receiveMessages().take(maxMessages)) -// .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) -// .assertNext(receivedMessage -> receiver.complete(receivedMessage).block(Duration.ofSeconds(15))) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that an empty entity does not error when peeking. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); -// -// final int maxMessages = 10; -// final int fromSequenceNumber = 1; -// -// // Assert & Act -// StepVerifier.create(receiver.peekMessages(maxMessages, fromSequenceNumber)) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can dead-letter a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int entityIndex = 0; -// setSender(entityType, entityIndex, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(); -// -// setReceiver(entityType, entityIndex, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages() -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) -// .flatMap(receivedMessage -> receiver.deadLetter(receivedMessage).thenReturn(receivedMessage)).take(1)) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .thenCancel() -// .verify(TIMEOUT); -// -// } -// -// /** -// * Verifies that we can send and receive a message AMQP Sequence andValue object. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; -// final boolean shareConnection = false; -// final Duration shortWait = Duration.ofSeconds(3); -// final Long expectedLongValue = Long.parseLong("6"); -// -// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) -// .buildAsyncClient()); -// -// // Send value Object -// String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromValue(expectedLongValue)); -// sendMessage(message).block(TIMEOUT); -// -// // send SEQUENCE -// messageId = UUID.randomUUID().toString(); -// -// List sequenceData = new ArrayList<>(); -// sequenceData.add("A1"); -// sequenceData.add(1L); -// sequenceData.add(2); -// -// message = getMessage(messageId, isSessionEnabled, AmqpMessageBody.fromSequence(sequenceData)); -// sendMessage(message).block(TIMEOUT); -// -// // Now create receiver -// if (isSessionEnabled) { -// assertNotNull(sessionId, "'sessionId' should have been set."); -// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) -// .buildAsyncClient()); -// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); -// } else { -// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) -// .buildAsyncClient()); -// } -// -// // Assert -// StepVerifier.create(receiver.receiveMessages()) -// .assertNext(receivedMessage -> { -// AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); -// AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); -// assertEquals(AmqpMessageBodyType.VALUE, type); -// Object value = amqpAnnotatedMessage.getBody().getValue(); -// assertTrue(value instanceof Long); -// assertEquals(expectedLongValue.longValue(), ((Long) value).longValue()); -// }) -// .assertNext(receivedMessage -> { -// AmqpAnnotatedMessage amqpAnnotatedMessage = receivedMessage.getRawAmqpMessage(); -// AmqpMessageBodyType type = amqpAnnotatedMessage.getBody().getBodyType(); -// assertEquals(AmqpMessageBodyType.SEQUENCE, type); -// assertArrayEquals(sequenceData.toArray(), amqpAnnotatedMessage.getBody().getSequence().toArray()); -// }) -// .thenAwait(shortWait) // Give time for autoComplete to finish -// .thenCancel() -// .verify(TIMEOUT); -// -// if (!isSessionEnabled) { -// StepVerifier.create(receiver.receiveMessages()) -// .thenAwait(shortWait) -// .thenCancel() -// .verify(TIMEOUT); -// } -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(TIMEOUT); -// -// setReceiver(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages() -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) -// .doOnNext(receivedMessage -> logMessage(receivedMessage, receiver.getEntityPath(), "received and filtered")) -// .flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can renew message lock on a non-session receiver. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void receiveAndRenewLock(MessagingEntityType entityType) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// -// // Blocking here because it is not part of the scenario we want to test. -// sendMessage(message).block(TIMEOUT); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); -// -// final ServiceBusReceivedMessage receivedMessage = receiver.receiveMessages().next().block(TIMEOUT); -// assertNotNull(receivedMessage); -// assertNotNull(receivedMessage.getLockedUntil()); -// -// final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); -// LOGGER.info("Received message. Seq: {}. lockedUntil: {}", receivedMessage.getSequenceNumber(), initialLock); -// -// // Assert & Act -// try { -// StepVerifier.create(Mono.delay(Duration.ofSeconds(7)) -// .then(Mono.defer(() -> receiver.renewMessageLock(receivedMessage)))) -// .assertNext(lockedUntil -> assertTrue(lockedUntil.isAfter(initialLock), -// String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", -// lockedUntil, initialLock))) -// .expectComplete() -// .verify(TIMEOUT); -// } finally { -// LOGGER.info("Completing message. Seq: {}.", receivedMessage.getSequenceNumber()); -// -// receiver.complete(receivedMessage) -// .doOnNext(m -> logMessage(receivedMessage, receiver.getEntityPath(), "complete")) -// .block(TIMEOUT); -// } -// } -// -// /** -// * Receiver should receive the messages even if user is not "settling the messages" in PEEK LOCK mode and -// * autoComplete is disabled. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int totalMessages = 5; -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Send messages -// final String messageId = UUID.randomUUID().toString(); -// final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); -// if (isSessionEnabled) { -// messages.forEach(m -> m.setSessionId(sessionId)); -// } -// sender.sendMessages(messages).block(TIMEOUT); -// logMessages(messages, sender.getEntityPath(), "sent messages"); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages().take(totalMessages)) -// .expectNextCount(totalMessages) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Receiver should receive the messages if processing time larger than message lock duration and -// * maxAutoLockRenewDuration is set to a large enough duration so user can complete in end. -// * This test takes longer time. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final int totalMessages = 2; -// // The lock timeout property set on the queue. -// final Duration lockRenewTimeout = Duration.ofSeconds(15); -// final ClientCreationOptions clientCreationOptions = new ClientCreationOptions().setMaxAutoLockRenewDuration(Duration.ofMinutes(1)); -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Send messages -// final String messageId = UUID.randomUUID().toString(); -// final List messages = TestUtils.getServiceBusMessages(totalMessages, messageId, CONTENTS_BYTES); -// if (isSessionEnabled) { -// messages.forEach(m -> m.setSessionId(sessionId)); -// } -// sender.sendMessages(messages).block(); -// logMessages(messages, sender.getEntityPath(), "sent messages"); -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled, clientCreationOptions); -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages() -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) -// .map(receivedMessage -> Mono.delay(lockRenewTimeout.plusSeconds(2)) -// .then(receiver.complete(receivedMessage)).thenReturn(receivedMessage).block()).take(totalMessages)) -// .expectNextCount(totalMessages) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that the lock can be automatically renewed. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final AtomicInteger lockRenewCount = new AtomicInteger(); -// -// setSender(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// // Send the message to verify. -// sendMessage(message).block(); -// -// setReceiver(entityType, TestUtils.USE_CASE_AUTO_RENEW_RECEIVE, isSessionEnabled); -// -// // Act & Assert -// StepVerifier.create(receiver.receiveMessages().flatMap(received -> { -// LOGGER.info("{}: lockToken[{}]. lockedUntil[{}]. now[{}]", received.getSequenceNumber(), -// received.getLockToken(), received.getLockedUntil(), OffsetDateTime.now()); -// -// // Simulate some sort of long processing. -// while (lockRenewCount.get() < 4) { -// lockRenewCount.incrementAndGet(); -// LOGGER.info("Iteration {}: Curren time {}.", lockRenewCount.get(), OffsetDateTime.now()); -// try { -// TimeUnit.SECONDS.sleep(5); -// } catch (InterruptedException error) { -// LOGGER.error("Error occurred while sleeping: " + error); -// } -// } -// return receiver.complete(received).thenReturn(received); -// })) -// .assertNext(received -> assertTrue(lockRenewCount.get() > 0)) -// .thenCancel() -// .verify(TIMEOUT); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(TIMEOUT); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// StepVerifier.create(receiver.receiveMessages() -// .flatMap(receivedMessage -> receiver.abandon(receivedMessage).thenReturn(receivedMessage)).take(1)) -// .assertNext(receivedMessage -> assertMessageEquals(receivedMessage, messageId, isSessionEnabled)) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(TIMEOUT); -// -// setReceiver(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); -// AtomicReference received = new AtomicReference(); -// -// // Act & Assert -// StepVerifier.create(receiver.receiveMessages() -// .flatMap(receivedMessage -> receiver.defer(receivedMessage).thenReturn(receivedMessage)).take(1)) -// .assertNext(m -> { -// received.set(m); -// assertMessageEquals(m, messageId, isSessionEnabled); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// // TODO(Hemant): Identify if this is valid scenario (https://github.com/Azure/azure-sdk-for-java/issues/19673) -// /*receiver.receiveDeferredMessage(received.get().getSequenceNumber()) -// .flatMap(m -> receiver.complete(m)) -// .block(TIMEOUT); -// messagesPending.decrementAndGet(); -// */ -// } -// -// /** -// * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") -// @ParameterizedTest -// void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFERRED_MESSAGE_BY_SEQUENCE_NUMBER, false); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// StepVerifier.create(sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create( -// receiver.receiveMessages() -// .flatMap(m -> receiver.defer(m).thenReturn(m)) -// .flatMap(received -> { -// logMessage(received, receiver.getEntityPath(), "received and deferred"); -// return receiver -// .receiveDeferredMessage(received.getSequenceNumber()) -// .flatMap(deferred -> { -// logMessage(deferred, receiver.getEntityPath(), "received deferred"); -// -// assertNotNull(deferred); -// assertEquals(received.getSequenceNumber(), deferred.getSequenceNumber()); -// -// switch (dispositionStatus) { -// case ABANDONED: -// logMessage(deferred, receiver.getEntityPath(), "abandon"); -// return receiver.abandon(deferred).thenReturn(deferred); -// case SUSPENDED: -// logMessage(deferred, receiver.getEntityPath(), "deadLetter"); -// return receiver.deadLetter(deferred).thenReturn(deferred); -// case COMPLETED: -// logMessage(deferred, receiver.getEntityPath(), "complete"); -// return receiver.complete(deferred).thenReturn(deferred); -// default: -// throw LOGGER.logExceptionAsError(new IllegalArgumentException( -// "Disposition status not recognized for this test case: " + dispositionStatus)); -// } -// }); -// }) -// .take(1)) -// .expectNextCount(1) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) { -// // Arrange -// final boolean isSessionEnabled = true; -// setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); -// Map sentProperties = messageToSend.getApplicationProperties(); -// sentProperties.put("NullProperty", null); -// sentProperties.put("BooleanProperty", true); -// sentProperties.put("ByteProperty", (byte) 1); -// sentProperties.put("ShortProperty", (short) 2); -// sentProperties.put("IntProperty", 3); -// sentProperties.put("LongProperty", 4L); -// sentProperties.put("FloatProperty", 5.5f); -// sentProperties.put("DoubleProperty", 6.6f); -// sentProperties.put("CharProperty", 'z'); -// sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); -// sentProperties.put("StringProperty", "string"); -// -// sendMessage(messageToSend).block(TIMEOUT); -// -// setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); -// -// // Assert & Act -// StepVerifier.create(receiver.receiveMessages().flatMap(receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage)).take(1)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// -// final Map received = receivedMessage.getApplicationProperties(); -// -// assertEquals(sentProperties.size(), received.size()); -// -// for (Map.Entry sentEntry : sentProperties.entrySet()) { -// if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { -// assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) received.get(sentEntry.getKey())); -// } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { -// final Object expected = sentEntry.getValue(); -// final Object actual = received.get(sentEntry.getKey()); -// -// assertEquals(expected, actual, String.format( -// "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, -// actual)); -// } -// } -// }) -// .thenCancel() -// .verify(TIMEOUT); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void setAndGetSessionState(MessagingEntityType entityType) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, true); -// -// final byte[] sessionState = "Finished".getBytes(UTF_8); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage messageToSend = getMessage(messageId, true); -// -// sendMessage(messageToSend).block(Duration.ofSeconds(10)); -// -// // Act -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, true); -// -// StepVerifier.create(receiver.receiveMessages() -// .flatMap(message -> { -// LOGGER.info("SessionId: {}. LockToken: {}. LockedUntil: {}. Message received.", -// message.getSessionId(), message.getLockToken(), message.getLockedUntil()); -// assertMessageEquals(message, messageId, isSessionEnabled); -// return receiver.abandon(message) -// .then(receiver.setSessionState(sessionState)) -// .then(receiver.getSessionState()); -// }) -// .take(1)) -// .assertNext(state -> { -// LOGGER.info("State received: {}", new String(state, UTF_8)); -// assertArrayEquals(sessionState, state); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can receive a message from dead letter queue. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// final Duration shortWait = Duration.ofSeconds(2); -// final int entityIndex = 0; -// -// if (isSessionEnabled && sessionId == null) { -// sessionId = UUID.randomUUID().toString(); -// } -// -// setSender(entityType, entityIndex, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message).block(); -// -// setReceiver(entityType, entityIndex, isSessionEnabled); -// -// receiver.receiveMessages() -// .filter(receivedMessage -> messageId.equals(receivedMessage.getMessageId())) -// .map(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// receiver.deadLetter(receivedMessage).block(); -// return receivedMessage; -// }).next().block(OPERATION_TIMEOUT); -// -// final ServiceBusReceiverAsyncClient deadLetterReceiver; -// switch (entityType) { -// case QUEUE: -// final String queueName = isSessionEnabled ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); -// assertNotNull(queueName, "'queueName' cannot be null."); -// -// deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() -// .queueName(queueName) -// .subQueue(SubQueue.DEAD_LETTER_QUEUE) -// .buildAsyncClient()); -// break; -// case SUBSCRIPTION: -// final String topicName = getTopicName(entityIndex); -// final String subscriptionName = isSessionEnabled ? getSessionSubscriptionBaseName() : getSubscriptionBaseName(); -// assertNotNull(topicName, "'topicName' cannot be null."); -// assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); -// -// deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() -// .topicName(topicName) -// .subscriptionName(subscriptionName) -// .subQueue(SubQueue.DEAD_LETTER_QUEUE) -// .buildAsyncClient()); -// break; -// default: -// throw LOGGER.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); -// } -// -// // Assert & Act -// try { -// deadLetterReceiver.receiveMessages() -// .filter(serviceBusReceivedMessage -> messageId.equals(serviceBusReceivedMessage.getMessageId())) -// .map(serviceBusReceivedMessage -> { -// assertMessageEquals(serviceBusReceivedMessage, messageId, isSessionEnabled); -// return serviceBusReceivedMessage; -// }) -// .next() -// .block(OPERATION_TIMEOUT); -// } finally { -// // close dead letter receiver. -// deadLetterReceiver.close(); -// } -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { -// testRenewLock(entityType, Duration.ZERO, (m) -> { -// toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); -// return Mono.empty(); -// }); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void autoRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { -// testRenewLock(entityType, Duration.ofSeconds(10), (m) -> Mono.empty()); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void autoAndManualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { -// testRenewLock(entityType, Duration.ofSeconds(10), (m) -> { -// toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); -// return Mono.empty(); -// }); -// } -// -// private void testRenewLock(MessagingEntityType entityType, Duration lockRenewalDuration, Function> renewMono) throws InterruptedException { -// setSender(entityType, TestUtils.USE_CASE_RENEW_LOCK, false); -// setReceiver(entityType, TestUtils.USE_CASE_RENEW_LOCK, false, new ClientCreationOptions() -// .setMaxAutoLockRenewDuration(lockRenewalDuration)); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// -// StepVerifier.create(sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// -// AtomicReference lockedUntil = new AtomicReference<>(null); -// -// CountDownLatch latch = new CountDownLatch(2); -// receiver.receiveMessages() -// .doOnNext(m -> logMessage(m, receiver.getEntityPath(), "received message")) -// .filter(m -> messageId.equals(m.getMessageId())) -// .flatMap(receivedMessage -> { -// latch.countDown(); -// logMessage(receivedMessage, receiver.getEntityPath(), "filtered message"); -// LOGGER.atInfo() -// .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) -// .addKeyValue("seqNo", receivedMessage.getSequenceNumber()) -// .addKeyValue("deliveryCount", receivedMessage.getDeliveryCount()) -// .addKeyValue("lockToken", receivedMessage.getLockToken()) -// .addKeyValue("lockedUntil", receivedMessage.getLockedUntil()) -// .log("message properties"); -// assertNotNull(receivedMessage.getLockedUntil()); -// // expect to receive the same message but only after lock renewal completes -// if (lockedUntil.compareAndSet(null, receivedMessage.getLockedUntil())) { -// return renewMono.apply(receivedMessage); -// } else { -// // TODO: why not not always bigger than lockeduntil? time skew with service? -// assertEquals(OffsetDateTime.now().toEpochSecond(), lockedUntil.get().toEpochSecond(), 10); -// return receiver.complete(receivedMessage); -// } -// }) -// .subscribe(i -> { }, ex -> fail(ex)); -// -// assertTrue(latch.await(2, TimeUnit.MINUTES)); -// } -// -// @Test -// @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") -// void receiveTwice() { -// setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// -// StepVerifier.create(sendMessage(message)).verifyComplete(); -// StepVerifier.create(receiver.receiveMessages().take(1)) -// .expectNextCount(1) -// .expectComplete() -// .verify(OPERATION_TIMEOUT); -// -// StepVerifier.create(sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// -// // cannot subscribe to the same receiver - there was a subscription that is disposed now -// StepVerifier.create(receiver.receiveMessages().take(1)) -// .expectComplete() -// .verify(OPERATION_TIMEOUT); -// } -// -// @Test -// @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") -// void receiveActiveSubscription() { -// setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// -// StepVerifier.create(sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// toClose(receiver.receiveMessages().subscribe(m -> { })); -// -// // cannot subscribe to the same receiver - there is active subscription -// StepVerifier.create(receiver.receiveMessages().take(1)) -// .expectError() -// .verify(OPERATION_TIMEOUT); -// } -// -// /** -// * Verifies that we can receive a message which have different section set (i.e header, footer, annotations, -// * application properties etc). -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void receiveAndValidateProperties(MessagingEntityType entityType) { -// // Arrange -// final boolean isSessionEnabled = false; -// final int totalMessages = 1; -// final String subject = "subject"; -// final Map footer = new HashMap<>(); -// footer.put("footer-key-1", "footer-value-1"); -// footer.put("footer-key-2", "footer-value-2"); -// -// final Map applicationProperties = new HashMap<>(); -// applicationProperties.put("ap-key-1", "ap-value-1"); -// applicationProperties.put("ap-key-2", "ap-value-2"); -// -// final Map deliveryAnnotation = new HashMap<>(); -// deliveryAnnotation.put("delivery-annotations-key-1", "delivery-annotations-value-1"); -// deliveryAnnotation.put("delivery-annotations-key-2", "delivery-annotations-value-2"); -// -// final String messageId = UUID.randomUUID().toString(); -// final AmqpAnnotatedMessage expectedAmqpProperties = new AmqpAnnotatedMessage( -// AmqpMessageBody.fromData(CONTENTS_BYTES)); -// expectedAmqpProperties.getProperties().setSubject(subject); -// expectedAmqpProperties.getProperties().setReplyToGroupId("r-gid"); -// expectedAmqpProperties.getProperties().setReplyTo(new AmqpAddress("reply-to")); -// expectedAmqpProperties.getProperties().setContentType("content-type"); -// expectedAmqpProperties.getProperties().setCorrelationId(new AmqpMessageId("correlation-id")); -// expectedAmqpProperties.getProperties().setTo(new AmqpAddress("to")); -// expectedAmqpProperties.getProperties().setAbsoluteExpiryTime(OffsetDateTime.now().plusSeconds(60)); -// expectedAmqpProperties.getProperties().setUserId("user-id-1".getBytes()); -// expectedAmqpProperties.getProperties().setContentEncoding("string"); -// expectedAmqpProperties.getProperties().setGroupSequence(2L); -// expectedAmqpProperties.getProperties().setCreationTime(OffsetDateTime.now().plusSeconds(30)); -// -// expectedAmqpProperties.getHeader().setPriority((short) 2); -// expectedAmqpProperties.getHeader().setFirstAcquirer(true); -// expectedAmqpProperties.getHeader().setDurable(true); -// -// expectedAmqpProperties.getFooter().putAll(footer); -// expectedAmqpProperties.getDeliveryAnnotations().putAll(deliveryAnnotation); -// expectedAmqpProperties.getApplicationProperties().putAll(applicationProperties); -// -// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// -// final AmqpAnnotatedMessage amqpAnnotatedMessage = message.getRawAmqpMessage(); -// amqpAnnotatedMessage.getMessageAnnotations().putAll(expectedAmqpProperties.getMessageAnnotations()); -// amqpAnnotatedMessage.getApplicationProperties().putAll(expectedAmqpProperties.getApplicationProperties()); -// amqpAnnotatedMessage.getDeliveryAnnotations().putAll(expectedAmqpProperties.getDeliveryAnnotations()); -// amqpAnnotatedMessage.getFooter().putAll(expectedAmqpProperties.getFooter()); -// -// final AmqpMessageHeader header = amqpAnnotatedMessage.getHeader(); -// header.setFirstAcquirer(expectedAmqpProperties.getHeader().isFirstAcquirer()); -// header.setTimeToLive(expectedAmqpProperties.getHeader().getTimeToLive()); -// header.setDurable(expectedAmqpProperties.getHeader().isDurable()); -// header.setDeliveryCount(expectedAmqpProperties.getHeader().getDeliveryCount()); -// header.setPriority(expectedAmqpProperties.getHeader().getPriority()); -// -// final AmqpMessageProperties amqpMessageProperties = amqpAnnotatedMessage.getProperties(); -// amqpMessageProperties.setReplyTo((expectedAmqpProperties.getProperties().getReplyTo())); -// amqpMessageProperties.setContentEncoding((expectedAmqpProperties.getProperties().getContentEncoding())); -// amqpMessageProperties.setAbsoluteExpiryTime((expectedAmqpProperties.getProperties().getAbsoluteExpiryTime())); -// amqpMessageProperties.setSubject((expectedAmqpProperties.getProperties().getSubject())); -// amqpMessageProperties.setContentType(expectedAmqpProperties.getProperties().getContentType()); -// amqpMessageProperties.setCorrelationId(expectedAmqpProperties.getProperties().getCorrelationId()); -// amqpMessageProperties.setTo(expectedAmqpProperties.getProperties().getTo()); -// amqpMessageProperties.setGroupSequence(expectedAmqpProperties.getProperties().getGroupSequence()); -// amqpMessageProperties.setUserId(expectedAmqpProperties.getProperties().getUserId()); -// amqpMessageProperties.setAbsoluteExpiryTime(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime()); -// amqpMessageProperties.setCreationTime(expectedAmqpProperties.getProperties().getCreationTime()); -// amqpMessageProperties.setReplyToGroupId(expectedAmqpProperties.getProperties().getReplyToGroupId()); -// -// setSender(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); -// -// // Send the message -// sendMessage(message).block(TIMEOUT); -// -// setReceiver(entityType, TestUtils.USE_CASE_VALIDATE_AMQP_PROPERTIES, isSessionEnabled); -// StepVerifier.create(receiver.receiveMessages()/*.take(totalMessages)*/) -// .assertNext(received -> { -// assertNotNull(received.getLockToken()); -// AmqpAnnotatedMessage actual = received.getRawAmqpMessage(); -// try { -// assertArrayEquals(CONTENTS_BYTES, message.getBody().toBytes()); -// assertEquals(expectedAmqpProperties.getHeader().getPriority(), actual.getHeader().getPriority()); -// assertEquals(expectedAmqpProperties.getHeader().isFirstAcquirer(), actual.getHeader().isFirstAcquirer()); -// assertEquals(expectedAmqpProperties.getHeader().isDurable(), actual.getHeader().isDurable()); -// -// assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); -// assertEquals(expectedAmqpProperties.getProperties().getReplyToGroupId(), actual.getProperties().getReplyToGroupId()); -// assertEquals(expectedAmqpProperties.getProperties().getReplyTo(), actual.getProperties().getReplyTo()); -// assertEquals(expectedAmqpProperties.getProperties().getContentType(), actual.getProperties().getContentType()); -// assertEquals(expectedAmqpProperties.getProperties().getCorrelationId(), actual.getProperties().getCorrelationId()); -// assertEquals(expectedAmqpProperties.getProperties().getTo(), actual.getProperties().getTo()); -// assertEquals(expectedAmqpProperties.getProperties().getAbsoluteExpiryTime().toEpochSecond(), actual.getProperties().getAbsoluteExpiryTime().toEpochSecond()); -// assertEquals(expectedAmqpProperties.getProperties().getSubject(), actual.getProperties().getSubject()); -// assertEquals(expectedAmqpProperties.getProperties().getContentEncoding(), actual.getProperties().getContentEncoding()); -// assertEquals(expectedAmqpProperties.getProperties().getGroupSequence(), actual.getProperties().getGroupSequence()); -// assertEquals(expectedAmqpProperties.getProperties().getCreationTime().toEpochSecond(), actual.getProperties().getCreationTime().toEpochSecond()); -// assertArrayEquals(expectedAmqpProperties.getProperties().getUserId(), actual.getProperties().getUserId()); -// -// assertMapValues(expectedAmqpProperties.getDeliveryAnnotations(), actual.getDeliveryAnnotations()); -// assertMapValues(expectedAmqpProperties.getMessageAnnotations(), actual.getMessageAnnotations()); -// assertMapValues(expectedAmqpProperties.getApplicationProperties(), actual.getApplicationProperties()); -// assertMapValues(expectedAmqpProperties.getFooter(), actual.getFooter()); -// } finally { -// receiver.complete(received).block(Duration.ofSeconds(15)); -// logMessage(received, receiver.getEntityPath(), "completed message"); -// } -// }) -// .thenCancel() -// .verify(Duration.ofMinutes(2)); -// } -// -// /** -// * Verifies we can autocomplete for a queue. -// * -// * @param entityType Entity Type. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void autoComplete(MessagingEntityType entityType) { -// // Arrange -// final Duration shortWait = Duration.ofSeconds(2); -// final int index = USE_CASE_AUTO_COMPLETE; -// setSender(entityType, index, false); -// -// final int numberOfEvents = 3; -// final String messageId = UUID.randomUUID().toString(); -// final List messages = getServiceBusMessages(numberOfEvents, messageId); -// -// setReceiver(entityType, index, false); -// -// // Send messages. -// StepVerifier.create(Flux.fromIterable(messages).flatMap(this::sendMessage)) -// .verifyComplete(); -// -// final ServiceBusReceiverAsyncClient autoCompleteReceiver = -// toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, index, false) -// .buildAsyncClient()); -// -// Set sequenceNumbers = new HashSet<>(); -// // Act -// // Expecting that as we receive these messages, they'll be completed. -// StepVerifier.create(autoCompleteReceiver.receiveMessages() -// .filter(m -> messageId.equals(m.getMessageId())) -// .doOnNext(m -> sequenceNumbers.add(m.getSequenceNumber()))) -// .expectNextCount(numberOfEvents) -// .thenAwait(shortWait) // Give time for autoComplete to finish -// .thenCancel() -// .verify(TIMEOUT); -// -// // Assert messages are completed. -// for (Long sequenceNumber : sequenceNumbers) { -// StepVerifier.create(autoCompleteReceiver.peekMessage(sequenceNumber)) -// .verifyComplete(); -// } -// } -// -// /** -// * Asserts the length and values with in the map. -// */ -// private void assertMapValues(Map expectedMap, Map actualMap) { -// assertTrue(actualMap.size() >= expectedMap.size()); -// for (String key : expectedMap.keySet()) { -// assertEquals(expectedMap.get(key), actualMap.get(key), "Value is not equal for Key " + key); -// } -// } -// /** * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. */ diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index 79a4e51da4f7..7c6fb22ccb82 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -3,900 +3,897 @@ package com.azure.messaging.servicebus; -class ServiceBusReceiverClientIntegrationTest { +import com.azure.core.amqp.models.AmqpMessageBody; +import com.azure.core.util.IterableStream; +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.implementation.DispositionStatus; +import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import com.azure.messaging.servicebus.models.AbandonOptions; +import com.azure.messaging.servicebus.models.CompleteOptions; +import com.azure.messaging.servicebus.models.DeadLetterOptions; +import com.azure.messaging.servicebus.models.DeferOptions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; + +import java.nio.charset.Charset; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Integration tests for {@link com.azure.messaging.servicebus.ServiceBusReceiverClient} from queues or subscriptions. + */ +@Tag("integration") +@Execution(ExecutionMode.SAME_THREAD) +class ServiceBusReceiverClientIntegrationTest extends IntegrationTestBase { + private static final ClientLogger LOGGER = new ClientLogger(ServiceBusReceiverClientIntegrationTest.class); + + private final AtomicInteger messagesPending = new AtomicInteger(); + private final AtomicReference> messagesDeferred = new AtomicReference<>(new ArrayList<>()); + + private ServiceBusReceiverClient receiver; + private ServiceBusSenderClient sender; + private ServiceBusSessionReceiverClient sessionReceiver; + + protected ServiceBusReceiverClientIntegrationTest() { + super(new ClientLogger(ServiceBusReceiverClientIntegrationTest.class)); + } + + @Override + protected void beforeTest() { + sessionId = UUID.randomUUID().toString(); + } + + @Override + protected void afterTest() { + dispose(receiver, sender, sessionReceiver); + } + + /** + * Verifies that we can only call receive() multiple times and with one of the receive does timeout. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); + final int maxMessages = 2; + final int totalReceive = 2; + final Duration shortTimeOut = Duration.ofSeconds(7); + int receivedMessageCount; + int totalReceivedCount = 0; + + final String messageId = UUID.randomUUID().toString(); + List messageList = new ArrayList<>(); + for (int i = 0; i < totalReceive * maxMessages; ++i) { + messageList.add(getMessage(messageId, isSessionEnabled)); + } + sendMessages(messageList); + + setReceiver(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); + + List messages; + // Act & Assert + for (int i = 0; i < totalReceive; ++i) { + IterableStream received = receiver.receiveMessages(maxMessages, shortTimeOut); + messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + receivedMessageCount = 0; + for (ServiceBusReceivedMessage receivedMessage : messages) { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + ++receivedMessageCount; + } + assertEquals(maxMessages, receivedMessageCount); + totalReceivedCount += receivedMessageCount; + } + + assertEquals(totalReceive * maxMessages, totalReceivedCount); + } + + /** + * Verifies that we can only call receive() multiple times. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + final int maxMessagesEachReceive = 3; + final int totalReceiver = 7; + final Duration shortTimeOut = Duration.ofSeconds(8); + + final String messageId = UUID.randomUUID().toString(); + final List messageList = new ArrayList<>(); + for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { + messageList.add(getMessage(messageId, isSessionEnabled)); + } + + sendMessages(messageList); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Act & Assert + List messages; + + int receivedMessageCount; + int totalReceivedCount = 0; + for (int i = 0; i < totalReceiver; ++i) { + IterableStream received = receiver.receiveMessages(maxMessagesEachReceive, shortTimeOut); + messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + receivedMessageCount = 0; + for (ServiceBusReceivedMessage receivedMessage : messages) { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + ++receivedMessageCount; + } + assertEquals(maxMessagesEachReceive, receivedMessageCount); + totalReceivedCount += receivedMessageCount; + } + + assertEquals(totalReceiver * maxMessagesEachReceive, totalReceivedCount); + } + + /** + * Verifies that we can only call receive() multiple times. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + final int maxMessagesEachReceive = 3; + final int totalReceiver = 3; + final Duration shortTimeOut = Duration.ofSeconds(4); + + final String messageId = UUID.randomUUID().toString(); + final List messageList = new ArrayList<>(); + for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { + messageList.add(getMessage(messageId, isSessionEnabled)); + } + + sendMessages(messageList); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Act & Assert + AtomicInteger totalReceivedMessages = new AtomicInteger(); + List receiverThreads = new ArrayList<>(); + for (int i = 0; i < totalReceiver; ++i) { + Thread thread = new Thread(() -> { + IterableStream received = receiver. + receiveMessages(maxMessagesEachReceive, shortTimeOut); + List messages1 = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + int receivedMessageCount = 0; + long lastSequenceReceiver = 0; + for (ServiceBusReceivedMessage receivedMessage : messages1) { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + assertTrue(receivedMessage.getSequenceNumber() > lastSequenceReceiver); + lastSequenceReceiver = receivedMessage.getSequenceNumber(); + messagesPending.decrementAndGet(); + ++receivedMessageCount; + } + totalReceivedMessages.addAndGet(receivedMessageCount); + assertTrue(receivedMessageCount >= 1); + }); + receiverThreads.add(thread); + } + + receiverThreads.forEach(Thread::start); + + receiverThreads.forEach(t -> { + try { + t.join(TIMEOUT.toMillis()); + } catch (InterruptedException e) { + fail("Error in receiving messages: " + e.getMessage()); + } + }); + assertTrue(totalReceivedMessages.get() >= totalReceiver); + } + + /** + * Verifies that we can send and receive two messages. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); + int maxMessages = 4; + int messagesToSend = 4; + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message); + sendMessage(message); + sendMessage(message); + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); + + // Act + IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); + List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + + // Assert + int receivedMessageCount = 0; + final long startTime = System.currentTimeMillis(); + for (ServiceBusReceivedMessage receivedMessage : messages) { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + ++receivedMessageCount; + } + final long endTime = System.currentTimeMillis(); + assertEquals(messagesToSend, receivedMessageCount); + assertTrue(TIMEOUT.toMillis() > (endTime - startTime)); + } + + /** + * Verifies that we do not receive any message in given timeout. + */ + @Test + void receiveNoMessage() { + // Arrange + boolean isSessionEnabled = false; + setReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_RECEIVE_NO_MESSAGES, isSessionEnabled); + int howManyMessage = 2; + long noMessages = 0; + + // Act + final IterableStream received = receiver.receiveMessages(howManyMessage, + Duration.ofSeconds(15)); + List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + // Assert + assertEquals(noMessages, messages.size()); + } + + /** + * Verifies that we can send, receive one message and settle on non session entity. + */ + @ParameterizedTest + @EnumSource(DispositionStatus.class) + void transactionMessageAndSettle(DispositionStatus dispositionStatus) { + // Arrange + final boolean isSessionEnabled = false; + final MessagingEntityType entityType = MessagingEntityType.QUEUE; + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + int maxMessages = 1; + final String deadLetterReason = "testing"; + + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message); + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Act & Assert + final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); + List messageList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + + final ServiceBusTransactionContext transaction = receiver.createTransaction(); + + assertEquals(maxMessages, messageList.size()); + + ServiceBusReceivedMessage receivedMessage = messageList.get(0); + + switch (dispositionStatus) { + case COMPLETED: + receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction)); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + break; + case ABANDONED: + receiver.abandon(receivedMessage, new AbandonOptions() + .setTransactionContext(transaction)); + logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); + break; + case SUSPENDED: + DeadLetterOptions deadLetterOptions = new DeadLetterOptions() + .setDeadLetterReason(deadLetterReason) + .setTransactionContext(transaction); + receiver.deadLetter(receivedMessage, deadLetterOptions); + logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); + break; + case DEFERRED: + receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction)); + logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); + break; + case RELEASED: + break; + default: + throw LOGGER.logExceptionAsWarning(new IllegalArgumentException( + "Disposition status not recognized for this test case: " + dispositionStatus)); + } + + receiver.commitTransaction(transaction); + } + + /** + * Verifies that we can send and receive one messages. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + int maxMessages = 1; + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message); + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Act + final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); + List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + // Assert + final AtomicInteger receivedMessageCount = new AtomicInteger(); + messages.forEach(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + receivedMessageCount.incrementAndGet(); + }); + + assertEquals(maxMessages, receivedMessageCount.get()); + } + + /** + * Verifies that we can send and peek a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + // Act + ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); + logMessage(receivedMessage, receiver.getEntityPath(), "peeked messages"); + + // Assert + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + } + + /** + * Verifies that an empty entity does not error when peeked. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); + + // Act + final ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); + + // Assert + assertNull(receivedMessage); + } + + /** + * Verifies that we can send and peek a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final int maxMessages = 1; + + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(received); + + List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + assertEquals(maxMessages, messages.size()); + final ServiceBusReceivedMessage receivedMessage = messages.get(0); + assertNotNull(receivedMessage); + + // Act + final ServiceBusReceivedMessage receivedPeekMessage = receiver.peekMessage(receivedMessage.getSequenceNumber()); + logMessage(receivedPeekMessage, receiver.getEntityPath(), "peeked message"); + + // Assert + assertEquals(receivedMessage.getSequenceNumber(), receivedPeekMessage.getSequenceNumber()); + assertMessageEquals(receivedPeekMessage, messageId, isSessionEnabled); + + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + } + + /** + * Verifies that we can send and peek a batch of messages. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { + // Arrange + setSender(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); + final byte[] payload = "peek-message".getBytes(Charset.defaultCharset()); + final int maxMessages = 4; + + List messagesToSend = IntStream.range(0, maxMessages) + .mapToObj(i -> getMessage(String.format("%s-%s-%s", entityType, isSessionEnabled, i), + isSessionEnabled, AmqpMessageBody.fromData(payload))) + .collect(Collectors.toList()); + Set messageIds = messagesToSend.stream().map(ServiceBusMessage::getMessageId).collect(Collectors.toSet()); + + setReceiver(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); + List filtered = new ArrayList<>(); + AtomicInteger iterations = new AtomicInteger(0); + + // Act + Thread peekMessages = new Thread(() -> { + // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times + // https://github.com/Azure/azure-sdk-for-java/issues/21168 + while (iterations.getAndIncrement() < 10 && filtered.size() < maxMessages) { + receiver.peekMessages(maxMessages) + .forEach(m -> { + logMessage(m, receiver.getEntityPath(), "peeked messages"); + if (messageIds.contains(m.getMessageId())) { + filtered.add(m); + } + }); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + fail(); + } + } + }); + + peekMessages.start(); + toClose((AutoCloseable) () -> peekMessages.interrupt()); + + messagesToSend.forEach(message -> sendMessage(message)); + peekMessages.join(TIMEOUT.toMillis()); + + LOGGER.atInfo() + .addKeyValue("received", filtered.size()) + .addKeyValue("iterations", iterations.get()) + .addKeyValue("isSessionEnabled", isSessionEnabled) + .log("done receiving"); + + // Assert + assertEquals(maxMessages, filtered.size()); + } + + /** + * Verifies that an empty entity does not error when a batch is peeked. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); + final int maxMessages = 10; + + // Act + final IterableStream received = receiver.peekMessages(maxMessages); + // Assert + assertNotNull(received); + + List messages = logReceivedMessages(received, receiver.getEntityPath(), "peeked messages"); + final Optional anyMessages = messages.stream().findAny(); + assertFalse(anyMessages.isPresent()); + } + + /** + * Verifies that we can send and peek a batch of messages. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void peekMessagesFromSequence(MessagingEntityType entityType) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + final int maxMessages = 2; + final int fromSequenceNumber = 1; + + sendMessage(message); + sendMessage(message); + + setReceiver(entityType, 0, false); + + // Act + IterableStream iterableMessages = receiver.peekMessages(maxMessages, fromSequenceNumber); + + // Assert + final List asList = logReceivedMessages(iterableMessages, receiver.getEntityPath(), "peeked messages"); + assertEquals(maxMessages, asList.size()); + + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + assertTrue(receivedMessage.getSequenceNumber() >= fromSequenceNumber); + } + + /** + * Verifies that we can dead-letter a message. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final int maxMessages = 1; + + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(context); + + final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + + // Assert & Act + receiver.deadLetter(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); + messagesPending.decrementAndGet(); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final int maxMessages = 1; + + sendMessage(message); + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(context); + + final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); + + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + + // Assert & Act + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + } + + /** + * Verifies that we can renew message lock. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedException { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + final int maxMessages = 1; + + // Blocking here because it is not part of the scenario we want to test. + sendMessage(message); + + setReceiver(entityType, 0, false); + + final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(context); + + final List asList = context.stream().collect(Collectors.toList()); + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + assertNotNull(receivedMessage.getLockedUntil()); + + final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); + logMessage(receivedMessage, receiver.getEntityPath(), "received message, locked until " + initialLock); + + // Assert & Act + try { + TimeUnit.SECONDS.sleep(5); // Let some lock duration expire. + OffsetDateTime lockedUntil = receiver.renewMessageLock(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "renewed lock"); + assertTrue(lockedUntil.isAfter(initialLock), + String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", + lockedUntil, initialLock)); + } finally { + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.decrementAndGet(); + } + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final int maxMessages = 1; + + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(context); + + final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); + + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + + // Assert & Act + receiver.abandon(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); + // Cleanup + int messagesCompleted = completeMessages(receiver, maxMessages); + messagesPending.addAndGet(-messagesCompleted); + } + + /** + * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") + @ParameterizedTest + void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, false); + final int maxMessages = 1; + + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); + + final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(context); + + final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + + receiver.defer(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); + final ServiceBusReceivedMessage receivedDeferredMessage = receiver + .receiveDeferredMessage(receivedMessage.getSequenceNumber()); + + assertNotNull(receivedDeferredMessage); + assertEquals(receivedMessage.getSequenceNumber(), receivedDeferredMessage.getSequenceNumber()); + + // Assert & Act + switch (dispositionStatus) { + case ABANDONED: + receiver.abandon(receivedDeferredMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); + messagesDeferred.get().add(receivedMessage.getSequenceNumber()); + break; + case SUSPENDED: + receiver.deadLetter(receivedDeferredMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); + break; + case COMPLETED: + receiver.complete(receivedDeferredMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + break; + default: + throw LOGGER.logExceptionAsError(new IllegalArgumentException( + "Disposition status not recognized for this test case: " + dispositionStatus)); + } + + if (dispositionStatus == DispositionStatus.SUSPENDED || dispositionStatus == DispositionStatus.COMPLETED) { + messagesPending.decrementAndGet(); + } + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + final int maxMessages = 1; + sendMessage(message); + + setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); + final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(context); + + final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + + // Act & Assert + receiver.defer(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); + + // cleanup + final ServiceBusReceivedMessage deferred; + deferred = receiver.receiveDeferredMessage(receivedMessage.getSequenceNumber()); + logMessage(deferred, receiver.getEntityPath(), "received deffered messages"); + receiver.complete(deferred); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + messagesPending.addAndGet(-maxMessages); + } + + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType, boolean isSessionEnabled) { + // Arrange + setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); + final int maxMessages = 1; + + Map sentProperties = messageToSend.getApplicationProperties(); + sentProperties.put("NullProperty", null); + sentProperties.put("BooleanProperty", true); + sentProperties.put("ByteProperty", (byte) 1); + sentProperties.put("ShortProperty", (short) 2); + sentProperties.put("IntProperty", 3); + sentProperties.put("LongProperty", 4L); + sentProperties.put("FloatProperty", 5.5f); + sentProperties.put("DoubleProperty", 6.6f); + sentProperties.put("CharProperty", 'z'); + sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); + sentProperties.put("StringProperty", "string"); + + sendMessage(messageToSend); + + setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); + + // Assert & Act + final IterableStream received = + receiver.receiveMessages(maxMessages, TIMEOUT); + assertNotNull(received); + + final List asList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); + + assertEquals(maxMessages, asList.size()); + final ServiceBusReceivedMessage receivedMessage = asList.get(0); + assertNotNull(receivedMessage); + + messagesPending.decrementAndGet(); + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + + final Map receivedProps = receivedMessage.getApplicationProperties(); + + assertEquals(sentProperties.size(), receivedProps.size()); + + for (Map.Entry sentEntry : sentProperties.entrySet()) { + if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { + assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) receivedProps.get(sentEntry.getKey())); + } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { + final Object expected = sentEntry.getValue(); + final Object actual = receivedProps.get(sentEntry.getKey()); + + assertEquals(expected, actual, String.format( + "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, + actual)); + } + } + receiver.complete(receivedMessage); + logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); + } + + private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { + setReceiver(entityType, entityIndex, isSessionEnabled, false); + } + + private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { + setSender(entityType, entityIndex, isSessionEnabled, false); + } + + private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); + } + + private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { + + if (isSessionEnabled) { + assertNotNull(sessionId, "'sessionId' should have been set."); + this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection, null) + .buildClient()); + this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId)); + } else { + this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection) + .buildClient()); + } + } + + private void sendMessages(List messageList) { + sender.sendMessages(messageList); + int number = messagesPending.getAndSet(messageList.size()); + logMessages(messageList, sender.getEntityPath(), "sendMessages"); + LOGGER.atInfo().addKeyValue("number", number).log("message sent"); + } + + private void sendMessage(ServiceBusMessage message) { + sender.sendMessage(message); + logMessage(message, sender.getEntityPath(), "sent"); + LOGGER.atInfo() + .addKeyValue("number", messagesPending.incrementAndGet()) + .log("message sent"); + } + + private int completeMessages(ServiceBusReceiverClient client, int totalMessages) { + final IterableStream contextStream = client.receiveMessages(totalMessages, TIMEOUT); + final List asList = contextStream.stream().collect(Collectors.toList()); + for (ServiceBusReceivedMessage message : asList) { + receiver.complete(message); + logMessage(message, receiver.getEntityPath(), "received and completed"); + } + return asList.size(); + } } -// -//import com.azure.core.amqp.models.AmqpMessageBody; -//import com.azure.core.util.IterableStream; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.implementation.DispositionStatus; -//import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import com.azure.messaging.servicebus.models.AbandonOptions; -//import com.azure.messaging.servicebus.models.CompleteOptions; -//import com.azure.messaging.servicebus.models.DeadLetterOptions; -//import com.azure.messaging.servicebus.models.DeferOptions; -//import org.junit.jupiter.api.Tag; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.parallel.Execution; -//import org.junit.jupiter.api.parallel.ExecutionMode; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.EnumSource; -//import org.junit.jupiter.params.provider.MethodSource; -// -//import java.nio.charset.Charset; -//import java.time.Duration; -//import java.time.OffsetDateTime; -//import java.util.ArrayList; -//import java.util.List; -//import java.util.Map; -//import java.util.Optional; -//import java.util.Set; -//import java.util.UUID; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.concurrent.atomic.AtomicReference; -//import java.util.stream.Collectors; -//import java.util.stream.IntStream; -// -//import static com.azure.messaging.servicebus.TestUtils.USE_CASE_PEEK_BATCH; -//import static org.junit.jupiter.api.Assertions.assertArrayEquals; -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertFalse; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assertions.fail; -// -///** -// * Integration tests for {@link com.azure.messaging.servicebus.ServiceBusReceiverClient} from queues or subscriptions. -// */ -//@Tag("integration") -//@Execution(ExecutionMode.SAME_THREAD) -//class ServiceBusReceiverClientIntegrationTest extends IntegrationTestBase { -// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusReceiverClientIntegrationTest.class); -// -// private final AtomicInteger messagesPending = new AtomicInteger(); -// private final AtomicReference> messagesDeferred = new AtomicReference<>(new ArrayList<>()); -// -// private ServiceBusReceiverClient receiver; -// private ServiceBusSenderClient sender; -// private ServiceBusSessionReceiverClient sessionReceiver; -// -// protected ServiceBusReceiverClientIntegrationTest() { -// super(new ClientLogger(ServiceBusReceiverClientIntegrationTest.class)); -// } -// -// @Override -// protected void beforeTest() { -// sessionId = UUID.randomUUID().toString(); -// } -// -// @Override -// protected void afterTest() { -// dispose(receiver, sender, sessionReceiver); -// } -// -// /** -// * Verifies that we can only call receive() multiple times and with one of the receive does timeout. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); -// final int maxMessages = 2; -// final int totalReceive = 2; -// final Duration shortTimeOut = Duration.ofSeconds(7); -// int receivedMessageCount; -// int totalReceivedCount = 0; -// -// final String messageId = UUID.randomUUID().toString(); -// List messageList = new ArrayList<>(); -// for (int i = 0; i < totalReceive * maxMessages; ++i) { -// messageList.add(getMessage(messageId, isSessionEnabled)); -// } -// sendMessages(messageList); -// -// setReceiver(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); -// -// List messages; -// // Act & Assert -// for (int i = 0; i < totalReceive; ++i) { -// IterableStream received = receiver.receiveMessages(maxMessages, shortTimeOut); -// messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// receivedMessageCount = 0; -// for (ServiceBusReceivedMessage receivedMessage : messages) { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// ++receivedMessageCount; -// } -// assertEquals(maxMessages, receivedMessageCount); -// totalReceivedCount += receivedMessageCount; -// } -// -// assertEquals(totalReceive * maxMessages, totalReceivedCount); -// } -// -// /** -// * Verifies that we can only call receive() multiple times. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// final int maxMessagesEachReceive = 3; -// final int totalReceiver = 7; -// final Duration shortTimeOut = Duration.ofSeconds(8); -// -// final String messageId = UUID.randomUUID().toString(); -// final List messageList = new ArrayList<>(); -// for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { -// messageList.add(getMessage(messageId, isSessionEnabled)); -// } -// -// sendMessages(messageList); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Act & Assert -// List messages; -// -// int receivedMessageCount; -// int totalReceivedCount = 0; -// for (int i = 0; i < totalReceiver; ++i) { -// IterableStream received = receiver.receiveMessages(maxMessagesEachReceive, shortTimeOut); -// messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// receivedMessageCount = 0; -// for (ServiceBusReceivedMessage receivedMessage : messages) { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// ++receivedMessageCount; -// } -// assertEquals(maxMessagesEachReceive, receivedMessageCount); -// totalReceivedCount += receivedMessageCount; -// } -// -// assertEquals(totalReceiver * maxMessagesEachReceive, totalReceivedCount); -// } -// -// /** -// * Verifies that we can only call receive() multiple times. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// final int maxMessagesEachReceive = 3; -// final int totalReceiver = 3; -// final Duration shortTimeOut = Duration.ofSeconds(4); -// -// final String messageId = UUID.randomUUID().toString(); -// final List messageList = new ArrayList<>(); -// for (int i = 0; i < totalReceiver * maxMessagesEachReceive; ++i) { -// messageList.add(getMessage(messageId, isSessionEnabled)); -// } -// -// sendMessages(messageList); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Act & Assert -// AtomicInteger totalReceivedMessages = new AtomicInteger(); -// List receiverThreads = new ArrayList<>(); -// for (int i = 0; i < totalReceiver; ++i) { -// Thread thread = new Thread(() -> { -// IterableStream received = receiver. -// receiveMessages(maxMessagesEachReceive, shortTimeOut); -// List messages1 = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// int receivedMessageCount = 0; -// long lastSequenceReceiver = 0; -// for (ServiceBusReceivedMessage receivedMessage : messages1) { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// assertTrue(receivedMessage.getSequenceNumber() > lastSequenceReceiver); -// lastSequenceReceiver = receivedMessage.getSequenceNumber(); -// messagesPending.decrementAndGet(); -// ++receivedMessageCount; -// } -// totalReceivedMessages.addAndGet(receivedMessageCount); -// assertTrue(receivedMessageCount >= 1); -// }); -// receiverThreads.add(thread); -// } -// -// receiverThreads.forEach(Thread::start); -// -// receiverThreads.forEach(t -> { -// try { -// t.join(TIMEOUT.toMillis()); -// } catch (InterruptedException e) { -// fail("Error in receiving messages: " + e.getMessage()); -// } -// }); -// assertTrue(totalReceivedMessages.get() >= totalReceiver); -// } -// -// /** -// * Verifies that we can send and receive two messages. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); -// int maxMessages = 4; -// int messagesToSend = 4; -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message); -// sendMessage(message); -// sendMessage(message); -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); -// -// // Act -// IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); -// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// -// // Assert -// int receivedMessageCount = 0; -// final long startTime = System.currentTimeMillis(); -// for (ServiceBusReceivedMessage receivedMessage : messages) { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// ++receivedMessageCount; -// } -// final long endTime = System.currentTimeMillis(); -// assertEquals(messagesToSend, receivedMessageCount); -// assertTrue(TIMEOUT.toMillis() > (endTime - startTime)); -// } -// -// /** -// * Verifies that we do not receive any message in given timeout. -// */ -// @Test -// void receiveNoMessage() { -// // Arrange -// boolean isSessionEnabled = false; -// setReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_RECEIVE_NO_MESSAGES, isSessionEnabled); -// int howManyMessage = 2; -// long noMessages = 0; -// -// // Act -// final IterableStream received = receiver.receiveMessages(howManyMessage, -// Duration.ofSeconds(15)); -// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// // Assert -// assertEquals(noMessages, messages.size()); -// } -// -// /** -// * Verifies that we can send, receive one message and settle on non session entity. -// */ -// @ParameterizedTest -// @EnumSource(DispositionStatus.class) -// void transactionMessageAndSettle(DispositionStatus dispositionStatus) { -// // Arrange -// final boolean isSessionEnabled = false; -// final MessagingEntityType entityType = MessagingEntityType.QUEUE; -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// int maxMessages = 1; -// final String deadLetterReason = "testing"; -// -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message); -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Act & Assert -// final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); -// List messageList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// -// final ServiceBusTransactionContext transaction = receiver.createTransaction(); -// -// assertEquals(maxMessages, messageList.size()); -// -// ServiceBusReceivedMessage receivedMessage = messageList.get(0); -// -// switch (dispositionStatus) { -// case COMPLETED: -// receiver.complete(receivedMessage, new CompleteOptions().setTransactionContext(transaction)); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// break; -// case ABANDONED: -// receiver.abandon(receivedMessage, new AbandonOptions() -// .setTransactionContext(transaction)); -// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); -// break; -// case SUSPENDED: -// DeadLetterOptions deadLetterOptions = new DeadLetterOptions() -// .setDeadLetterReason(deadLetterReason) -// .setTransactionContext(transaction); -// receiver.deadLetter(receivedMessage, deadLetterOptions); -// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); -// break; -// case DEFERRED: -// receiver.defer(receivedMessage, new DeferOptions().setTransactionContext(transaction)); -// logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); -// break; -// case RELEASED: -// break; -// default: -// throw LOGGER.logExceptionAsWarning(new IllegalArgumentException( -// "Disposition status not recognized for this test case: " + dispositionStatus)); -// } -// -// receiver.commitTransaction(transaction); -// } -// -// /** -// * Verifies that we can send and receive one messages. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// int maxMessages = 1; -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message); -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Act -// final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); -// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// // Assert -// final AtomicInteger receivedMessageCount = new AtomicInteger(); -// messages.forEach(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// receivedMessageCount.incrementAndGet(); -// }); -// -// assertEquals(maxMessages, receivedMessageCount.get()); -// } -// -// /** -// * Verifies that we can send and peek a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// // Act -// ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); -// logMessage(receivedMessage, receiver.getEntityPath(), "peeked messages"); -// -// // Assert -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// } -// -// /** -// * Verifies that an empty entity does not error when peeked. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); -// -// // Act -// final ServiceBusReceivedMessage receivedMessage = receiver.peekMessage(); -// -// // Assert -// assertNull(receivedMessage); -// } -// -// /** -// * Verifies that we can send and peek a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final int maxMessages = 1; -// -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final IterableStream received = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(received); -// -// List messages = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// assertEquals(maxMessages, messages.size()); -// final ServiceBusReceivedMessage receivedMessage = messages.get(0); -// assertNotNull(receivedMessage); -// -// // Act -// final ServiceBusReceivedMessage receivedPeekMessage = receiver.peekMessage(receivedMessage.getSequenceNumber()); -// logMessage(receivedPeekMessage, receiver.getEntityPath(), "peeked message"); -// -// // Assert -// assertEquals(receivedMessage.getSequenceNumber(), receivedPeekMessage.getSequenceNumber()); -// assertMessageEquals(receivedPeekMessage, messageId, isSessionEnabled); -// -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// } -// -// /** -// * Verifies that we can send and peek a batch of messages. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { -// // Arrange -// setSender(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); -// final byte[] payload = "peek-message".getBytes(Charset.defaultCharset()); -// final int maxMessages = 4; -// -// List messagesToSend = IntStream.range(0, maxMessages) -// .mapToObj(i -> getMessage(String.format("%s-%s-%s", entityType, isSessionEnabled, i), -// isSessionEnabled, AmqpMessageBody.fromData(payload))) -// .collect(Collectors.toList()); -// Set messageIds = messagesToSend.stream().map(ServiceBusMessage::getMessageId).collect(Collectors.toSet()); -// -// setReceiver(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); -// List filtered = new ArrayList<>(); -// AtomicInteger iterations = new AtomicInteger(0); -// -// // Act -// Thread peekMessages = new Thread(() -> { -// // maxMessages are not always guaranteed, sometime, we get less than asked for, just trying two times is not enough, so we will try many times -// // https://github.com/Azure/azure-sdk-for-java/issues/21168 -// while (iterations.getAndIncrement() < 10 && filtered.size() < maxMessages) { -// receiver.peekMessages(maxMessages) -// .forEach(m -> { -// logMessage(m, receiver.getEntityPath(), "peeked messages"); -// if (messageIds.contains(m.getMessageId())) { -// filtered.add(m); -// } -// }); -// try { -// Thread.sleep(1000); -// } catch (InterruptedException e) { -// fail(); -// } -// } -// }); -// -// peekMessages.start(); -// toClose((AutoCloseable) () -> peekMessages.interrupt()); -// -// messagesToSend.forEach(message -> sendMessage(message)); -// peekMessages.join(TIMEOUT.toMillis()); -// -// LOGGER.atInfo() -// .addKeyValue("received", filtered.size()) -// .addKeyValue("iterations", iterations.get()) -// .addKeyValue("isSessionEnabled", isSessionEnabled) -// .log("done receiving"); -// -// // Assert -// assertEquals(maxMessages, filtered.size()); -// } -// -// /** -// * Verifies that an empty entity does not error when a batch is peeked. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); -// final int maxMessages = 10; -// -// // Act -// final IterableStream received = receiver.peekMessages(maxMessages); -// // Assert -// assertNotNull(received); -// -// List messages = logReceivedMessages(received, receiver.getEntityPath(), "peeked messages"); -// final Optional anyMessages = messages.stream().findAny(); -// assertFalse(anyMessages.isPresent()); -// } -// -// /** -// * Verifies that we can send and peek a batch of messages. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void peekMessagesFromSequence(MessagingEntityType entityType) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// final int maxMessages = 2; -// final int fromSequenceNumber = 1; -// -// sendMessage(message); -// sendMessage(message); -// -// setReceiver(entityType, 0, false); -// -// // Act -// IterableStream iterableMessages = receiver.peekMessages(maxMessages, fromSequenceNumber); -// -// // Assert -// final List asList = logReceivedMessages(iterableMessages, receiver.getEntityPath(), "peeked messages"); -// assertEquals(maxMessages, asList.size()); -// -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// assertTrue(receivedMessage.getSequenceNumber() >= fromSequenceNumber); -// } -// -// /** -// * Verifies that we can dead-letter a message. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final int maxMessages = 1; -// -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(context); -// -// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// -// // Assert & Act -// receiver.deadLetter(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); -// messagesPending.decrementAndGet(); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final int maxMessages = 1; -// -// sendMessage(message); -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(context); -// -// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); -// -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// -// // Assert & Act -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// } -// -// /** -// * Verifies that we can renew message lock. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedException { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// final int maxMessages = 1; -// -// // Blocking here because it is not part of the scenario we want to test. -// sendMessage(message); -// -// setReceiver(entityType, 0, false); -// -// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(context); -// -// final List asList = context.stream().collect(Collectors.toList()); -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// assertNotNull(receivedMessage.getLockedUntil()); -// -// final OffsetDateTime initialLock = receivedMessage.getLockedUntil(); -// logMessage(receivedMessage, receiver.getEntityPath(), "received message, locked until " + initialLock); -// -// // Assert & Act -// try { -// TimeUnit.SECONDS.sleep(5); // Let some lock duration expire. -// OffsetDateTime lockedUntil = receiver.renewMessageLock(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "renewed lock"); -// assertTrue(lockedUntil.isAfter(initialLock), -// String.format("Updated lock is not after the initial Lock. updated: [%s]. initial:[%s]", -// lockedUntil, initialLock)); -// } finally { -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.decrementAndGet(); -// } -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final int maxMessages = 1; -// -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(context); -// -// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); -// -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// -// // Assert & Act -// receiver.abandon(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); -// // Cleanup -// int messagesCompleted = completeMessages(receiver, maxMessages); -// messagesPending.addAndGet(-messagesCompleted); -// } -// -// /** -// * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") -// @ParameterizedTest -// void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, false); -// final int maxMessages = 1; -// -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, false); -// -// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(context); -// -// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// -// receiver.defer(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "deferred message"); -// final ServiceBusReceivedMessage receivedDeferredMessage = receiver -// .receiveDeferredMessage(receivedMessage.getSequenceNumber()); -// -// assertNotNull(receivedDeferredMessage); -// assertEquals(receivedMessage.getSequenceNumber(), receivedDeferredMessage.getSequenceNumber()); -// -// // Assert & Act -// switch (dispositionStatus) { -// case ABANDONED: -// receiver.abandon(receivedDeferredMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "abandoned message"); -// messagesDeferred.get().add(receivedMessage.getSequenceNumber()); -// break; -// case SUSPENDED: -// receiver.deadLetter(receivedDeferredMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "deadLettered message"); -// break; -// case COMPLETED: -// receiver.complete(receivedDeferredMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// break; -// default: -// throw LOGGER.logExceptionAsError(new IllegalArgumentException( -// "Disposition status not recognized for this test case: " + dispositionStatus)); -// } -// -// if (dispositionStatus == DispositionStatus.SUSPENDED || dispositionStatus == DispositionStatus.COMPLETED) { -// messagesPending.decrementAndGet(); -// } -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// final int maxMessages = 1; -// sendMessage(message); -// -// setReceiver(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); -// final IterableStream context = receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(context); -// -// final List asList = logReceivedMessages(context, receiver.getEntityPath(), "received messages"); -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// -// // Act & Assert -// receiver.defer(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "deferred messages"); -// -// // cleanup -// final ServiceBusReceivedMessage deferred; -// deferred = receiver.receiveDeferredMessage(receivedMessage.getSequenceNumber()); -// logMessage(deferred, receiver.getEntityPath(), "received deffered messages"); -// receiver.complete(deferred); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// messagesPending.addAndGet(-maxMessages); -// } -// -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType, boolean isSessionEnabled) { -// // Arrange -// setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage messageToSend = getMessage(messageId, isSessionEnabled); -// final int maxMessages = 1; -// -// Map sentProperties = messageToSend.getApplicationProperties(); -// sentProperties.put("NullProperty", null); -// sentProperties.put("BooleanProperty", true); -// sentProperties.put("ByteProperty", (byte) 1); -// sentProperties.put("ShortProperty", (short) 2); -// sentProperties.put("IntProperty", 3); -// sentProperties.put("LongProperty", 4L); -// sentProperties.put("FloatProperty", 5.5f); -// sentProperties.put("DoubleProperty", 6.6f); -// sentProperties.put("CharProperty", 'z'); -// sentProperties.put("UUIDProperty", UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d")); -// sentProperties.put("StringProperty", "string"); -// -// sendMessage(messageToSend); -// -// setReceiver(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); -// -// // Assert & Act -// final IterableStream received = -// receiver.receiveMessages(maxMessages, TIMEOUT); -// assertNotNull(received); -// -// final List asList = logReceivedMessages(received, receiver.getEntityPath(), "received messages"); -// -// assertEquals(maxMessages, asList.size()); -// final ServiceBusReceivedMessage receivedMessage = asList.get(0); -// assertNotNull(receivedMessage); -// -// messagesPending.decrementAndGet(); -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// -// final Map receivedProps = receivedMessage.getApplicationProperties(); -// -// assertEquals(sentProperties.size(), receivedProps.size()); -// -// for (Map.Entry sentEntry : sentProperties.entrySet()) { -// if (sentEntry.getValue() != null && sentEntry.getValue().getClass().isArray()) { -// assertArrayEquals((Object[]) sentEntry.getValue(), (Object[]) receivedProps.get(sentEntry.getKey())); -// } else if (!sentEntry.getKey().equals("traceparent") && !sentEntry.getKey().equals("Diagnostic-Id")) { -// final Object expected = sentEntry.getValue(); -// final Object actual = receivedProps.get(sentEntry.getKey()); -// -// assertEquals(expected, actual, String.format( -// "Key '%s' does not match. Expected: '%s'. Actual: '%s'", sentEntry.getKey(), expected, -// actual)); -// } -// } -// receiver.complete(receivedMessage); -// logMessage(receivedMessage, receiver.getEntityPath(), "completed message"); -// } -// -// private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { -// setReceiver(entityType, entityIndex, isSessionEnabled, false); -// } -// -// private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { -// setSender(entityType, entityIndex, isSessionEnabled, false); -// } -// -// private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { -// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); -// } -// -// private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { -// -// if (isSessionEnabled) { -// assertNotNull(sessionId, "'sessionId' should have been set."); -// this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection, null) -// .buildClient()); -// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId)); -// } else { -// this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection) -// .buildClient()); -// } -// } -// -// private void sendMessages(List messageList) { -// sender.sendMessages(messageList); -// int number = messagesPending.getAndSet(messageList.size()); -// logMessages(messageList, sender.getEntityPath(), "sendMessages"); -// LOGGER.atInfo().addKeyValue("number", number).log("message sent"); -// } -// -// private void sendMessage(ServiceBusMessage message) { -// sender.sendMessage(message); -// logMessage(message, sender.getEntityPath(), "sent"); -// LOGGER.atInfo() -// .addKeyValue("number", messagesPending.incrementAndGet()) -// .log("message sent"); -// } -// -// private int completeMessages(ServiceBusReceiverClient client, int totalMessages) { -// final IterableStream contextStream = client.receiveMessages(totalMessages, TIMEOUT); -// final List asList = contextStream.stream().collect(Collectors.toList()); -// for (ServiceBusReceivedMessage message : asList) { -// receiver.complete(message); -// logMessage(message, receiver.getEntityPath(), "received and completed"); -// } -// return asList.size(); -// } -//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index b8a405473fa1..2e7ae5ee4a9e 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -3,558 +3,555 @@ package com.azure.messaging.servicebus; -class ServiceBusSenderAsyncClientIntegrationTest { +import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.logging.LogLevel; +import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Integration tests for {@link ServiceBusSenderAsyncClient} from queues or subscriptions. + */ +@Tag("integration") +class ServiceBusSenderAsyncClientIntegrationTest extends IntegrationTestBase { + private static final ClientLogger LOGGER = new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class); + + private ServiceBusSenderAsyncClient sender; + private ServiceBusReceiverAsyncClient receiver; + private final AtomicInteger messagesPending = new AtomicInteger(); + + ServiceBusSenderAsyncClientIntegrationTest() { + super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); + } + + @Override + protected void beforeTest() { + sessionId = UUID.randomUUID().toString(); + } + + @Override + protected void afterTest() { + dispose(sender); + + final int numberOfMessages = messagesPending.get(); + if (numberOfMessages < 1) { + dispose(receiver); + return; + } + + try { + receiver.receiveMessages() + .take(numberOfMessages) + .map(message -> { + logger.info("Message received: {}", message.getSequenceNumber()); + return message; + }) + .timeout(Duration.ofSeconds(5), Mono.empty()) + .blockLast(); + } catch (Exception e) { + logger.warning("Error occurred when draining queue.", e); + } finally { + dispose(receiver); + } + } + + static Stream transactionMessageSendAndCompleteTransaction() { + return Stream.of( + Arguments.of(MessagingEntityType.QUEUE, true), + Arguments.of(MessagingEntityType.SUBSCRIPTION, true), + Arguments.of(MessagingEntityType.QUEUE, false), + Arguments.of(MessagingEntityType.SUBSCRIPTION, false) + ); + } + + /** + * Verifies that we can send a message to a non-session queue. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void nonSessionQueueSendMessage(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + + // Assert & Act + StepVerifier.create(sender.sendMessage(message).doOnSuccess(aVoid -> messagesPending.incrementAndGet())) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send a list of messages to a non-session entity. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void nonSessionEntitySendMessageList(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); + int count = 4; + + final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); + + // Assert & Act + StepVerifier.create(sender.sendMessages(messages) + .doOnSuccess(aVoid -> messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()))) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void nonSessionMessageBatch(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); + + final String messageId = UUID.randomUUID().toString(); + final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); + final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); + + // Assert & Act + StepVerifier.create(sender.createMessageBatch(options) + .flatMap(batch -> { + for (ServiceBusMessage message : messages) { + Assertions.assertTrue(batch.tryAddMessage(message)); + } + + return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); + })) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can send message to final destination using via-queue. + */ + @Disabled("The send via functionality is removing for first GA release, later we will come back to it.") + @Test + void viaQueueMessageSendTest() { + // Arrange + final Duration shortTimeout = Duration.ofSeconds(15); + final int viaIntermediateEntity = TestUtils.USE_CASE_TXN_1; + final int destinationEntity = TestUtils.USE_CASE_TXN_2; + final boolean shareConnection = true; + final MessagingEntityType entityType = MessagingEntityType.QUEUE; + final boolean isSessionEnabled = false; + final String messageId = UUID.randomUUID().toString(); + final int total = 1; + final int totalToDestination = 2; + final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); + final String viaQueueName = getQueueName(viaIntermediateEntity); + + setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); + + final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, + destinationEntity, false, shareConnection) + //.viaQueueName(viaQueueName) + .buildAsyncClient()); + final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, + destinationEntity, shareConnection) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .disableAutoComplete() + .buildAsyncClient()); + + final AtomicReference transaction = new AtomicReference<>(); + + // Act + try { + StepVerifier.create(destination1ViaSender.createTransaction()) + .assertNext(transactionContext -> { + transaction.set(transactionContext); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + assertNotNull(transaction.get()); + + StepVerifier.create(sender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()) + .delaySubscription(Duration.ofSeconds(1))) + .expectComplete() + .verify(TIMEOUT); + + // Assert + // Verify message is received by final destination Entity + StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + + // Verify, intermediate-via queue has it delivered to intermediate Entity. + StepVerifier.create(receiver.receiveMessages().take(total).timeout(shortTimeout)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } finally { + destination1Receiver.close(); + destination1ViaSender.close(); + } + } + + + /** + * Verifies that we can send message to final destination using via-topic. + */ + @Disabled("The send via functionality is removed for first GA release, later we will come back to it.") + @Test + void viaTopicMessageSendTest() { + // Arrange + final Duration shortTimeout = Duration.ofSeconds(15); + final int viaIntermediateEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_1; + final int destinationEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_2; + final boolean shareConnection = true; + final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; + final boolean isSessionEnabled = false; + final String messageId = UUID.randomUUID().toString(); + final int total = 1; + final int totalToDestination = 2; + final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); + final String viaTopicName = getTopicName(viaIntermediateEntity); + + setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); + final ServiceBusReceiverAsyncClient intermediateReceiver = receiver; + final ServiceBusSenderAsyncClient intermediateSender = sender; + + final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, + destinationEntity, false, shareConnection) + //.viaTopicName(viaTopicName) + .buildAsyncClient()); + + final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, + destinationEntity, shareConnection) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .disableAutoComplete() + .buildAsyncClient()); + + final AtomicReference transaction = new AtomicReference<>(); + + // Act + StepVerifier.create(destination1ViaSender.createTransaction()) + .assertNext(transactionContext -> { + transaction.set(transactionContext); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + assertNotNull(transaction.get()); + + StepVerifier.create(intermediateSender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) + .expectComplete() + .verify(TIMEOUT); + + // Assert + // Verify message is received by final destination Entity + StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + + // Verify, intermediate-via topic has it delivered to intermediate Entity. + StepVerifier.create(intermediateReceiver.receiveMessages().take(total).timeout(shortTimeout)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can do following + * 1. create transaction + * 2. send message with transactionContext + * 3. Rollback/commit this transaction. + */ + @MethodSource + @ParameterizedTest + void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { + // Arrange + Duration shortTimeout = Duration.ofSeconds(15); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, USE_CREDENTIALS); + final boolean isSessionEnabled = false; + final String messageId = UUID.randomUUID().toString(); + final int total = 3; + final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); + + // Assert & Act + AtomicReference transaction = new AtomicReference<>(); + StepVerifier.create(sender.createTransaction()) + .assertNext(transactionContext -> { + transaction.set(transactionContext); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + assertNotNull(transaction.get()); + + // Assert & Act + StepVerifier.create(sender.sendMessages(messages, transaction.get())) + .expectComplete() + .verify(TIMEOUT); + if (isCommit) { + StepVerifier.create(sender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(receiver.receiveMessages().take(total)) + .assertNext(receivedMessage -> { + LOGGER.log(LogLevel.VERBOSE, () -> "1"); + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .assertNext(receivedMessage -> { + LOGGER.log(LogLevel.VERBOSE, () -> "2"); + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .assertNext(receivedMessage -> { + LOGGER.log(LogLevel.VERBOSE, () -> "3"); + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(shortTimeout); + } else { + StepVerifier.create(sender.rollbackTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(receiver.receiveMessages().take(total)) + .verifyTimeout(shortTimeout); + } + } + + /** + * Verifies that we can send using credentials. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void sendWithCredentials(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); + + final String messageId = UUID.randomUUID().toString(); + final List messages = TestUtils.getServiceBusMessages(5, messageId, CONTENTS_BYTES); + + // Act & Assert + StepVerifier.create(sender.createMessageBatch() + .flatMap(batch -> { + messages.forEach(m -> Assertions.assertTrue(batch.tryAddMessage(m))); + + return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); + })) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can create transaction, scheduleMessage and commit. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void transactionScheduleAndCommitTest(MessagingEntityType entityType) { + + // Arrange + boolean isSessionEnabled = false; + setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); + final Duration scheduleDuration = Duration.ofSeconds(3); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); + + // Assert & Act + AtomicReference transaction = new AtomicReference<>(); + StepVerifier.create(sender.createTransaction()) + .assertNext(transactionContext -> { + transaction.set(transactionContext); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(5), transaction.get())) + .assertNext(sequenceNumber -> { + assertNotNull(sequenceNumber); + assertTrue(sequenceNumber.intValue() > 0); + }) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(sender.commitTransaction(transaction.get())) + .expectComplete() + .verify(TIMEOUT); + StepVerifier.create(Mono.delay(scheduleDuration).then(receiver.receiveMessages().next())) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } + + /** + * Verifies that we can create transaction, scheduleMessages and commit. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void transactionScheduleMessagesTest(MessagingEntityType entityType) { + + // Arrange + final boolean isSessionEnabled = false; + final int total = 2; + final Duration shortWait = Duration.ofSeconds(3); + + setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, USE_CREDENTIALS); + + final Duration scheduleDuration = Duration.ofSeconds(5); + final String messageId = UUID.randomUUID().toString(); + final List messages = new ArrayList<>(); + for (int i = 0; i < total; ++i) { + messages.add(getMessage(messageId, isSessionEnabled)); + } + + // Assert & Act + AtomicReference transaction = new AtomicReference<>(); + StepVerifier.create(sender.createTransaction()) + .assertNext(transactionContext -> { + transaction.set(transactionContext); + assertNotNull(transaction); + }) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration), transaction.get()).collectList()) + .assertNext(longs -> { + assertEquals(total, longs.size()); + }) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(sender.commitTransaction(transaction.get())) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(Mono.delay(scheduleDuration).thenMany(receiver.receiveMessages().take(total))) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .thenAwait(shortWait) + .thenCancel() + .verify(TIMEOUT); + } + + /** + * Verifies that we can schedule messages and cancel them. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + @ParameterizedTest + void cancelScheduledMessagesTest(MessagingEntityType entityType) { + + // Arrange + final boolean isSessionEnabled = false; + final Duration shortWaitTime = Duration.ofSeconds(5); + final int total = 2; + setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, USE_CREDENTIALS); + final Duration scheduleDuration = Duration.ofSeconds(15); + final String messageId = UUID.randomUUID().toString(); + final List messages = new ArrayList<>(); + for (int i = 0; i < total; ++i) { + messages.add(getMessage(messageId, isSessionEnabled)); + } + List seqNumbers = sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration)).collectList().block(shortWaitTime); + + // Assert & Act + Assertions.assertNotNull(seqNumbers); + Assertions.assertEquals(total, seqNumbers.size()); + + StepVerifier.create(sender.cancelScheduledMessages(seqNumbers)) + .expectComplete() + .verify(TIMEOUT); + + // The messages should have been cancelled and we should not find any messages. + StepVerifier.create(receiver.receiveMessages().take(total)) + .verifyTimeout(shortWaitTime); + } + + /** + * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. + */ + private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { + final boolean isSessionAware = false; + final boolean sharedConnection = true; + + this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) + .buildAsyncClient()); + this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .disableAutoComplete() + .buildAsyncClient()); + } } -// -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.core.util.logging.LogLevel; -//import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; -//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.Disabled; -//import org.junit.jupiter.api.Tag; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.Arguments; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.core.publisher.Mono; -//import reactor.test.StepVerifier; -// -//import java.time.Duration; -//import java.time.OffsetDateTime; -//import java.util.ArrayList; -//import java.util.List; -//import java.util.UUID; -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.concurrent.atomic.AtomicReference; -//import java.util.stream.Stream; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -// -///** -// * Integration tests for {@link ServiceBusSenderAsyncClient} from queues or subscriptions. -// */ -//@Tag("integration") -//class ServiceBusSenderAsyncClientIntegrationTest extends IntegrationTestBase { -// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class); -// -// private ServiceBusSenderAsyncClient sender; -// private ServiceBusReceiverAsyncClient receiver; -// private final AtomicInteger messagesPending = new AtomicInteger(); -// -// ServiceBusSenderAsyncClientIntegrationTest() { -// super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); -// } -// -// @Override -// protected void beforeTest() { -// sessionId = UUID.randomUUID().toString(); -// } -// -// @Override -// protected void afterTest() { -// dispose(sender); -// -// final int numberOfMessages = messagesPending.get(); -// if (numberOfMessages < 1) { -// dispose(receiver); -// return; -// } -// -// try { -// receiver.receiveMessages() -// .take(numberOfMessages) -// .map(message -> { -// logger.info("Message received: {}", message.getSequenceNumber()); -// return message; -// }) -// .timeout(Duration.ofSeconds(5), Mono.empty()) -// .blockLast(); -// } catch (Exception e) { -// logger.warning("Error occurred when draining queue.", e); -// } finally { -// dispose(receiver); -// } -// } -// -// static Stream transactionMessageSendAndCompleteTransaction() { -// return Stream.of( -// Arguments.of(MessagingEntityType.QUEUE, true), -// Arguments.of(MessagingEntityType.SUBSCRIPTION, true), -// Arguments.of(MessagingEntityType.QUEUE, false), -// Arguments.of(MessagingEntityType.SUBSCRIPTION, false) -// ); -// } -// -// /** -// * Verifies that we can send a message to a non-session queue. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void nonSessionQueueSendMessage(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// -// // Assert & Act -// StepVerifier.create(sender.sendMessage(message).doOnSuccess(aVoid -> messagesPending.incrementAndGet())) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send a list of messages to a non-session entity. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void nonSessionEntitySendMessageList(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); -// int count = 4; -// -// final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); -// -// // Assert & Act -// StepVerifier.create(sender.sendMessages(messages) -// .doOnSuccess(aVoid -> messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()))) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void nonSessionMessageBatch(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); -// -// final String messageId = UUID.randomUUID().toString(); -// final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); -// final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); -// -// // Assert & Act -// StepVerifier.create(sender.createMessageBatch(options) -// .flatMap(batch -> { -// for (ServiceBusMessage message : messages) { -// Assertions.assertTrue(batch.tryAddMessage(message)); -// } -// -// return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); -// })) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can send message to final destination using via-queue. -// */ -// @Disabled("The send via functionality is removing for first GA release, later we will come back to it.") -// @Test -// void viaQueueMessageSendTest() { -// // Arrange -// final Duration shortTimeout = Duration.ofSeconds(15); -// final int viaIntermediateEntity = TestUtils.USE_CASE_TXN_1; -// final int destinationEntity = TestUtils.USE_CASE_TXN_2; -// final boolean shareConnection = true; -// final MessagingEntityType entityType = MessagingEntityType.QUEUE; -// final boolean isSessionEnabled = false; -// final String messageId = UUID.randomUUID().toString(); -// final int total = 1; -// final int totalToDestination = 2; -// final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); -// final String viaQueueName = getQueueName(viaIntermediateEntity); -// -// setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); -// -// final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, -// destinationEntity, false, shareConnection) -// //.viaQueueName(viaQueueName) -// .buildAsyncClient()); -// final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, -// destinationEntity, shareConnection) -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .disableAutoComplete() -// .buildAsyncClient()); -// -// final AtomicReference transaction = new AtomicReference<>(); -// -// // Act -// try { -// StepVerifier.create(destination1ViaSender.createTransaction()) -// .assertNext(transactionContext -> { -// transaction.set(transactionContext); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// assertNotNull(transaction.get()); -// -// StepVerifier.create(sender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()) -// .delaySubscription(Duration.ofSeconds(1))) -// .expectComplete() -// .verify(TIMEOUT); -// -// // Assert -// // Verify message is received by final destination Entity -// StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// // Verify, intermediate-via queue has it delivered to intermediate Entity. -// StepVerifier.create(receiver.receiveMessages().take(total).timeout(shortTimeout)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } finally { -// destination1Receiver.close(); -// destination1ViaSender.close(); -// } -// } -// -// -// /** -// * Verifies that we can send message to final destination using via-topic. -// */ -// @Disabled("The send via functionality is removed for first GA release, later we will come back to it.") -// @Test -// void viaTopicMessageSendTest() { -// // Arrange -// final Duration shortTimeout = Duration.ofSeconds(15); -// final int viaIntermediateEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_1; -// final int destinationEntity = TestUtils.USE_CASE_SEND_VIA_TOPIC_2; -// final boolean shareConnection = true; -// final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; -// final boolean isSessionEnabled = false; -// final String messageId = UUID.randomUUID().toString(); -// final int total = 1; -// final int totalToDestination = 2; -// final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); -// final String viaTopicName = getTopicName(viaIntermediateEntity); -// -// setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); -// final ServiceBusReceiverAsyncClient intermediateReceiver = receiver; -// final ServiceBusSenderAsyncClient intermediateSender = sender; -// -// final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, -// destinationEntity, false, shareConnection) -// //.viaTopicName(viaTopicName) -// .buildAsyncClient()); -// -// final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, -// destinationEntity, shareConnection) -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .disableAutoComplete() -// .buildAsyncClient()); -// -// final AtomicReference transaction = new AtomicReference<>(); -// -// // Act -// StepVerifier.create(destination1ViaSender.createTransaction()) -// .assertNext(transactionContext -> { -// transaction.set(transactionContext); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// assertNotNull(transaction.get()); -// -// StepVerifier.create(intermediateSender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(destination1ViaSender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(destination1ViaSender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) -// .expectComplete() -// .verify(TIMEOUT); -// -// // Assert -// // Verify message is received by final destination Entity -// StepVerifier.create(destination1Receiver.receiveMessages().take(totalToDestination).timeout(shortTimeout)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// // Verify, intermediate-via topic has it delivered to intermediate Entity. -// StepVerifier.create(intermediateReceiver.receiveMessages().take(total).timeout(shortTimeout)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can do following -// * 1. create transaction -// * 2. send message with transactionContext -// * 3. Rollback/commit this transaction. -// */ -// @MethodSource -// @ParameterizedTest -// void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { -// // Arrange -// Duration shortTimeout = Duration.ofSeconds(15); -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, USE_CREDENTIALS); -// final boolean isSessionEnabled = false; -// final String messageId = UUID.randomUUID().toString(); -// final int total = 3; -// final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); -// -// // Assert & Act -// AtomicReference transaction = new AtomicReference<>(); -// StepVerifier.create(sender.createTransaction()) -// .assertNext(transactionContext -> { -// transaction.set(transactionContext); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// assertNotNull(transaction.get()); -// -// // Assert & Act -// StepVerifier.create(sender.sendMessages(messages, transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// if (isCommit) { -// StepVerifier.create(sender.commitTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(receiver.receiveMessages().take(total)) -// .assertNext(receivedMessage -> { -// LOGGER.log(LogLevel.VERBOSE, () -> "1"); -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .assertNext(receivedMessage -> { -// LOGGER.log(LogLevel.VERBOSE, () -> "2"); -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .assertNext(receivedMessage -> { -// LOGGER.log(LogLevel.VERBOSE, () -> "3"); -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(shortTimeout); -// } else { -// StepVerifier.create(sender.rollbackTransaction(transaction.get()).delaySubscription(Duration.ofSeconds(1))) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(receiver.receiveMessages().take(total)) -// .verifyTimeout(shortTimeout); -// } -// } -// -// /** -// * Verifies that we can send using credentials. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void sendWithCredentials(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); -// -// final String messageId = UUID.randomUUID().toString(); -// final List messages = TestUtils.getServiceBusMessages(5, messageId, CONTENTS_BYTES); -// -// // Act & Assert -// StepVerifier.create(sender.createMessageBatch() -// .flatMap(batch -> { -// messages.forEach(m -> Assertions.assertTrue(batch.tryAddMessage(m))); -// -// return sender.sendMessages(batch).doOnSuccess(aVoid -> messagesPending.incrementAndGet()); -// })) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can create transaction, scheduleMessage and commit. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void transactionScheduleAndCommitTest(MessagingEntityType entityType) { -// -// // Arrange -// boolean isSessionEnabled = false; -// setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); -// final Duration scheduleDuration = Duration.ofSeconds(3); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); -// -// // Assert & Act -// AtomicReference transaction = new AtomicReference<>(); -// StepVerifier.create(sender.createTransaction()) -// .assertNext(transactionContext -> { -// transaction.set(transactionContext); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(5), transaction.get())) -// .assertNext(sequenceNumber -> { -// assertNotNull(sequenceNumber); -// assertTrue(sequenceNumber.intValue() > 0); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(sender.commitTransaction(transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// StepVerifier.create(Mono.delay(scheduleDuration).then(receiver.receiveMessages().next())) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can create transaction, scheduleMessages and commit. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void transactionScheduleMessagesTest(MessagingEntityType entityType) { -// -// // Arrange -// final boolean isSessionEnabled = false; -// final int total = 2; -// final Duration shortWait = Duration.ofSeconds(3); -// -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, USE_CREDENTIALS); -// -// final Duration scheduleDuration = Duration.ofSeconds(5); -// final String messageId = UUID.randomUUID().toString(); -// final List messages = new ArrayList<>(); -// for (int i = 0; i < total; ++i) { -// messages.add(getMessage(messageId, isSessionEnabled)); -// } -// -// // Assert & Act -// AtomicReference transaction = new AtomicReference<>(); -// StepVerifier.create(sender.createTransaction()) -// .assertNext(transactionContext -> { -// transaction.set(transactionContext); -// assertNotNull(transaction); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration), transaction.get()).collectList()) -// .assertNext(longs -> { -// assertEquals(total, longs.size()); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(sender.commitTransaction(transaction.get())) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(Mono.delay(scheduleDuration).thenMany(receiver.receiveMessages().take(total))) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .thenAwait(shortWait) -// .thenCancel() -// .verify(TIMEOUT); -// } -// -// /** -// * Verifies that we can schedule messages and cancel them. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// @ParameterizedTest -// void cancelScheduledMessagesTest(MessagingEntityType entityType) { -// -// // Arrange -// final boolean isSessionEnabled = false; -// final Duration shortWaitTime = Duration.ofSeconds(5); -// final int total = 2; -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, USE_CREDENTIALS); -// final Duration scheduleDuration = Duration.ofSeconds(15); -// final String messageId = UUID.randomUUID().toString(); -// final List messages = new ArrayList<>(); -// for (int i = 0; i < total; ++i) { -// messages.add(getMessage(messageId, isSessionEnabled)); -// } -// List seqNumbers = sender.scheduleMessages(messages, OffsetDateTime.now().plus(scheduleDuration)).collectList().block(shortWaitTime); -// -// // Assert & Act -// Assertions.assertNotNull(seqNumbers); -// Assertions.assertEquals(total, seqNumbers.size()); -// -// StepVerifier.create(sender.cancelScheduledMessages(seqNumbers)) -// .expectComplete() -// .verify(TIMEOUT); -// -// // The messages should have been cancelled and we should not find any messages. -// StepVerifier.create(receiver.receiveMessages().take(total)) -// .verifyTimeout(shortWaitTime); -// } -// -// /** -// * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. -// */ -// private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { -// final boolean isSessionAware = false; -// final boolean sharedConnection = true; -// -// this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) -// .buildAsyncClient()); -// this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .disableAutoComplete() -// .buildAsyncClient()); -// } -//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java index be71318f9694..6ca8c647a87b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java @@ -3,211 +3,208 @@ package com.azure.messaging.servicebus; -class ServiceBusSenderClientIntegrationTest { +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.publisher.Mono; + +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; + +/** + * Integration tests for the {@link ServiceBusSenderClient}. + */ +@Tag("integration") +class ServiceBusSenderClientIntegrationTest extends IntegrationTestBase { + private ServiceBusSenderClient sender; + private ServiceBusReceiverAsyncClient receiver; + private final AtomicInteger messagesPending = new AtomicInteger(); + + ServiceBusSenderClientIntegrationTest() { + super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); + } + + @Override + protected void afterTest() { + dispose(sender); + + final int numberOfMessages = messagesPending.get(); + if (numberOfMessages < 1) { + dispose(receiver); + return; + } + try { + receiver.receiveMessages() + .take(messagesPending.get()) + .map(message -> { + logger.info("Message received: {}", message.getSequenceNumber()); + return message; + }) + .timeout(Duration.ofSeconds(5), Mono.empty()) + .blockLast(); + } catch (Exception e) { + logger.warning("Error occurred when draining queue.", e); + } finally { + dispose(receiver); + } + } + + static Stream receiverTypesProvider() { + return Stream.of( + Arguments.of(MessagingEntityType.QUEUE), + Arguments.of(MessagingEntityType.SUBSCRIPTION) + ); + } + + /** + * Verifies that we can send a message to a non-session queue. + */ + @MethodSource("receiverTypesProvider") + @ParameterizedTest + void nonSessionQueueSendMessage(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); + + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + + // Assert & Act + sender.sendMessage(message); + + messagesPending.incrementAndGet(); + } + + /** + * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. + */ + @MethodSource("receiverTypesProvider") + @ParameterizedTest + void nonSessionMessageBatch(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); + + final String messageId = UUID.randomUUID().toString(); + final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); + final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); + + // Assert & Act + ServiceBusMessageBatch batch = sender.createMessageBatch(options); + for (ServiceBusMessage message : messages) { + Assertions.assertTrue(batch.tryAddMessage(message)); + } + + sender.sendMessages(batch); + + for (int i = 0; i < messages.size(); i++) { + messagesPending.incrementAndGet(); + } + } + + /** + * Verifies that we can send a list of messages to a non-session entity. + */ + @MethodSource("receiverTypesProvider") + @ParameterizedTest + void nonSessionEntitySendMessageList(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); + int count = 3; + final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); + + // Assert & Act + sender.sendMessages(messages); + + messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()); + } + + /** + * Verifies that we can schedule a message to a non-session entity. + */ + @MethodSource("receiverTypesProvider") + @ParameterizedTest + void nonSessionScheduleMessage(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); + + final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + + // Act + long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); + + // Assert + Assertions.assertTrue(sequenceNumber >= 0); + + messagesPending.incrementAndGet(); + } + + /** + * Verifies that we can cancel a scheduled a message to a non-session entity. + */ + @MethodSource("receiverTypesProvider") + @ParameterizedTest + void nonSessionCancelScheduleMessage(MessagingEntityType entityType) { + // Arrange + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); + + final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(20); + final String messageId = UUID.randomUUID().toString(); + final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + + // Assert & Act + long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); + Assertions.assertTrue(sequenceNumber >= 0); + + sender.cancelScheduledMessage(sequenceNumber); + + messagesPending.incrementAndGet(); + } + + void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex) { + switch (entityType) { + case QUEUE: + final String queueName = getQueueName(entityIndex); + + Assertions.assertNotNull(queueName, "'queueName' cannot be null."); + + sender = toClose(getBuilder().sender() + .queueName(queueName) + .buildClient()); + receiver = toClose(getBuilder().receiver() + .queueName(queueName) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .buildAsyncClient()); + break; + case SUBSCRIPTION: + final String topicName = getTopicName(entityIndex); + final String subscriptionName = TestUtils.getSubscriptionBaseName(); + + Assertions.assertNotNull(topicName, "'topicName' cannot be null."); + Assertions.assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); + + sender = toClose(getBuilder().sender() + .topicName(topicName) + .buildClient()); + receiver = toClose(getBuilder().receiver() + .topicName(topicName) + .subscriptionName(subscriptionName) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .buildAsyncClient()); + break; + default: + throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); + } + } } -// -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; -//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.Tag; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.Arguments; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.core.publisher.Mono; -// -//import java.time.Duration; -//import java.time.OffsetDateTime; -//import java.util.List; -//import java.util.UUID; -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.stream.Stream; -// -///** -// * Integration tests for the {@link ServiceBusSenderClient}. -// */ -//@Tag("integration") -//class ServiceBusSenderClientIntegrationTest extends IntegrationTestBase { -// private ServiceBusSenderClient sender; -// private ServiceBusReceiverAsyncClient receiver; -// private final AtomicInteger messagesPending = new AtomicInteger(); -// -// ServiceBusSenderClientIntegrationTest() { -// super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); -// } -// -// @Override -// protected void afterTest() { -// dispose(sender); -// -// final int numberOfMessages = messagesPending.get(); -// if (numberOfMessages < 1) { -// dispose(receiver); -// return; -// } -// try { -// receiver.receiveMessages() -// .take(messagesPending.get()) -// .map(message -> { -// logger.info("Message received: {}", message.getSequenceNumber()); -// return message; -// }) -// .timeout(Duration.ofSeconds(5), Mono.empty()) -// .blockLast(); -// } catch (Exception e) { -// logger.warning("Error occurred when draining queue.", e); -// } finally { -// dispose(receiver); -// } -// } -// -// static Stream receiverTypesProvider() { -// return Stream.of( -// Arguments.of(MessagingEntityType.QUEUE), -// Arguments.of(MessagingEntityType.SUBSCRIPTION) -// ); -// } -// -// /** -// * Verifies that we can send a message to a non-session queue. -// */ -// @MethodSource("receiverTypesProvider") -// @ParameterizedTest -// void nonSessionQueueSendMessage(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); -// -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// -// // Assert & Act -// sender.sendMessage(message); -// -// messagesPending.incrementAndGet(); -// } -// -// /** -// * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. -// */ -// @MethodSource("receiverTypesProvider") -// @ParameterizedTest -// void nonSessionMessageBatch(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); -// -// final String messageId = UUID.randomUUID().toString(); -// final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); -// final List messages = TestUtils.getServiceBusMessages(3, messageId, CONTENTS_BYTES); -// -// // Assert & Act -// ServiceBusMessageBatch batch = sender.createMessageBatch(options); -// for (ServiceBusMessage message : messages) { -// Assertions.assertTrue(batch.tryAddMessage(message)); -// } -// -// sender.sendMessages(batch); -// -// for (int i = 0; i < messages.size(); i++) { -// messagesPending.incrementAndGet(); -// } -// } -// -// /** -// * Verifies that we can send a list of messages to a non-session entity. -// */ -// @MethodSource("receiverTypesProvider") -// @ParameterizedTest -// void nonSessionEntitySendMessageList(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); -// int count = 3; -// final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); -// -// // Assert & Act -// sender.sendMessages(messages); -// -// messages.forEach(serviceBusMessage -> messagesPending.incrementAndGet()); -// } -// -// /** -// * Verifies that we can schedule a message to a non-session entity. -// */ -// @MethodSource("receiverTypesProvider") -// @ParameterizedTest -// void nonSessionScheduleMessage(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); -// -// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(10); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// -// // Act -// long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); -// -// // Assert -// Assertions.assertTrue(sequenceNumber >= 0); -// -// messagesPending.incrementAndGet(); -// } -// -// /** -// * Verifies that we can cancel a scheduled a message to a non-session entity. -// */ -// @MethodSource("receiverTypesProvider") -// @ParameterizedTest -// void nonSessionCancelScheduleMessage(MessagingEntityType entityType) { -// // Arrange -// setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); -// -// final OffsetDateTime scheduledEnqueueTime = OffsetDateTime.now().plusSeconds(20); -// final String messageId = UUID.randomUUID().toString(); -// final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// -// // Assert & Act -// long sequenceNumber = sender.scheduleMessage(message, scheduledEnqueueTime); -// Assertions.assertTrue(sequenceNumber >= 0); -// -// sender.cancelScheduledMessage(sequenceNumber); -// -// messagesPending.incrementAndGet(); -// } -// -// void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex) { -// switch (entityType) { -// case QUEUE: -// final String queueName = getQueueName(entityIndex); -// -// Assertions.assertNotNull(queueName, "'queueName' cannot be null."); -// -// sender = toClose(getBuilder().sender() -// .queueName(queueName) -// .buildClient()); -// receiver = toClose(getBuilder().receiver() -// .queueName(queueName) -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .buildAsyncClient()); -// break; -// case SUBSCRIPTION: -// final String topicName = getTopicName(entityIndex); -// final String subscriptionName = TestUtils.getSubscriptionBaseName(); -// -// Assertions.assertNotNull(topicName, "'topicName' cannot be null."); -// Assertions.assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); -// -// sender = toClose(getBuilder().sender() -// .topicName(topicName) -// .buildClient()); -// receiver = toClose(getBuilder().receiver() -// .topicName(topicName) -// .subscriptionName(subscriptionName) -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .buildAsyncClient()); -// break; -// default: -// throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); -// } -// } -//} From 4315c9d9c5bfee2728576f7d9e379b834f7ae977 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 13:50:50 -0700 Subject: [PATCH 06/29] Enable ServiceBus[SessionManager|Processor|MixedClient|Builder]IntegrationTest --- .../ServiceBusClientBuilderTest.java | 796 +++++++-------- .../ServiceBusMixClientIntegrationTest.java | 963 +++++++++--------- ...viceBusProcessorClientIntegrationTest.java | 411 ++++---- ...rviceBusSessionManagerIntegrationTest.java | 425 ++++---- 4 files changed, 1289 insertions(+), 1306 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index a4d33a0e4afa..4b3ae1225e05 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -3,405 +3,401 @@ package com.azure.messaging.servicebus; -class ServiceBusClientBuilderTest { +import com.azure.core.amqp.AmqpTransportType; +import com.azure.core.amqp.ProxyAuthenticationType; +import com.azure.core.amqp.ProxyOptions; +import com.azure.core.amqp.implementation.ConnectionStringProperties; +import com.azure.core.credential.AzureNamedKeyCredential; +import com.azure.core.credential.AzureSasCredential; +import com.azure.core.util.Configuration; +import com.azure.core.util.CoreUtils; +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; +import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import com.azure.messaging.servicebus.models.SubQueue; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.test.StepVerifier; + +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Locale; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import static java.nio.charset.StandardCharsets.UTF_8; + +class ServiceBusClientBuilderTest extends IntegrationTestBase { + private static final String NAMESPACE_NAME = "dummyNamespaceName"; + private static final String DEFAULT_DOMAIN_NAME = TestUtils.getEndpoint().substring(1) + "/"; + private static final String ENDPOINT_FORMAT = "sb://%s.%s"; + private static final String QUEUE_NAME = "test-queue-name"; + private static final String VIA_QUEUE_NAME = "test-via-queue-name"; + private static final String TOPIC_NAME = "test-topic-name"; + private static final String VIA_TOPIC_NAME = "test-via-queue-name"; + private static final String SHARED_ACCESS_KEY_NAME = "dummySasKeyName"; + private static final String SHARED_ACCESS_KEY = "dummySasKey"; + private static final String ENDPOINT = getUri(ENDPOINT_FORMAT, NAMESPACE_NAME, DEFAULT_DOMAIN_NAME).toString(); + private static final String DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$deadletterqueue"; + private static final String TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$Transfer/$deadletterqueue"; + private static final String JAVA_NET_USER_SYSTEM_PROXIES = "java.net.useSystemProxies"; + + private static final String PROXY_HOST = "127.0.0.1"; + private static final String PROXY_PORT = "3128"; + + private static final String NAMESPACE_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s", + ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY); + private static final String ENTITY_PATH_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s", + ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY, QUEUE_NAME); + private static final Proxy PROXY_ADDRESS = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, Integer.parseInt(PROXY_PORT))); + + private static final String TEST_MESSAGE = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \nUt sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \nAenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \nAenean fringilla quam elit, id mattis purus vestibulum nec. Praesent porta eros in dapibus molestie. Vestibulum orci libero, tincidunt et turpis eget, condimentum lobortis enim. Fusce suscipit ante et mauris consequat cursus nec laoreet lorem. Maecenas in sollicitudin diam, non tincidunt purus. Nunc mauris purus, laoreet eget interdum vitae, placerat a sapien. In mi risus, blandit eu facilisis nec, molestie suscipit leo. Pellentesque molestie urna vitae dui faucibus bibendum. \nDonec quis ipsum ultricies, imperdiet ex vel, scelerisque eros. Ut at urna arcu. Vestibulum rutrum odio dolor, vitae cursus nunc pulvinar vel. Donec accumsan sapien in malesuada tempor. Maecenas in condimentum eros. Sed vestibulum facilisis massa a iaculis. Etiam et nibh felis. Donec maximus, sem quis vestibulum gravida, turpis risus congue dolor, pharetra tincidunt lectus nisi at velit."; + + ServiceBusClientBuilderTest() { + super(new ClientLogger(ServiceBusClientBuilderTest.class)); + } + + @Test + void ensureIdentifierString() { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + final ServiceBusSenderAsyncClient client = toClose(builder + .connectionString(NAMESPACE_CONNECTION_STRING) + .sender() + .queueName(QUEUE_NAME) + .buildAsyncClient()); + + Assertions.assertFalse(CoreUtils.isNullOrEmpty(client.getIdentifier())); + } + + @Test + void deadLetterQueueClient() { + // Arrange + final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .receiver() + .queueName(QUEUE_NAME) + .subQueue(SubQueue.DEAD_LETTER_QUEUE); + + + // Act + final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); + + // Assert + assertTrue(client.getEntityPath().endsWith(DEAD_LETTER_QUEUE_NAME_SUFFIX)); + } + + @Test + void transferDeadLetterqueueClient() { + // Arrange + final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .receiver() + .queueName(QUEUE_NAME) + .subQueue(SubQueue.TRANSFER_DEAD_LETTER_QUEUE); + + // Act + final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); + + // Assert + assertTrue(client.getEntityPath().endsWith(TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX)); + } + + @Test + void missingConnectionString() { + assertThrows(IllegalArgumentException.class, () -> { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + builder.sender() + .queueName(QUEUE_NAME) + .buildAsyncClient(); + }); + } + + @Test + void defaultProxyConfigurationBuilder() { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + final ServiceBusSenderAsyncClient client = builder.connectionString(NAMESPACE_CONNECTION_STRING) + .sender() + .queueName(QUEUE_NAME) + .buildAsyncClient(); + + assertNotNull(client); + } + + @Test + void customNoneProxyConfigurationBuilder() { + // Arrange + final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.NONE, PROXY_ADDRESS, + null, null); + + // Act + final ServiceBusSenderClientBuilder builder = new ServiceBusClientBuilder() + .connectionString(ENTITY_PATH_CONNECTION_STRING) + .proxyOptions(proxyConfig) + .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) + .sender(); + + // Assert + assertNotNull(builder.buildAsyncClient()); + } + + @Test + void throwsWithProxyWhenTransportTypeNotChanged() { + assertThrows(IllegalArgumentException.class, () -> { + // Arrange + final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.BASIC, PROXY_ADDRESS, + null, null); + + // Act + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder() + .connectionString(ENTITY_PATH_CONNECTION_STRING) + .proxyOptions(proxyConfig); + + // Assert + assertNotNull(builder.sender().buildAsyncClient()); + }); + } + + private static Stream invalidEntityPathConfigurations() { + return Stream.of( + // When no queue or topic name is set for a sender or receiver. + Arguments.of(NAMESPACE_CONNECTION_STRING, null, null, null), + + // When both queue or topic name is set for a sender or receiver. + Arguments.of(NAMESPACE_CONNECTION_STRING, "baz", "bar", "foo"), + + // When queue name does not match an entity path connection string. + Arguments.of(ENTITY_PATH_CONNECTION_STRING, "baz", null, null), + + // When topic name does not match an entity path connection string. + Arguments.of(ENTITY_PATH_CONNECTION_STRING, null, "bar", "foo")); + } + + /** + * Tests different invalid entity path scenarios. + */ + @ParameterizedTest + @MethodSource + void invalidEntityPathConfigurations(String connectionString, String topicName, String queueName, + String subscriptionName) { + + // Arrange + final ServiceBusSenderClientBuilder senderBuilder = new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .sender(); + final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .receiver(); + + // Act & Assert + assertThrows(IllegalStateException.class, senderBuilder::buildAsyncClient); + assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); + } + + /** + * Throws when topic name is set for receiver, but no subscription name is set. + */ + @Test + void throwsWhenSubscriptionNameNotSet() { + // Arrange + final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .receiver() + .topicName("baz"); + + // Act & Assert + assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); + } + + /** + * Throws when the prefetch is less than 1. + */ + @Test + void invalidPrefetch() { + // Arrange + final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .receiver() + .topicName("baz").subscriptionName("bar") + .receiveMode(ServiceBusReceiveMode.PEEK_LOCK); + + // Act & Assert + assertThrows(IllegalArgumentException.class, () -> receiverBuilder.prefetchCount(-1)); + } + + @MethodSource("getProxyConfigurations") + @ParameterizedTest + public void testProxyOptionsConfiguration(String proxyConfiguration) { + Configuration configuration = TestUtils.getGlobalConfiguration().clone() + .put(Configuration.PROPERTY_HTTP_PROXY, proxyConfiguration) + .put(JAVA_NET_USER_SYSTEM_PROXIES, "true"); + + // Client creation should not fail with incorrect proxy configuration + toClose(new ServiceBusClientBuilder() + .connectionString(NAMESPACE_CONNECTION_STRING) + .configuration(configuration) + .receiver() + .topicName("baz").subscriptionName("bar") + .receiveMode(ServiceBusReceiveMode.PEEK_LOCK) + .buildClient()); + } + + @Test + public void testConnectionStringWithSas() { + String connectionStringWithEntityPath = "Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;" + + "SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name"; + assertNotNull(new ServiceBusClientBuilder() + .connectionString(connectionStringWithEntityPath)); + + assertThrows(IllegalArgumentException.class, + () -> new ServiceBusClientBuilder() + .connectionString("SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name")); + + assertThrows(IllegalArgumentException.class, + () -> new ServiceBusClientBuilder() + .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); + } + + @Test + @Disabled("Convert to use AzurePowerShellCredentials?") + public void testBatchSendEventByAzureNameKeyCredential() { + ConnectionStringProperties properties = getConnectionStringProperties(); + String fullyQualifiedNamespace = getFullyQualifiedDomainName(); + String sharedAccessKeyName = properties.getSharedAccessKeyName(); + String sharedAccessKey = properties.getSharedAccessKey(); + String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); + + final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); + + ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey)) + .sender() + .queueName(queueName) + .buildAsyncClient()); + StepVerifier.create( + senderAsyncClient.createMessageBatch().flatMap(batch -> { + assertTrue(batch.tryAddMessage(testData)); + return senderAsyncClient.sendMessages(batch); + })) + .expectComplete() + .verify(TIMEOUT); + } + + @Test + @Disabled("Convert to use AzurePowerShellCredentials?") + public void testBatchSendEventByAzureSasCredential() { + ConnectionStringProperties properties = getConnectionStringProperties(true); + String fullyQualifiedNamespace = getFullyQualifiedDomainName(); + String sharedAccessSignature = properties.getSharedAccessSignature(); + String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); + + final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); + + ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, + new AzureSasCredential(sharedAccessSignature)) + .sender() + .queueName(queueName) + .buildAsyncClient()); + + StepVerifier.create( + senderAsyncClient.createMessageBatch().flatMap(batch -> { + assertTrue(batch.tryAddMessage(testData)); + return senderAsyncClient.sendMessages(batch); + })) + .expectComplete() + .verify(TIMEOUT); + } + + @Test + public void testConnectionWithAzureNameKeyCredential() { + String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); + String sharedAccessKeyName = "SharedAccessKeyName test-value"; + String sharedAccessKey = "SharedAccessKey test-value"; + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(null, + new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); + + assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() + .credential("", + new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, + new AzureNamedKeyCredential(null, sharedAccessKey))); + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, + new AzureNamedKeyCredential(sharedAccessKeyName, null))); + + assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, + new AzureNamedKeyCredential("", sharedAccessKey))); + + assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, + new AzureNamedKeyCredential(sharedAccessKeyName, ""))); + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, (AzureNamedKeyCredential) null)); + + } + + @Test + public void testConnectionWithAzureSasCredential() { + String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); + String sharedAccessSignature = "SharedAccessSignature test-value"; + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(null, new AzureSasCredential(sharedAccessSignature))); + + assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() + .credential("", new AzureSasCredential(sharedAccessSignature))); + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, new AzureSasCredential(null))); + + assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, new AzureSasCredential(""))); + + assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, (AzureSasCredential) null)); + + } + + private static Stream getProxyConfigurations() { + return Stream.of( + Arguments.of("http://localhost:8080"), + Arguments.of("localhost:8080"), + Arguments.of("localhost_8080"), + Arguments.of("http://example.com:8080"), + Arguments.of("http://sub.example.com:8080"), + Arguments.of(":8080"), + Arguments.of("http://localhost"), + Arguments.of("sub.example.com:8080"), + Arguments.of("https://username:password@sub.example.com:8080"), + Arguments.of("https://username:password@sub.example.com") + ); + + } + + private static URI getUri(String endpointFormat, String namespace, String domainName) { + try { + return new URI(String.format(Locale.US, endpointFormat, namespace, domainName)); + } catch (URISyntaxException exception) { + throw new IllegalArgumentException(String.format(Locale.US, + "Invalid namespace name: %s", namespace), exception); + } + } } -// -//import com.azure.core.amqp.AmqpTransportType; -//import com.azure.core.amqp.ProxyAuthenticationType; -//import com.azure.core.amqp.ProxyOptions; -//import com.azure.core.amqp.implementation.ConnectionStringProperties; -//import com.azure.core.credential.AzureNamedKeyCredential; -//import com.azure.core.credential.AzureSasCredential; -//import com.azure.core.util.Configuration; -//import com.azure.core.util.CoreUtils; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; -//import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; -//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -//import com.azure.messaging.servicebus.models.SubQueue; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.Disabled; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.Arguments; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.test.StepVerifier; -// -//import java.net.InetSocketAddress; -//import java.net.Proxy; -//import java.net.URI; -//import java.net.URISyntaxException; -//import java.util.Locale; -//import java.util.stream.Stream; -// -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertThrows; -//import static org.junit.jupiter.api.Assertions.assertTrue; -// -//import static java.nio.charset.StandardCharsets.UTF_8; -// -//class ServiceBusClientBuilderTest extends IntegrationTestBase { -// private static final String NAMESPACE_NAME = "dummyNamespaceName"; -// private static final String DEFAULT_DOMAIN_NAME = TestUtils.getEndpoint().substring(1) + "/"; -// private static final String ENDPOINT_FORMAT = "sb://%s.%s"; -// private static final String QUEUE_NAME = "test-queue-name"; -// private static final String VIA_QUEUE_NAME = "test-via-queue-name"; -// private static final String TOPIC_NAME = "test-topic-name"; -// private static final String VIA_TOPIC_NAME = "test-via-queue-name"; -// private static final String SHARED_ACCESS_KEY_NAME = "dummySasKeyName"; -// private static final String SHARED_ACCESS_KEY = "dummySasKey"; -// private static final String ENDPOINT = getUri(ENDPOINT_FORMAT, NAMESPACE_NAME, DEFAULT_DOMAIN_NAME).toString(); -// private static final String DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$deadletterqueue"; -// private static final String TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX = "/$Transfer/$deadletterqueue"; -// private static final String JAVA_NET_USER_SYSTEM_PROXIES = "java.net.useSystemProxies"; -// -// private static final String PROXY_HOST = "127.0.0.1"; -// private static final String PROXY_PORT = "3128"; -// -// private static final String NAMESPACE_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s", -// ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY); -// private static final String ENTITY_PATH_CONNECTION_STRING = String.format("Endpoint=%s;SharedAccessKeyName=%s;SharedAccessKey=%s;EntityPath=%s", -// ENDPOINT, SHARED_ACCESS_KEY_NAME, SHARED_ACCESS_KEY, QUEUE_NAME); -// private static final Proxy PROXY_ADDRESS = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, Integer.parseInt(PROXY_PORT))); -// -// private static final String TEST_MESSAGE = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \nUt sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \nAenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \nAenean fringilla quam elit, id mattis purus vestibulum nec. Praesent porta eros in dapibus molestie. Vestibulum orci libero, tincidunt et turpis eget, condimentum lobortis enim. Fusce suscipit ante et mauris consequat cursus nec laoreet lorem. Maecenas in sollicitudin diam, non tincidunt purus. Nunc mauris purus, laoreet eget interdum vitae, placerat a sapien. In mi risus, blandit eu facilisis nec, molestie suscipit leo. Pellentesque molestie urna vitae dui faucibus bibendum. \nDonec quis ipsum ultricies, imperdiet ex vel, scelerisque eros. Ut at urna arcu. Vestibulum rutrum odio dolor, vitae cursus nunc pulvinar vel. Donec accumsan sapien in malesuada tempor. Maecenas in condimentum eros. Sed vestibulum facilisis massa a iaculis. Etiam et nibh felis. Donec maximus, sem quis vestibulum gravida, turpis risus congue dolor, pharetra tincidunt lectus nisi at velit."; -// -// ServiceBusClientBuilderTest() { -// super(new ClientLogger(ServiceBusClientBuilderTest.class)); -// } -// -// @Test -// void ensureIdentifierString() { -// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); -// final ServiceBusSenderAsyncClient client = toClose(builder -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .sender() -// .queueName(QUEUE_NAME) -// .buildAsyncClient()); -// -// Assertions.assertFalse(CoreUtils.isNullOrEmpty(client.getIdentifier())); -// } -// -// @Test -// void deadLetterQueueClient() { -// // Arrange -// final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .receiver() -// .queueName(QUEUE_NAME) -// .subQueue(SubQueue.DEAD_LETTER_QUEUE); -// -// -// // Act -// final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); -// -// // Assert -// assertTrue(client.getEntityPath().endsWith(DEAD_LETTER_QUEUE_NAME_SUFFIX)); -// } -// -// @Test -// void transferDeadLetterqueueClient() { -// // Arrange -// final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .receiver() -// .queueName(QUEUE_NAME) -// .subQueue(SubQueue.TRANSFER_DEAD_LETTER_QUEUE); -// -// // Act -// final ServiceBusReceiverAsyncClient client = toClose(builder.buildAsyncClient()); -// -// // Assert -// assertTrue(client.getEntityPath().endsWith(TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX)); -// } -// -// @Test -// void missingConnectionString() { -// assertThrows(IllegalArgumentException.class, () -> { -// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); -// builder.sender() -// .queueName(QUEUE_NAME) -// .buildAsyncClient(); -// }); -// } -// -// @Test -// void defaultProxyConfigurationBuilder() { -// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); -// final ServiceBusSenderAsyncClient client = builder.connectionString(NAMESPACE_CONNECTION_STRING) -// .sender() -// .queueName(QUEUE_NAME) -// .buildAsyncClient(); -// -// assertNotNull(client); -// } -// -// @Test -// void customNoneProxyConfigurationBuilder() { -// // Arrange -// final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.NONE, PROXY_ADDRESS, -// null, null); -// -// // Act -// final ServiceBusSenderClientBuilder builder = new ServiceBusClientBuilder() -// .connectionString(ENTITY_PATH_CONNECTION_STRING) -// .proxyOptions(proxyConfig) -// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) -// .sender(); -// -// // Assert -// assertNotNull(builder.buildAsyncClient()); -// } -// -// @Test -// void throwsWithProxyWhenTransportTypeNotChanged() { -// assertThrows(IllegalArgumentException.class, () -> { -// // Arrange -// final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.BASIC, PROXY_ADDRESS, -// null, null); -// -// // Act -// final ServiceBusClientBuilder builder = new ServiceBusClientBuilder() -// .connectionString(ENTITY_PATH_CONNECTION_STRING) -// .proxyOptions(proxyConfig); -// -// // Assert -// assertNotNull(builder.sender().buildAsyncClient()); -// }); -// } -// -// private static Stream invalidEntityPathConfigurations() { -// return Stream.of( -// // When no queue or topic name is set for a sender or receiver. -// Arguments.of(NAMESPACE_CONNECTION_STRING, null, null, null), -// -// // When both queue or topic name is set for a sender or receiver. -// Arguments.of(NAMESPACE_CONNECTION_STRING, "baz", "bar", "foo"), -// -// // When queue name does not match an entity path connection string. -// Arguments.of(ENTITY_PATH_CONNECTION_STRING, "baz", null, null), -// -// // When topic name does not match an entity path connection string. -// Arguments.of(ENTITY_PATH_CONNECTION_STRING, null, "bar", "foo")); -// } -// -// /** -// * Tests different invalid entity path scenarios. -// */ -// @ParameterizedTest -// @MethodSource -// void invalidEntityPathConfigurations(String connectionString, String topicName, String queueName, -// String subscriptionName) { -// -// // Arrange -// final ServiceBusSenderClientBuilder senderBuilder = new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .sender(); -// final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .receiver(); -// -// // Act & Assert -// assertThrows(IllegalStateException.class, senderBuilder::buildAsyncClient); -// assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); -// } -// -// /** -// * Throws when topic name is set for receiver, but no subscription name is set. -// */ -// @Test -// void throwsWhenSubscriptionNameNotSet() { -// // Arrange -// final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .receiver() -// .topicName("baz"); -// -// // Act & Assert -// assertThrows(IllegalStateException.class, receiverBuilder::buildAsyncClient); -// } -// -// /** -// * Throws when the prefetch is less than 1. -// */ -// @Test -// void invalidPrefetch() { -// // Arrange -// final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .receiver() -// .topicName("baz").subscriptionName("bar") -// .receiveMode(ServiceBusReceiveMode.PEEK_LOCK); -// -// // Act & Assert -// assertThrows(IllegalArgumentException.class, () -> receiverBuilder.prefetchCount(-1)); -// } -// -// @MethodSource("getProxyConfigurations") -// @ParameterizedTest -// public void testProxyOptionsConfiguration(String proxyConfiguration) { -// Configuration configuration = TestUtils.getGlobalConfiguration().clone() -// .put(Configuration.PROPERTY_HTTP_PROXY, proxyConfiguration) -// .put(JAVA_NET_USER_SYSTEM_PROXIES, "true"); -// -// // Client creation should not fail with incorrect proxy configuration -// toClose(new ServiceBusClientBuilder() -// .connectionString(NAMESPACE_CONNECTION_STRING) -// .configuration(configuration) -// .receiver() -// .topicName("baz").subscriptionName("bar") -// .receiveMode(ServiceBusReceiveMode.PEEK_LOCK) -// .buildClient()); -// } -// -// @Test -// public void testConnectionStringWithSas() { -// String connectionStringWithEntityPath = "Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;" -// + "SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name"; -// assertNotNull(new ServiceBusClientBuilder() -// .connectionString(connectionStringWithEntityPath)); -// -// assertThrows(IllegalArgumentException.class, -// () -> new ServiceBusClientBuilder() -// .connectionString("SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name")); -// -// assertThrows(IllegalArgumentException.class, -// () -> new ServiceBusClientBuilder() -// .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); -// } -// -// @Test -// @Disabled("Convert to use AzurePowerShellCredentials?") -// public void testBatchSendEventByAzureNameKeyCredential() { -// ConnectionStringProperties properties = getConnectionStringProperties(); -// String fullyQualifiedNamespace = getFullyQualifiedDomainName(); -// String sharedAccessKeyName = properties.getSharedAccessKeyName(); -// String sharedAccessKey = properties.getSharedAccessKey(); -// String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); -// -// final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); -// -// ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey)) -// .sender() -// .queueName(queueName) -// .buildAsyncClient()); -// StepVerifier.create( -// senderAsyncClient.createMessageBatch().flatMap(batch -> { -// assertTrue(batch.tryAddMessage(testData)); -// return senderAsyncClient.sendMessages(batch); -// })) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// @Test -// @Disabled("Convert to use AzurePowerShellCredentials?") -// public void testBatchSendEventByAzureSasCredential() { -// ConnectionStringProperties properties = getConnectionStringProperties(true); -// String fullyQualifiedNamespace = getFullyQualifiedDomainName(); -// String sharedAccessSignature = properties.getSharedAccessSignature(); -// String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); -// -// final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); -// -// ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, -// new AzureSasCredential(sharedAccessSignature)) -// .sender() -// .queueName(queueName) -// .buildAsyncClient()); -// -// StepVerifier.create( -// senderAsyncClient.createMessageBatch().flatMap(batch -> { -// assertTrue(batch.tryAddMessage(testData)); -// return senderAsyncClient.sendMessages(batch); -// })) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// @Test -// public void testConnectionWithAzureNameKeyCredential() { -// String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); -// String sharedAccessKeyName = "SharedAccessKeyName test-value"; -// String sharedAccessKey = "SharedAccessKey test-value"; -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(null, -// new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); -// -// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() -// .credential("", -// new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey))); -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, -// new AzureNamedKeyCredential(null, sharedAccessKey))); -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, -// new AzureNamedKeyCredential(sharedAccessKeyName, null))); -// -// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, -// new AzureNamedKeyCredential("", sharedAccessKey))); -// -// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, -// new AzureNamedKeyCredential(sharedAccessKeyName, ""))); -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, (AzureNamedKeyCredential) null)); -// -// } -// -// @Test -// public void testConnectionWithAzureSasCredential() { -// String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); -// String sharedAccessSignature = "SharedAccessSignature test-value"; -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(null, new AzureSasCredential(sharedAccessSignature))); -// -// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() -// .credential("", new AzureSasCredential(sharedAccessSignature))); -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, new AzureSasCredential(null))); -// -// assertThrows(IllegalArgumentException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, new AzureSasCredential(""))); -// -// assertThrows(NullPointerException.class, () -> new ServiceBusClientBuilder() -// .credential(fullyQualifiedNamespace, (AzureSasCredential) null)); -// -// } -// -// private static Stream getProxyConfigurations() { -// return Stream.of( -// Arguments.of("http://localhost:8080"), -// Arguments.of("localhost:8080"), -// Arguments.of("localhost_8080"), -// Arguments.of("http://example.com:8080"), -// Arguments.of("http://sub.example.com:8080"), -// Arguments.of(":8080"), -// Arguments.of("http://localhost"), -// Arguments.of("sub.example.com:8080"), -// Arguments.of("https://username:password@sub.example.com:8080"), -// Arguments.of("https://username:password@sub.example.com") -// ); -// -// } -// -// private static URI getUri(String endpointFormat, String namespace, String domainName) { -// try { -// return new URI(String.format(Locale.US, endpointFormat, namespace, domainName)); -// } catch (URISyntaxException exception) { -// throw new IllegalArgumentException(String.format(Locale.US, -// "Invalid namespace name: %s", namespace), exception); -// } -// } -// -//} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java index cb2ec6fccef9..bf0e6bfe1f20 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java @@ -3,489 +3,484 @@ package com.azure.messaging.servicebus; -public class ServiceBusMixClientIntegrationTest { +import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.logging.LogLevel; +import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import com.azure.messaging.servicebus.models.CompleteOptions; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import reactor.core.Disposable; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; -} +import java.time.Duration; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; + +/** + * Test where various clients are involved for example Sender, Receiver and Processor client. + */ +public class ServiceBusMixClientIntegrationTest extends IntegrationTestBase { + private static final ClientLogger LOGGER = new ClientLogger(ServiceBusMixClientIntegrationTest.class); + + private ServiceBusSenderAsyncClient sender; + private ServiceBusReceiverAsyncClient receiver; + private final AtomicInteger messagesPending = new AtomicInteger(); + + ServiceBusMixClientIntegrationTest() { + super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); + } + + @Override + protected void beforeTest() { + sessionId = UUID.randomUUID().toString(); + } + + @Override + protected void afterTest() { + dispose(sender); + + final int numberOfMessages = messagesPending.get(); + if (numberOfMessages < 1) { + dispose(receiver); + return; + } + + try { + if (receiver == null) { + return; + } + receiver.receiveMessages() + .take(numberOfMessages) + .map(message -> { + logger.info("Message received: {}", message.getSequenceNumber()); + return message; + }) + .timeout(Duration.ofSeconds(5), Mono.empty()) + .blockLast(); + } catch (Exception e) { + logger.warning("Error occurred when draining queue.", e); + } finally { + dispose(receiver); + } + } + + /** + * Use case: Test cross entity transaction using processor client and sender. + * 1. Read messages from entity A. + * 2. complete the messages from entity A and write to entity B. + * 2. commit the transaction. + */ + @ParameterizedTest + @ValueSource(strings = {"true", "false"}) + void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { + + // Arrange + final MessagingEntityType entityType = MessagingEntityType.QUEUE; + final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; + final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; + final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); + final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); + final AtomicBoolean transactionComplete = new AtomicBoolean(); + final CountDownLatch countdownLatch = new CountDownLatch(1); + final AtomicInteger receivedMessages = new AtomicInteger(); + + final String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + message.setSessionId(sessionId); + final List messages = Arrays.asList(message); + + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + + // Initialize sender + final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); + final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); + + Consumer processMessage = (context) -> { + receivedMessages.incrementAndGet(); + messagesPending.incrementAndGet(); + ServiceBusReceivedMessage myMessage = context.getMessage(); + LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), + myMessage.getSequenceNumber(), myMessage.getBody()); + if (receivedMessages.get() == 1) { + + //Start a transaction + ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); + context.complete(new CompleteOptions().setTransactionContext(transactionId)); + senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); + senderSyncB.commitTransaction(transactionId); + transactionComplete.set(true); + countdownLatch.countDown(); + logger.info("Transaction committed."); + } + }; + + Consumer processError = context -> { + LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", + context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); + Assertions.fail("Failed processing of message.", context.getException()); + + if (!(context.getException() instanceof ServiceBusException)) { + LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); + } + }; + + final ServiceBusProcessorClient processorA; + // Initialize processor client + if (isSessionEnabled) { + processorA = toClose(builder.sessionProcessor().disableAutoComplete().queueName(queueA) + .processMessage(processMessage).processError(processError) + .buildProcessorClient()); + } else { + processorA = toClose(builder.processor().disableAutoComplete().queueName(queueA) + .processMessage(processMessage).processError(processError) + .buildProcessorClient()); + } + + // Send messages + StepVerifier.create(senderAsyncA.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + // Create an instance of the processor through the ServiceBusClientBuilder + + // Act + LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); + processorA.start(); + toClose((AutoCloseable) () -> processorA.stop()); + + // Assert + LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); + if (countdownLatch.await(10, TimeUnit.SECONDS)) { + LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); + Assertions.assertTrue(transactionComplete.get()); + } else { + LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); + Assertions.fail("Failed to process message."); + } + + processorA.close(); + + // Verify that message is received by queue B + if (!isSessionEnabled) { + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + StepVerifier.create(receiver.receiveMessages().take(1)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } + } + + /** + * Use case: Test cross entity transaction using processor client and sender. + * 1. Read messages from entity A. + * 2. complete the messages from entity A and write to entity B. + * 2. commit the transaction. + */ + @ParameterizedTest + @ValueSource(strings = {"true", "false"}) + void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { + + // Arrange + final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; + final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; + final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; + final String topicA = getTopicName(receiveQueueAIndex); + final String topicB = getTopicName(sendQueueBIndex); + final AtomicBoolean transactionComplete = new AtomicBoolean(); + + final CountDownLatch countdownLatch = new CountDownLatch(1); + final AtomicInteger receivedMessages = new AtomicInteger(); + + final String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + message.setSessionId(sessionId); + final List messages = Arrays.asList(message); + + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + + // Initialize sender + final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); + final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); + + Consumer processMessage = (context) -> { + receivedMessages.incrementAndGet(); + messagesPending.incrementAndGet(); + ServiceBusReceivedMessage myMessage = context.getMessage(); + LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), + myMessage.getSequenceNumber(), myMessage.getBody()); + if (receivedMessages.get() == 1) { + + //Start a transaction + ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); + context.complete(new CompleteOptions().setTransactionContext(transactionId)); + senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); + senderSyncB.commitTransaction(transactionId); + transactionComplete.set(true); + countdownLatch.countDown(); + logger.info("Transaction committed."); + } + }; + + Consumer processError = context -> { + LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", + context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); + Assertions.fail("Failed processing of message.", context.getException()); + + if (!(context.getException() instanceof ServiceBusException)) { + LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); + } + }; -// -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.core.util.logging.LogLevel; -//import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import com.azure.messaging.servicebus.models.CompleteOptions; -//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.ValueSource; -//import reactor.core.Disposable; -//import reactor.core.publisher.Mono; -//import reactor.test.StepVerifier; -// -//import java.time.Duration; -//import java.util.Arrays; -//import java.util.List; -//import java.util.UUID; -//import java.util.concurrent.CountDownLatch; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicBoolean; -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.function.Consumer; -// -///** -// * Test where various clients are involved for example Sender, Receiver and Processor client. -// */ -//public class ServiceBusMixClientIntegrationTest extends IntegrationTestBase { -// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusMixClientIntegrationTest.class); -// -// private ServiceBusSenderAsyncClient sender; -// private ServiceBusReceiverAsyncClient receiver; -// private final AtomicInteger messagesPending = new AtomicInteger(); -// -// ServiceBusMixClientIntegrationTest() { -// super(new ClientLogger(ServiceBusSenderAsyncClientIntegrationTest.class)); -// } -// -// @Override -// protected void beforeTest() { -// sessionId = UUID.randomUUID().toString(); -// } -// -// @Override -// protected void afterTest() { -// dispose(sender); -// -// final int numberOfMessages = messagesPending.get(); -// if (numberOfMessages < 1) { -// dispose(receiver); -// return; -// } -// -// try { -// if (receiver == null) { -// return; -// } -// receiver.receiveMessages() -// .take(numberOfMessages) -// .map(message -> { -// logger.info("Message received: {}", message.getSequenceNumber()); -// return message; -// }) -// .timeout(Duration.ofSeconds(5), Mono.empty()) -// .blockLast(); -// } catch (Exception e) { -// logger.warning("Error occurred when draining queue.", e); -// } finally { -// dispose(receiver); -// } -// } -// -// /** -// * Use case: Test cross entity transaction using processor client and sender. -// * 1. Read messages from entity A. -// * 2. complete the messages from entity A and write to entity B. -// * 2. commit the transaction. -// */ -// @ParameterizedTest -// @ValueSource(strings = {"true", "false"}) -// void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { -// -// // Arrange -// final MessagingEntityType entityType = MessagingEntityType.QUEUE; -// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; -// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; -// final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); -// final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); -// final AtomicBoolean transactionComplete = new AtomicBoolean(); -// final CountDownLatch countdownLatch = new CountDownLatch(1); -// final AtomicInteger receivedMessages = new AtomicInteger(); -// -// final String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// message.setSessionId(sessionId); -// final List messages = Arrays.asList(message); -// -// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); -// -// // Initialize sender -// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); -// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); -// -// Consumer processMessage = (context) -> { -// receivedMessages.incrementAndGet(); -// messagesPending.incrementAndGet(); -// ServiceBusReceivedMessage myMessage = context.getMessage(); -// LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), -// myMessage.getSequenceNumber(), myMessage.getBody()); -// if (receivedMessages.get() == 1) { -// -// //Start a transaction -// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); -// context.complete(new CompleteOptions().setTransactionContext(transactionId)); -// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); -// senderSyncB.commitTransaction(transactionId); -// transactionComplete.set(true); -// countdownLatch.countDown(); -// logger.info("Transaction committed."); -// } -// }; -// -// Consumer processError = context -> { -// LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", -// context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); -// Assertions.fail("Failed processing of message.", context.getException()); -// -// if (!(context.getException() instanceof ServiceBusException)) { -// LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); -// } -// }; -// -// final ServiceBusProcessorClient processorA; -// // Initialize processor client -// if (isSessionEnabled) { -// processorA = toClose(builder.sessionProcessor().disableAutoComplete().queueName(queueA) -// .processMessage(processMessage).processError(processError) -// .buildProcessorClient()); -// } else { -// processorA = toClose(builder.processor().disableAutoComplete().queueName(queueA) -// .processMessage(processMessage).processError(processError) -// .buildProcessorClient()); -// } -// -// // Send messages -// StepVerifier.create(senderAsyncA.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// // Create an instance of the processor through the ServiceBusClientBuilder -// -// // Act -// LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); -// processorA.start(); -// toClose((AutoCloseable) () -> processorA.stop()); -// -// // Assert -// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); -// if (countdownLatch.await(10, TimeUnit.SECONDS)) { -// LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); -// Assertions.assertTrue(transactionComplete.get()); -// } else { -// LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); -// Assertions.fail("Failed to process message."); -// } -// -// processorA.close(); -// -// // Verify that message is received by queue B -// if (!isSessionEnabled) { -// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); -// StepVerifier.create(receiver.receiveMessages().take(1)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// } -// -// /** -// * Use case: Test cross entity transaction using processor client and sender. -// * 1. Read messages from entity A. -// * 2. complete the messages from entity A and write to entity B. -// * 2. commit the transaction. -// */ -// @ParameterizedTest -// @ValueSource(strings = {"true", "false"}) -// void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { -// -// // Arrange -// final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; -// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; -// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; -// final String topicA = getTopicName(receiveQueueAIndex); -// final String topicB = getTopicName(sendQueueBIndex); -// final AtomicBoolean transactionComplete = new AtomicBoolean(); -// -// final CountDownLatch countdownLatch = new CountDownLatch(1); -// final AtomicInteger receivedMessages = new AtomicInteger(); -// -// final String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// message.setSessionId(sessionId); -// final List messages = Arrays.asList(message); -// -// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); -// -// // Initialize sender -// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); -// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); -// -// Consumer processMessage = (context) -> { -// receivedMessages.incrementAndGet(); -// messagesPending.incrementAndGet(); -// ServiceBusReceivedMessage myMessage = context.getMessage(); -// LOGGER.verbose("Processing message. MessageId: {}, Sequence #: {}. Contents: {}", myMessage.getMessageId(), -// myMessage.getSequenceNumber(), myMessage.getBody()); -// if (receivedMessages.get() == 1) { -// -// //Start a transaction -// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); -// context.complete(new CompleteOptions().setTransactionContext(transactionId)); -// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); -// senderSyncB.commitTransaction(transactionId); -// transactionComplete.set(true); -// countdownLatch.countDown(); -// logger.info("Transaction committed."); -// } -// }; -// -// Consumer processError = context -> { -// LOGGER.verbose("Error when receiving messages from namespace: '{}'. Entity: '{}'. Error Source: '{}'", -// context.getFullyQualifiedNamespace(), context.getEntityPath(), context.getErrorSource()); -// Assertions.fail("Failed processing of message.", context.getException()); -// -// if (!(context.getException() instanceof ServiceBusException)) { -// LOGGER.log(LogLevel.VERBOSE, () -> "Non-ServiceBusException occurred: " + context.getException()); -// } -// }; -// -// final ServiceBusProcessorClient processorA; -// // Initialize processor client -// if (isSessionEnabled) { -// processorA = toClose(builder.sessionProcessor() -// .disableAutoComplete() -// .topicName(topicA) -// .subscriptionName(TestUtils.getSessionSubscriptionBaseName()) -// .processMessage(processMessage) -// .processError(processError) -// .buildProcessorClient()); -// } else { -// processorA = toClose(builder.processor() -// .disableAutoComplete() -// .topicName(topicA) -// .subscriptionName(TestUtils.getSubscriptionBaseName()) -// .processMessage(processMessage) -// .processError(processError) -// .buildProcessorClient()); -// } -// -// // Send messages -// StepVerifier.create(senderAsyncA.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// // Create an instance of the processor through the ServiceBusClientBuilder -// -// // Act -// LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); -// processorA.start(); -// toClose((AutoCloseable) () -> processorA.stop()); -// -// // Assert -// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); -// if (countdownLatch.await(10, TimeUnit.SECONDS)) { -// LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); -// Assertions.assertTrue(transactionComplete.get()); -// } else { -// LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); -// Assertions.fail("Failed to process message."); -// } -// -// processorA.close(); -// -// // Verify that message is received by queue B -// if (!isSessionEnabled) { -// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); -// StepVerifier.create(receiver.receiveMessages().take(1)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// } -// -// /** -// * Use case: Test cross entity transaction using receiver and senders. -// * 1. Read messages from entity A. -// * 2. complete the messages from entity A and write to entity B. -// * 2. commit the transaction. -// */ -// @ParameterizedTest -// @ValueSource(strings = {"true", "false"}) -// void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { -// -// // Arrange -// final MessagingEntityType entityType = MessagingEntityType.QUEUE; -// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; -// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; -// final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); -// final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); -// final AtomicBoolean transactionComplete = new AtomicBoolean(); -// -// final CountDownLatch countdownLatch = new CountDownLatch(1); -// -// final String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// message.setSessionId(sessionId); -// final List messages = Arrays.asList(message); -// -// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); -// -// // Initialize sender -// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); -// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); -// -// // Send messages -// StepVerifier.create(senderAsyncA.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// -// final ServiceBusReceiverAsyncClient receiverA; -// -// if (isSessionEnabled) { -// receiverA = builder.sessionReceiver().disableAutoComplete().queueName(queueA) -// .buildAsyncClient().acceptNextSession().block(); -// } else { -// receiverA = builder.receiver().disableAutoComplete().queueName(queueA) -// .buildAsyncClient(); -// } -// -// Disposable subscription = receiverA.receiveMessages() -// .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())) -// .flatMap(receivedMessage -> { -// //Start a transaction -// logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); -// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); -// receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); -// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); -// senderSyncB.commitTransaction(transactionId); -// transactionComplete.set(true); -// countdownLatch.countDown(); -// logger.info("Transaction committed."); -// return Mono.just(receivedMessage); -// }).subscribe(); -// toClose(subscription); -// -// // Act -// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); -// if (countdownLatch.await(10, TimeUnit.SECONDS)) { -// LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); -// Assertions.assertTrue(transactionComplete.get()); -// } else { -// LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); -// Assertions.fail("Failed to process message."); -// } -// -// // Assert -// // Verify that message is received by entity B -// if (!isSessionEnabled) { -// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); -// StepVerifier.create(receiver.receiveMessages() -// .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())).take(1)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// } -// -// /** -// * Use case: Test cross entity transaction using receiver and senders. -// * 1. Read messages from entity A. -// * 2. complete the messages from entity A and write to entity B. -// * 2. commit the transaction. -// */ -// @ParameterizedTest -// @ValueSource(strings = {"true", "false"}) -// void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { -// -// // Arrange -// final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; -// final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; -// final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; -// final String topicA = getTopicName(receiveQueueAIndex); -// final String topicB = getTopicName(sendQueueBIndex); -// final AtomicBoolean transactionComplete = new AtomicBoolean(); -// -// final CountDownLatch countdownLatch = new CountDownLatch(1); -// -// final String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); -// message.setSessionId(sessionId); -// final List messages = Arrays.asList(message); -// -// ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); -// -// // Initialize sender -// final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); -// final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); -// -// -// // Send messages -// StepVerifier.create(senderAsyncA.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// -// final ServiceBusReceiverAsyncClient receiverA; -// -// if (isSessionEnabled) { -// receiverA = builder.sessionReceiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSessionSubscriptionBaseName()) -// .buildAsyncClient().acceptNextSession().block(); -// } else { -// receiverA = builder.receiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSubscriptionBaseName()) -// .buildAsyncClient(); -// } -// -// Disposable subscription = receiverA.receiveMessages().flatMap(receivedMessage -> { -// //Start a transaction -// logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); -// ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); -// receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); -// senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); -// senderSyncB.commitTransaction(transactionId); -// transactionComplete.set(true); -// countdownLatch.countDown(); -// logger.info("Transaction committed."); -// return Mono.just(receivedMessage); -// }).subscribe(); -// toClose(subscription); -// // Act -// LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); -// if (countdownLatch.await(10, TimeUnit.SECONDS)) { -// LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); -// Assertions.assertTrue(transactionComplete.get()); -// } else { -// LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); -// Assertions.fail("Failed to process message."); -// } -// -// // Assert -// // Verify that message is received by entity B -// if (!isSessionEnabled) { -// setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); -// StepVerifier.create(receiver.receiveMessages().take(1)) -// .assertNext(receivedMessage -> { -// assertMessageEquals(receivedMessage, messageId, isSessionEnabled); -// messagesPending.decrementAndGet(); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// } -// -// /** -// * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. -// */ -// private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { -// final boolean isSessionAware = false; -// final boolean sharedConnection = true; -// -// this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) -// .buildAsyncClient()); -// this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .disableAutoComplete() -// .buildAsyncClient()); -// } -//} + final ServiceBusProcessorClient processorA; + // Initialize processor client + if (isSessionEnabled) { + processorA = toClose(builder.sessionProcessor() + .disableAutoComplete() + .topicName(topicA) + .subscriptionName(TestUtils.getSessionSubscriptionBaseName()) + .processMessage(processMessage) + .processError(processError) + .buildProcessorClient()); + } else { + processorA = toClose(builder.processor() + .disableAutoComplete() + .topicName(topicA) + .subscriptionName(TestUtils.getSubscriptionBaseName()) + .processMessage(processMessage) + .processError(processError) + .buildProcessorClient()); + } + + // Send messages + StepVerifier.create(senderAsyncA.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + // Create an instance of the processor through the ServiceBusClientBuilder + + // Act + LOGGER.log(LogLevel.VERBOSE, () -> "Starting the processor"); + processorA.start(); + toClose((AutoCloseable) () -> processorA.stop()); + + // Assert + LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); + if (countdownLatch.await(10, TimeUnit.SECONDS)) { + LOGGER.log(LogLevel.VERBOSE, () -> "Completed processing successfully."); + Assertions.assertTrue(transactionComplete.get()); + } else { + LOGGER.log(LogLevel.VERBOSE, () -> "Closing processor."); + Assertions.fail("Failed to process message."); + } + + processorA.close(); + + // Verify that message is received by queue B + if (!isSessionEnabled) { + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + StepVerifier.create(receiver.receiveMessages().take(1)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } + } + + /** + * Use case: Test cross entity transaction using receiver and senders. + * 1. Read messages from entity A. + * 2. complete the messages from entity A and write to entity B. + * 2. commit the transaction. + */ + @ParameterizedTest + @ValueSource(strings = {"true", "false"}) + void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { + + // Arrange + final MessagingEntityType entityType = MessagingEntityType.QUEUE; + final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; + final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; + final String queueA = isSessionEnabled ? getSessionQueueName(receiveQueueAIndex) : getQueueName(receiveQueueAIndex); + final String queueB = isSessionEnabled ? getSessionQueueName(sendQueueBIndex) : getQueueName(sendQueueBIndex); + final AtomicBoolean transactionComplete = new AtomicBoolean(); + + final CountDownLatch countdownLatch = new CountDownLatch(1); + + final String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + message.setSessionId(sessionId); + final List messages = Arrays.asList(message); + + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + + // Initialize sender + final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); + final ServiceBusSenderClient senderSyncB = toClose(builder.sender().queueName(queueB).buildClient()); + + // Send messages + StepVerifier.create(senderAsyncA.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + + final ServiceBusReceiverAsyncClient receiverA; + + if (isSessionEnabled) { + receiverA = builder.sessionReceiver().disableAutoComplete().queueName(queueA) + .buildAsyncClient().acceptNextSession().block(); + } else { + receiverA = builder.receiver().disableAutoComplete().queueName(queueA) + .buildAsyncClient(); + } + + Disposable subscription = receiverA.receiveMessages() + .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())) + .flatMap(receivedMessage -> { + //Start a transaction + logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); + ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); + receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); + senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); + senderSyncB.commitTransaction(transactionId); + transactionComplete.set(true); + countdownLatch.countDown(); + logger.info("Transaction committed."); + return Mono.just(receivedMessage); + }).subscribe(); + toClose(subscription); + + // Act + LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); + if (countdownLatch.await(10, TimeUnit.SECONDS)) { + LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); + Assertions.assertTrue(transactionComplete.get()); + } else { + LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); + Assertions.fail("Failed to process message."); + } + + // Assert + // Verify that message is received by entity B + if (!isSessionEnabled) { + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + StepVerifier.create(receiver.receiveMessages() + .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())).take(1)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } + } + + /** + * Use case: Test cross entity transaction using receiver and senders. + * 1. Read messages from entity A. + * 2. complete the messages from entity A and write to entity B. + * 2. commit the transaction. + */ + @ParameterizedTest + @ValueSource(strings = {"true", "false"}) + void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { + + // Arrange + final MessagingEntityType entityType = MessagingEntityType.SUBSCRIPTION; + final int receiveQueueAIndex = TestUtils.USE_CASE_TXN_1; + final int sendQueueBIndex = TestUtils.USE_CASE_TXN_2; + final String topicA = getTopicName(receiveQueueAIndex); + final String topicB = getTopicName(sendQueueBIndex); + final AtomicBoolean transactionComplete = new AtomicBoolean(); + + final CountDownLatch countdownLatch = new CountDownLatch(1); + + final String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); + message.setSessionId(sessionId); + final List messages = Arrays.asList(message); + + ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + + // Initialize sender + final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); + final ServiceBusSenderClient senderSyncB = toClose(builder.sender().topicName(topicB).buildClient()); + + + // Send messages + StepVerifier.create(senderAsyncA.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + + final ServiceBusReceiverAsyncClient receiverA; + + if (isSessionEnabled) { + receiverA = builder.sessionReceiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSessionSubscriptionBaseName()) + .buildAsyncClient().acceptNextSession().block(); + } else { + receiverA = builder.receiver().disableAutoComplete().topicName(topicA).subscriptionName(TestUtils.getSubscriptionBaseName()) + .buildAsyncClient(); + } + + Disposable subscription = receiverA.receiveMessages().flatMap(receivedMessage -> { + //Start a transaction + logger.info("Received message sequence number {}. Creating transaction", receivedMessage.getSequenceNumber()); + ServiceBusTransactionContext transactionId = senderSyncB.createTransaction(); + receiverA.complete(receivedMessage, new CompleteOptions().setTransactionContext(transactionId)).block(); + senderSyncB.sendMessage(new ServiceBusMessage(CONTENTS_BYTES).setMessageId(messageId).setSessionId(sessionId), transactionId); + senderSyncB.commitTransaction(transactionId); + transactionComplete.set(true); + countdownLatch.countDown(); + logger.info("Transaction committed."); + return Mono.just(receivedMessage); + }).subscribe(); + toClose(subscription); + // Act + LOGGER.log(LogLevel.VERBOSE, () -> "Listening for 10 seconds..."); + if (countdownLatch.await(10, TimeUnit.SECONDS)) { + LOGGER.log(LogLevel.VERBOSE, () -> "Completed message processing successfully."); + Assertions.assertTrue(transactionComplete.get()); + } else { + LOGGER.log(LogLevel.VERBOSE, () -> "Some error."); + Assertions.fail("Failed to process message."); + } + + // Assert + // Verify that message is received by entity B + if (!isSessionEnabled) { + setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + StepVerifier.create(receiver.receiveMessages().take(1)) + .assertNext(receivedMessage -> { + assertMessageEquals(receivedMessage, messageId, isSessionEnabled); + messagesPending.decrementAndGet(); + }) + .expectComplete() + .verify(TIMEOUT); + } + } + + /** + * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. + */ + private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { + final boolean isSessionAware = false; + final boolean sharedConnection = true; + + this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) + .buildAsyncClient()); + this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .disableAutoComplete() + .buildAsyncClient()); + } +} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index 2e254bc91a50..cad23138cf20 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -3,213 +3,208 @@ package com.azure.messaging.servicebus; -public class ServiceBusProcessorClientIntegrationTest { +import com.azure.core.amqp.AmqpRetryOptions; +import com.azure.core.util.CoreUtils; +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; +import reactor.core.scheduler.Schedulers; -} +import java.time.Duration; +import java.time.OffsetTime; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; + +import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Tests for {@link ServiceBusProcessorClient}. + */ + +public class ServiceBusProcessorClientIntegrationTest extends IntegrationTestBase { + private static final ClientLogger LOGGER = new ClientLogger(ServiceBusProcessorClientIntegrationTest.class); + private final AtomicInteger messagesPending = new AtomicInteger(); + private final Scheduler scheduler = Schedulers.parallel(); + + @Override + protected void beforeTest() { + sessionId = CoreUtils.randomUuid().toString(); + } + + @Override + protected void afterTest() { + sharedBuilder = null; + } + + ServiceBusProcessorClientIntegrationTest() { + super(new ClientLogger(ServiceBusProcessorClientIntegrationTest.class)); + } + + /** + * Validate that processor receive the message and {@code MaxAutoLockRenewDuration} is set on the + * {@link ServiceBusReceiverAsyncClient}. The message lock is released by the client and same message received + * again. + */ + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") + @ParameterizedTest + void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { + // Arrange + // The message is locked for this duration at a time. + final int lockTimeoutDurationSeconds = 15; + final int entityIndex = TestUtils.USE_CASE_PROCESSOR_RECEIVE; + final Duration expectedMaxAutoLockRenew = Duration.ofSeconds(35); + + final String messageId = UUID.randomUUID().toString(); + final AtomicReference lastMessageReceivedTime = new AtomicReference<>(); + final ServiceBusMessage message = getMessage(messageId, isSessionEnabled).setMessageId(messageId); + + // The message should comeback after the client release the lock once because maxAutoLockRenewDuration is set + // by user. + CountDownLatch countDownLatch = new CountDownLatch(2); + + // send the message + ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, isSessionEnabled); + sendMessage(sender, message).block(TIMEOUT); + + ServiceBusProcessorClient processor; + if (isSessionEnabled) { + assertNotNull(sessionId, "'sessionId' should have been set."); + AmqpRetryOptions amqpRetryOptions = new AmqpRetryOptions() + .setTryTimeout(Duration.ofSeconds(2 * lockTimeoutDurationSeconds)); + processor = toClose(getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, amqpRetryOptions) + .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) + .disableAutoComplete() + .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) + .processError(context -> processError(context, countDownLatch)) + .buildProcessorClient()); + + } else { + processor = toClose(getProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false) + .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) + .disableAutoComplete() + .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) + .processError(context -> processError(context, countDownLatch)) + .buildProcessorClient()); + } + + // Assert & Act + processor.start(); + toClose((AutoCloseable) () -> processor.stop()); + + assertTrue(countDownLatch.await(lockTimeoutDurationSeconds * 6, TimeUnit.SECONDS), "Message not arrived, closing processor."); + LOGGER.info("Message lock has been renewed. Now closing processor"); + } + + @ParameterizedTest + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { + final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; + final Duration sessionIdleTimeout = Duration.ofSeconds(3); -// -//import com.azure.core.amqp.AmqpRetryOptions; -//import com.azure.core.util.CoreUtils; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.core.publisher.Mono; -//import reactor.core.scheduler.Scheduler; -//import reactor.core.scheduler.Schedulers; -// -//import java.time.Duration; -//import java.time.OffsetTime; -//import java.util.UUID; -//import java.util.concurrent.CountDownLatch; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicInteger; -//import java.util.concurrent.atomic.AtomicReference; -// -//import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assertions.fail; -// -///** -// * Tests for {@link ServiceBusProcessorClient}. -// */ -// -//public class ServiceBusProcessorClientIntegrationTest extends IntegrationTestBase { -// private static final ClientLogger LOGGER = new ClientLogger(ServiceBusProcessorClientIntegrationTest.class); -// private final AtomicInteger messagesPending = new AtomicInteger(); -// private final Scheduler scheduler = Schedulers.parallel(); -// -// @Override -// protected void beforeTest() { -// sessionId = CoreUtils.randomUuid().toString(); -// } -// -// @Override -// protected void afterTest() { -// sharedBuilder = null; -// } -// -// ServiceBusProcessorClientIntegrationTest() { -// super(new ClientLogger(ServiceBusProcessorClientIntegrationTest.class)); -// } -// -// /** -// * Validate that processor receive the message and {@code MaxAutoLockRenewDuration} is set on the -// * {@link ServiceBusReceiverAsyncClient}. The message lock is released by the client and same message received -// * again. -// */ -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") -// @ParameterizedTest -// void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { -// // Arrange -// // The message is locked for this duration at a time. -// final int lockTimeoutDurationSeconds = 15; -// final int entityIndex = TestUtils.USE_CASE_PROCESSOR_RECEIVE; -// final Duration expectedMaxAutoLockRenew = Duration.ofSeconds(35); -// -// final String messageId = UUID.randomUUID().toString(); -// final AtomicReference lastMessageReceivedTime = new AtomicReference<>(); -// final ServiceBusMessage message = getMessage(messageId, isSessionEnabled).setMessageId(messageId); -// -// // The message should comeback after the client release the lock once because maxAutoLockRenewDuration is set -// // by user. -// CountDownLatch countDownLatch = new CountDownLatch(2); -// -// // send the message -// ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, isSessionEnabled); -// sendMessage(sender, message).block(TIMEOUT); -// -// ServiceBusProcessorClient processor; -// if (isSessionEnabled) { -// assertNotNull(sessionId, "'sessionId' should have been set."); -// AmqpRetryOptions amqpRetryOptions = new AmqpRetryOptions() -// .setTryTimeout(Duration.ofSeconds(2 * lockTimeoutDurationSeconds)); -// processor = toClose(getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, amqpRetryOptions) -// .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) -// .disableAutoComplete() -// .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) -// .processError(context -> processError(context, countDownLatch)) -// .buildProcessorClient()); -// -// } else { -// processor = toClose(getProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false) -// .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) -// .disableAutoComplete() -// .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) -// .processError(context -> processError(context, countDownLatch)) -// .buildProcessorClient()); -// } -// -// // Assert & Act -// processor.start(); -// toClose((AutoCloseable) () -> processor.stop()); -// -// assertTrue(countDownLatch.await(lockTimeoutDurationSeconds * 6, TimeUnit.SECONDS), "Message not arrived, closing processor."); -// LOGGER.info("Message lock has been renewed. Now closing processor"); -// } -// -// @ParameterizedTest -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { -// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; -// final Duration sessionIdleTimeout = Duration.ofSeconds(3); -// -// ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); -// -// ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = -// getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, RETRY_OPTIONS) -// .sessionIdleTimeout(sessionIdleTimeout) -// .disableAutoComplete(); -// -// rollingSessionTest(sender, processorBuilder); -// } -// -// @ParameterizedTest -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { -// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; -// final Duration tryTimeout = Duration.ofSeconds(3); -// -// ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); -// ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = -// getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, -// new AmqpRetryOptions().setTryTimeout(tryTimeout)) -// .disableAutoComplete(); -// -// rollingSessionTest(sender, processorBuilder); -// } -// -// void rollingSessionTest(ServiceBusSenderAsyncClient sender, ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder) throws InterruptedException { -// final String contents = "Some-contents"; -// final String randomPrefix = UUID.randomUUID().toString(); -// ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); -// ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); -// -// CountDownLatch latch = new CountDownLatch(2); -// ServiceBusProcessorClient processor = toClose(processorBuilder -// .processMessage(context -> { -// ServiceBusReceivedMessage received = context.getMessage(); -// context.complete(); -// -// if (received.getMessageId().startsWith(randomPrefix)) { -// latch.countDown(); -// if (message0.getMessageId().equals(received.getMessageId())) { -// sendMessage(sender, message1).block(); -// } -// } -// }) -// .processError(context -> fail(context.getException())) -// .buildProcessorClient()); -// -// processor.start(); -// sendMessage(sender, message0).block(); -// -// toClose((AutoCloseable) () -> processor.stop()); -// -// assertTrue(latch.await(20, TimeUnit.SECONDS), "Messages did not arrived, closing processor."); -// } -// -// private void processMessage(ServiceBusReceivedMessageContext context, CountDownLatch countDownLatch, -// String expectedMessageId, AtomicReference lastMessageReceivedTime, int lockTimeoutDurationSeconds) { -// ServiceBusReceivedMessage message = context.getMessage(); -// if (message.getMessageId().equals(expectedMessageId)) { -// LOGGER.info("Processing message. Session: {}, Sequence #: {}. Contents: {}", message.getMessageId(), -// message.getSequenceNumber(), message.getBody()); -// if (lastMessageReceivedTime.get() == null) { -// lastMessageReceivedTime.set(OffsetTime.now()); -// countDownLatch.countDown(); -// } else { -// long messageReceivedAfterSeconds = Duration.between(lastMessageReceivedTime.get(), OffsetTime.now()).getSeconds(); -// LOGGER.info("Processing message again. Session: {}, Sequence #: {}. Contents: {}, message received after {} seconds.", message.getMessageId(), -// message.getSequenceNumber(), message.getBody(), messageReceivedAfterSeconds); -// // Ensure that the lock is renewed and message is received again after atlest one lock renew -// if (messageReceivedAfterSeconds >= 2 * lockTimeoutDurationSeconds) { -// countDownLatch.countDown(); -// } -// } -// } else { -// LOGGER.info("Received message, message id did not match. Session: %s, Sequence #: %s. Contents: %s%n", message.getMessageId(), -// message.getSequenceNumber(), message.getBody()); -// } -// } -// -// private void processError(ServiceBusErrorContext context, CountDownLatch countdownLatch) { -// LOGGER.info("Error when receiving messages from namespace: {}. Entity: {}}", -// context.getFullyQualifiedNamespace(), context.getEntityPath()); -// } -// -// private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { -// final boolean shareConnection = false; -// return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) -// .buildAsyncClient()); -// } -// -// private Mono sendMessage(ServiceBusSenderAsyncClient sender, ServiceBusMessage message) { -// return sender.sendMessage(message).doOnSuccess(aVoid -> { -// logMessage(message, sender.getEntityPath(), "sent"); -// int number = messagesPending.incrementAndGet(); -// LOGGER.atInfo().addKeyValue("number", number).log("Number sent"); -// }); -// } -//} + ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); + + ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = + getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, RETRY_OPTIONS) + .sessionIdleTimeout(sessionIdleTimeout) + .disableAutoComplete(); + + rollingSessionTest(sender, processorBuilder); + } + + @ParameterizedTest + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { + final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; + final Duration tryTimeout = Duration.ofSeconds(3); + + ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); + ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = + getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, + new AmqpRetryOptions().setTryTimeout(tryTimeout)) + .disableAutoComplete(); + + rollingSessionTest(sender, processorBuilder); + } + + void rollingSessionTest(ServiceBusSenderAsyncClient sender, ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder) throws InterruptedException { + final String contents = "Some-contents"; + final String randomPrefix = UUID.randomUUID().toString(); + ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); + ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); + + CountDownLatch latch = new CountDownLatch(2); + ServiceBusProcessorClient processor = toClose(processorBuilder + .processMessage(context -> { + ServiceBusReceivedMessage received = context.getMessage(); + context.complete(); + + if (received.getMessageId().startsWith(randomPrefix)) { + latch.countDown(); + if (message0.getMessageId().equals(received.getMessageId())) { + sendMessage(sender, message1).block(); + } + } + }) + .processError(context -> fail(context.getException())) + .buildProcessorClient()); + + processor.start(); + sendMessage(sender, message0).block(); + + toClose((AutoCloseable) () -> processor.stop()); + + assertTrue(latch.await(20, TimeUnit.SECONDS), "Messages did not arrived, closing processor."); + } + + private void processMessage(ServiceBusReceivedMessageContext context, CountDownLatch countDownLatch, + String expectedMessageId, AtomicReference lastMessageReceivedTime, int lockTimeoutDurationSeconds) { + ServiceBusReceivedMessage message = context.getMessage(); + if (message.getMessageId().equals(expectedMessageId)) { + LOGGER.info("Processing message. Session: {}, Sequence #: {}. Contents: {}", message.getMessageId(), + message.getSequenceNumber(), message.getBody()); + if (lastMessageReceivedTime.get() == null) { + lastMessageReceivedTime.set(OffsetTime.now()); + countDownLatch.countDown(); + } else { + long messageReceivedAfterSeconds = Duration.between(lastMessageReceivedTime.get(), OffsetTime.now()).getSeconds(); + LOGGER.info("Processing message again. Session: {}, Sequence #: {}. Contents: {}, message received after {} seconds.", message.getMessageId(), + message.getSequenceNumber(), message.getBody(), messageReceivedAfterSeconds); + // Ensure that the lock is renewed and message is received again after atlest one lock renew + if (messageReceivedAfterSeconds >= 2 * lockTimeoutDurationSeconds) { + countDownLatch.countDown(); + } + } + } else { + LOGGER.info("Received message, message id did not match. Session: %s, Sequence #: %s. Contents: %s%n", message.getMessageId(), + message.getSequenceNumber(), message.getBody()); + } + } + + private void processError(ServiceBusErrorContext context, CountDownLatch countdownLatch) { + LOGGER.info("Error when receiving messages from namespace: {}. Entity: {}}", + context.getFullyQualifiedNamespace(), context.getEntityPath()); + } + + private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { + final boolean shareConnection = false; + return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + .buildAsyncClient()); + } + + private Mono sendMessage(ServiceBusSenderAsyncClient sender, ServiceBusMessage message) { + return sender.sendMessage(message).doOnSuccess(aVoid -> { + logMessage(message, sender.getEntityPath(), "sent"); + int number = messagesPending.incrementAndGet(); + LOGGER.atInfo().addKeyValue("number", number).log("Number sent"); + }); + } +} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index 443a4ce6b906..262ad0ec9b78 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -3,219 +3,216 @@ package com.azure.messaging.servicebus; -class ServiceBusSessionManagerIntegrationTest { +import com.azure.core.amqp.AmqpRetryOptions; +import com.azure.core.util.CoreUtils; +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; +import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import reactor.core.Disposable; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.time.Duration; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; + +import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Integration tests for {@link ServiceBusSessionManager}. + */ +@Tag("integration") +class ServiceBusSessionManagerIntegrationTest extends IntegrationTestBase { + private static final AmqpRetryOptions DEFAULT_RETRY_OPTIONS = null; + private ServiceBusReceiverAsyncClient receiver; + private ServiceBusSenderAsyncClient sender; + private ServiceBusSessionReceiverAsyncClient sessionReceiver; + + ServiceBusSessionManagerIntegrationTest() { + super(new ClientLogger(ServiceBusSessionManagerIntegrationTest.class)); + } + + @Override + protected void beforeTest() { + sessionId = UUID.randomUUID().toString(); + } + + @Override + protected void afterTest() { + try { + dispose(receiver, sender, sessionReceiver); + } catch (Exception e) { + logger.warning("Error occurred when draining queue.", e); + } + } + + @ParameterizedTest + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + void singleUnnamedSession(MessagingEntityType entityType) { + // Arrange + final int entityIndex = TestUtils.USE_CASE_SINGLE_SESSION; + final String messageId = "singleUnnamedSession"; + final String contents = "Some-contents"; + final int numberToSend = 5; + + setSender(entityType, entityIndex); + final Disposable subscription = Flux.interval(Duration.ofMillis(500)) + .take(numberToSend) + .flatMap(index -> { + final ServiceBusMessage message = getServiceBusMessage(contents, messageId) + .setSessionId(sessionId); + return sender.sendMessage(message).thenReturn(index); + }) + .subscribe( + number -> logger.info("sessionId[{}] sent[{}] Message sent.", sessionId, number), + error -> logger.error("sessionId[{}] Error encountered.", sessionId, error), + () -> logger.info("sessionId[{}] Finished sending.", sessionId)); + toClose(subscription); + setReceiver(entityType, entityIndex, Function.identity()); + + // Act & Assert + StepVerifier.create(receiver.receiveMessages().concatMap( + receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage) + )) + .assertNext(serviceBusReceivedMessage -> + assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) + .assertNext(serviceBusReceivedMessage -> + assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) + .assertNext(serviceBusReceivedMessage -> + assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) + .assertNext(serviceBusReceivedMessage -> + assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) + .assertNext(serviceBusReceivedMessage -> + assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) + .thenCancel() + .verify(Duration.ofMinutes(2)); + } + + @ParameterizedTest + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { + final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; + final Duration sessionIdleTimeout = Duration.ofSeconds(3); + setSender(entityType, entityIndex); + + this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, + entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) + .disableAutoComplete() + .maxConcurrentSessions(1) + .sessionIdleTimeout(sessionIdleTimeout) + .buildAsyncClientForProcessor()); + + rollingSessionTest(); + } + + @ParameterizedTest + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { + final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS3; + final Duration tryTimeout = Duration.ofSeconds(3); + final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); + setSender(entityType, entityIndex); + + this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, + entityType, entityIndex, false, retryOptions) + .disableAutoComplete() + .maxConcurrentSessions(1) + .buildAsyncClientForProcessor()); + + rollingSessionTest(); + } + + private void rollingSessionTest() throws InterruptedException { + final String contents = "Some-contents"; + final String randomPrefix = UUID.randomUUID().toString(); + ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); + ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); + + CountDownLatch latch = new CountDownLatch(2); + toClose(sender.sendMessage(message0) + .thenMany(receiver.receiveMessages()) + .flatMap(m -> receiver.complete(m).thenReturn(m)) + .filter(m -> m.getMessageId().startsWith(randomPrefix)) + .flatMap(m -> + (message0.getMessageId().equals(m.getMessageId())) + ? sender.sendMessage(message1).thenReturn(m) : Mono.just(m) + ) + .subscribe(m -> latch.countDown(), ex -> fail(ex))); + + assertTrue(latch.await(20, TimeUnit.SECONDS)); + } + @ParameterizedTest + @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") + void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { + final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS2; + final String contents = "Some-contents"; + final Duration sessionIdleTimeout = Duration.ofSeconds(3); + final Duration tryTimeout = Duration.ofSeconds(10); + setSender(entityType, entityIndex); + final String randomPrefix = UUID.randomUUID().toString(); + ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); + ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); + + AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); + this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, + entityType, entityIndex, false, retryOptions) + .disableAutoComplete() + .sessionIdleTimeout(sessionIdleTimeout) + .buildAsyncClientForProcessor()); + + AtomicReference sessionId = new AtomicReference<>(); + StepVerifier.create( + sender.sendMessage(message0) + .thenMany(receiver.receiveMessages()) + .flatMap(m -> receiver.complete(m).thenReturn(m)) + .flatMap(m -> { + if (!sessionId.compareAndSet(null, m.getSessionId())) { + assertEquals(sessionId.get(), m.getSessionId(), "session rolling should not happen"); + } + return sender.sendMessage(message1).thenReturn(m); + }) + ) + .expectNextCount(1) + .verifyTimeout(tryTimeout.plusSeconds(20)); + } + + /** + * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. + */ + private void setSender(MessagingEntityType entityType, int entityIndex) { + this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, true, false) + .buildAsyncClient()); + } + + private void setReceiver(MessagingEntityType entityType, int entityIndex, + Function onBuild) { + ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(USE_CREDENTIALS, + entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); + + this.sessionReceiver = toClose(onBuild.apply(sessionBuilder).buildAsyncClient()); + this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); + } + + private static void assertMessageEquals(String sessionId, String messageId, String contents, ServiceBusReceivedMessage message) { + assertNotNull(message, "'message' should not be null."); + + if (!CoreUtils.isNullOrEmpty(sessionId)) { + assertEquals(sessionId, message.getSessionId()); + } + + assertEquals(messageId, message.getMessageId()); + assertEquals(contents, message.getBody().toString()); + } } -// -//import com.azure.core.amqp.AmqpRetryOptions; -//import com.azure.core.util.CoreUtils; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; -//import com.azure.messaging.servicebus.implementation.MessagingEntityType; -//import org.junit.jupiter.api.Tag; -//import org.junit.jupiter.params.ParameterizedTest; -//import org.junit.jupiter.params.provider.MethodSource; -//import reactor.core.Disposable; -//import reactor.core.publisher.Flux; -//import reactor.core.publisher.Mono; -//import reactor.test.StepVerifier; -// -//import java.time.Duration; -//import java.util.UUID; -//import java.util.concurrent.CountDownLatch; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicReference; -//import java.util.function.Function; -// -//import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assertions.fail; -// -///** -// * Integration tests for {@link ServiceBusSessionManager}. -// */ -//@Tag("integration") -//class ServiceBusSessionManagerIntegrationTest extends IntegrationTestBase { -// private static final AmqpRetryOptions DEFAULT_RETRY_OPTIONS = null; -// private ServiceBusReceiverAsyncClient receiver; -// private ServiceBusSenderAsyncClient sender; -// private ServiceBusSessionReceiverAsyncClient sessionReceiver; -// -// ServiceBusSessionManagerIntegrationTest() { -// super(new ClientLogger(ServiceBusSessionManagerIntegrationTest.class)); -// } -// -// @Override -// protected void beforeTest() { -// sessionId = UUID.randomUUID().toString(); -// } -// -// @Override -// protected void afterTest() { -// try { -// dispose(receiver, sender, sessionReceiver); -// } catch (Exception e) { -// logger.warning("Error occurred when draining queue.", e); -// } -// } -// -// @ParameterizedTest -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// void singleUnnamedSession(MessagingEntityType entityType) { -// // Arrange -// final int entityIndex = TestUtils.USE_CASE_SINGLE_SESSION; -// final String messageId = "singleUnnamedSession"; -// final String contents = "Some-contents"; -// final int numberToSend = 5; -// -// setSender(entityType, entityIndex); -// final Disposable subscription = Flux.interval(Duration.ofMillis(500)) -// .take(numberToSend) -// .flatMap(index -> { -// final ServiceBusMessage message = getServiceBusMessage(contents, messageId) -// .setSessionId(sessionId); -// return sender.sendMessage(message).thenReturn(index); -// }) -// .subscribe( -// number -> logger.info("sessionId[{}] sent[{}] Message sent.", sessionId, number), -// error -> logger.error("sessionId[{}] Error encountered.", sessionId, error), -// () -> logger.info("sessionId[{}] Finished sending.", sessionId)); -// toClose(subscription); -// setReceiver(entityType, entityIndex, Function.identity()); -// -// // Act & Assert -// StepVerifier.create(receiver.receiveMessages().concatMap( -// receivedMessage -> receiver.complete(receivedMessage).thenReturn(receivedMessage) -// )) -// .assertNext(serviceBusReceivedMessage -> -// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) -// .assertNext(serviceBusReceivedMessage -> -// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) -// .assertNext(serviceBusReceivedMessage -> -// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) -// .assertNext(serviceBusReceivedMessage -> -// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) -// .assertNext(serviceBusReceivedMessage -> -// assertMessageEquals(sessionId, messageId, contents, serviceBusReceivedMessage)) -// .thenCancel() -// .verify(Duration.ofMinutes(2)); -// } -// -// @ParameterizedTest -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { -// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; -// final Duration sessionIdleTimeout = Duration.ofSeconds(3); -// setSender(entityType, entityIndex); -// -// this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, -// entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) -// .disableAutoComplete() -// .maxConcurrentSessions(1) -// .sessionIdleTimeout(sessionIdleTimeout) -// .buildAsyncClientForProcessor()); -// -// rollingSessionTest(); -// } -// -// @ParameterizedTest -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { -// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS3; -// final Duration tryTimeout = Duration.ofSeconds(3); -// final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); -// setSender(entityType, entityIndex); -// -// this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, -// entityType, entityIndex, false, retryOptions) -// .disableAutoComplete() -// .maxConcurrentSessions(1) -// .buildAsyncClientForProcessor()); -// -// rollingSessionTest(); -// } -// -// private void rollingSessionTest() throws InterruptedException { -// final String contents = "Some-contents"; -// final String randomPrefix = UUID.randomUUID().toString(); -// ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); -// ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); -// -// CountDownLatch latch = new CountDownLatch(2); -// toClose(sender.sendMessage(message0) -// .thenMany(receiver.receiveMessages()) -// .flatMap(m -> receiver.complete(m).thenReturn(m)) -// .filter(m -> m.getMessageId().startsWith(randomPrefix)) -// .flatMap(m -> -// (message0.getMessageId().equals(m.getMessageId())) -// ? sender.sendMessage(message1).thenReturn(m) : Mono.just(m) -// ) -// .subscribe(m -> latch.countDown(), ex -> fail(ex))); -// -// assertTrue(latch.await(20, TimeUnit.SECONDS)); -// } -// @ParameterizedTest -// @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") -// void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { -// final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS2; -// final String contents = "Some-contents"; -// final Duration sessionIdleTimeout = Duration.ofSeconds(3); -// final Duration tryTimeout = Duration.ofSeconds(10); -// setSender(entityType, entityIndex); -// final String randomPrefix = UUID.randomUUID().toString(); -// ServiceBusMessage message0 = getServiceBusMessage(contents, randomPrefix + "0").setSessionId(randomPrefix + "0"); -// ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); -// -// AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); -// this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, -// entityType, entityIndex, false, retryOptions) -// .disableAutoComplete() -// .sessionIdleTimeout(sessionIdleTimeout) -// .buildAsyncClientForProcessor()); -// -// AtomicReference sessionId = new AtomicReference<>(); -// StepVerifier.create( -// sender.sendMessage(message0) -// .thenMany(receiver.receiveMessages()) -// .flatMap(m -> receiver.complete(m).thenReturn(m)) -// .flatMap(m -> { -// if (!sessionId.compareAndSet(null, m.getSessionId())) { -// assertEquals(sessionId.get(), m.getSessionId(), "session rolling should not happen"); -// } -// return sender.sendMessage(message1).thenReturn(m); -// }) -// ) -// .expectNextCount(1) -// .verifyTimeout(tryTimeout.plusSeconds(20)); -// } -// -// /** -// * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. -// */ -// private void setSender(MessagingEntityType entityType, int entityIndex) { -// this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, true, false) -// .buildAsyncClient()); -// } -// -// private void setReceiver(MessagingEntityType entityType, int entityIndex, -// Function onBuild) { -// ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(USE_CREDENTIALS, -// entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); -// -// this.sessionReceiver = toClose(onBuild.apply(sessionBuilder).buildAsyncClient()); -// this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); -// } -// -// private static void assertMessageEquals(String sessionId, String messageId, String contents, ServiceBusReceivedMessage message) { -// assertNotNull(message, "'message' should not be null."); -// -// if (!CoreUtils.isNullOrEmpty(sessionId)) { -// assertEquals(sessionId, message.getSessionId()); -// } -// -// assertEquals(messageId, message.getMessageId()); -// assertEquals(contents, message.getBody().toString()); -// } -//} From 026493542b641bfd89b64790e5a08f2d4e0f71f4 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 16:43:36 -0700 Subject: [PATCH 07/29] enable proxy integration tests --- .../servicebus/IntegrationTestBase.java | 4 - .../servicebus/ProxyReceiveTest.java | 256 +++++++++--------- .../servicebus/ProxySelectorTest.java | 191 +++++++------ .../messaging/servicebus/ProxySendTest.java | 210 +++++++------- 4 files changed, 345 insertions(+), 316 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 6be95449ed5f..9978f7755525 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -220,16 +220,12 @@ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { .scheduler(scheduler) .configuration(v1OrV2(true)); - System.out.println("Getting Builder using credentials : " + useCredentials); logger.info("Getting Builder using credentials : [{}] ", useCredentials); if (useCredentials) { final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - return builder.credential(fullyQualifiedDomainName, tokenCredential); } else { return builder.connectionString(getConnectionString()); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index fb606440490b..cf9dbb9e8f32 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -3,128 +3,138 @@ package com.azure.messaging.servicebus; -public class ProxyReceiveTest { +import com.azure.core.amqp.AmqpTransportType; +import com.azure.core.credential.TokenCredential; +import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.AzurePowerShellCredentialBuilder; +import com.azure.messaging.servicebus.jproxy.ProxyServer; +import com.azure.messaging.servicebus.jproxy.SimpleProxy; +import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; +import org.apache.qpid.proton.engine.SslDomain; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; -} +import java.io.IOException; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +/** + * Verify we can use jproxy hosted locally to receive messages. + */ +public class ProxyReceiveTest extends IntegrationTestBase { + private static final int PROXY_PORT = 9102; + private static final int NUMBER_OF_EVENTS = 10; + + private static ProxyServer proxyServer; + private static ProxySelector defaultProxySelector; + + public ProxyReceiveTest() { + super(new ClientLogger(ProxyReceiveTest.class)); + } + + @BeforeEach + public void setup() throws IOException { + proxyServer = new SimpleProxy(PROXY_PORT); + proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); + + defaultProxySelector = ProxySelector.getDefault(); + ProxySelector.setDefault(new ProxySelector() { + @Override + public List select(URI uri) { + List proxies = new ArrayList<>(); + proxies.add(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); + return proxies; + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + // no-op + } + }); + } + + @AfterEach() + public void cleanup() throws Exception { + if (proxyServer != null) { + proxyServer.stop(); + } + + ProxySelector.setDefault(defaultProxySelector); + } + + @Test + public void receiveMessage() { + // Arrange + final String queueName = getQueueName(0); -// -//import com.azure.core.amqp.AmqpTransportType; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.identity.AzurePowerShellCredentialBuilder; -//import com.azure.messaging.servicebus.jproxy.ProxyServer; -//import com.azure.messaging.servicebus.jproxy.SimpleProxy; -//import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; -//import org.apache.qpid.proton.engine.SslDomain; -//import org.junit.jupiter.api.AfterEach; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.Test; -//import reactor.test.StepVerifier; -// -//import java.io.IOException; -//import java.net.Proxy; -//import java.net.ProxySelector; -//import java.net.SocketAddress; -//import java.net.URI; -//import java.time.Duration; -//import java.util.ArrayList; -//import java.util.List; -//import java.util.UUID; -// -///** -// * Verify we can use jproxy hosted locally to receive messages. -// */ -//public class ProxyReceiveTest extends IntegrationTestBase { -// private static final int PROXY_PORT = 9102; -// private static final int NUMBER_OF_EVENTS = 10; -// -// private static ProxyServer proxyServer; -// private static ProxySelector defaultProxySelector; -// -// public ProxyReceiveTest() { -// super(new ClientLogger(ProxyReceiveTest.class)); -// } -// -// @BeforeEach -// public void setup() throws IOException { -// proxyServer = new SimpleProxy(PROXY_PORT); -// proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); -// -// defaultProxySelector = ProxySelector.getDefault(); -// ProxySelector.setDefault(new ProxySelector() { -// @Override -// public List select(URI uri) { -// List proxies = new ArrayList<>(); -// proxies.add(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); -// return proxies; -// } -// -// @Override -// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { -// // no-op -// } -// }); -// } -// -// @AfterEach() -// public void cleanup() throws Exception { -// if (proxyServer != null) { -// proxyServer.stop(); -// } -// -// ProxySelector.setDefault(defaultProxySelector); -// } -// -// @Test -// public void receiveMessage() { -// // Arrange -// final String queueName = getQueueName(0); -// -// Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); -// -// final String messageTracking = UUID.randomUUID().toString(); -// -// final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageTracking); -// final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() -// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) -// .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) -// .credential(new AzurePowerShellCredentialBuilder().build()) -// .sender() -// .queueName(queueName) -// .buildAsyncClient(); -// -// toClose(sender); -// -// final ServiceBusReceiverAsyncClient receiver = new ServiceBusClientBuilder() -// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) -// .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) -// .credential(new AzurePowerShellCredentialBuilder().build()) -// .receiver() -// .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) -// .queueName(queueName) -// .buildAsyncClient(); -// -// toClose(receiver); -// -// // Act & Assert -// try { -// StepVerifier.create(sender.createMessageBatch() -// .flatMap(batch -> { -// for (int i = 0; i < messages.size(); i++) { -// Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); -// } -// -// return sender.sendMessages(batch); -// })) -// .expectComplete() -// .verify(Duration.ofSeconds(30)); -// -// StepVerifier.create(receiver.receiveMessages().take(NUMBER_OF_EVENTS)) -// .expectNextCount(NUMBER_OF_EVENTS) -// .expectComplete() -// .verify(TIMEOUT); -// } finally { -// dispose(sender, receiver); -// } -// } -//} + Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); + + final String messageTracking = UUID.randomUUID().toString(); + + final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageTracking); + final ServiceBusSenderAsyncClient sender = getBuilder(USE_CREDENTIALS, logger) + .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) + .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) + .sender() + .queueName(queueName) + .buildAsyncClient(); + + toClose(sender); + + final ServiceBusReceiverAsyncClient receiver = getBuilder(USE_CREDENTIALS, logger) + .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) + .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) + .receiver() + .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) + .queueName(queueName) + .buildAsyncClient(); + + toClose(receiver); + + // Act & Assert + try { + StepVerifier.create(sender.createMessageBatch() + .flatMap(batch -> { + for (int i = 0; i < messages.size(); i++) { + Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); + } + + return sender.sendMessages(batch); + })) + .expectComplete() + .verify(Duration.ofSeconds(30)); + + StepVerifier.create(receiver.receiveMessages().take(NUMBER_OF_EVENTS)) + .expectNextCount(NUMBER_OF_EVENTS) + .expectComplete() + .verify(TIMEOUT); + } finally { + dispose(sender, receiver); + } + } + + private static ServiceBusClientBuilder getBuilder(boolean useCredentials, ClientLogger logger) { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + logger.info("Getting Builder using credentials : [{}] ", useCredentials); + if (useCredentials) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), + "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); + final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + return builder.credential(fullyQualifiedDomainName, tokenCredential); + } else { + return builder.connectionString(getConnectionString()); + } + } +} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java index 95211553f56b..72dca1af7534 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java @@ -3,95 +3,106 @@ package com.azure.messaging.servicebus; -public class ProxySelectorTest { +import com.azure.core.amqp.AmqpRetryOptions; +import com.azure.core.amqp.AmqpTransportType; +import com.azure.core.credential.TokenCredential; +import com.azure.core.util.BinaryData; +import com.azure.core.util.logging.ClientLogger; +import com.azure.core.util.logging.LogLevel; +import com.azure.identity.AzurePowerShellCredentialBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; -} +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +public class ProxySelectorTest extends IntegrationTestBase { + private static final ClientLogger LOGGER = new ClientLogger(ProxySelectorTest.class); + + private static final int PROXY_PORT = 9002; + private static final InetSocketAddress SIMPLE_PROXY_ADDRESS = new InetSocketAddress("localhost", PROXY_PORT); + private ProxySelector defaultProxySelector; + + public ProxySelectorTest() { + super(new ClientLogger(ProxySelectorTest.class)); + } + + @Override + public void beforeTest() { + defaultProxySelector = ProxySelector.getDefault(); + } + + @Override + public void afterTest() { + ProxySelector.setDefault(defaultProxySelector); + } + + @Disabled("Fix when proxy error is propagated back up to receiver.") + @Test + public void proxySelectorConnectFailedInvokeTest() throws InterruptedException { + final String queueName = getQueueName(9); -// -//import com.azure.core.amqp.AmqpRetryOptions; -//import com.azure.core.amqp.AmqpTransportType; -//import com.azure.core.util.BinaryData; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.core.util.logging.LogLevel; -//import com.azure.identity.AzurePowerShellCredentialBuilder; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.Disabled; -//import org.junit.jupiter.api.Test; -//import reactor.test.StepVerifier; -// -//import java.io.IOException; -//import java.net.InetSocketAddress; -//import java.net.Proxy; -//import java.net.ProxySelector; -//import java.net.SocketAddress; -//import java.net.URI; -//import java.time.Duration; -//import java.util.Collections; -//import java.util.List; -//import java.util.concurrent.CountDownLatch; -//import java.util.concurrent.TimeUnit; -// -//public class ProxySelectorTest extends IntegrationTestBase { -// private static final ClientLogger LOGGER = new ClientLogger(ProxySelectorTest.class); -// -// private static final int PROXY_PORT = 9002; -// private static final InetSocketAddress SIMPLE_PROXY_ADDRESS = new InetSocketAddress("localhost", PROXY_PORT); -// private ProxySelector defaultProxySelector; -// -// public ProxySelectorTest() { -// super(new ClientLogger(ProxySelectorTest.class)); -// } -// -// @Override -// public void beforeTest() { -// defaultProxySelector = ProxySelector.getDefault(); -// } -// -// @Override -// public void afterTest() { -// ProxySelector.setDefault(defaultProxySelector); -// } -// -// @Disabled("Fix when proxy error is propagated back up to receiver.") -// @Test -// public void proxySelectorConnectFailedInvokeTest() throws InterruptedException { -// final String queueName = getQueueName(9); -// -// Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); -// -// // doesn't start proxy server and verifies that the connectFailed callback is invoked. -// final CountDownLatch countDownLatch = new CountDownLatch(1); -// ProxySelector.setDefault(new ProxySelector() { -// @Override -// public List select(URI uri) { -// return Collections.singletonList(new Proxy(Proxy.Type.HTTP, SIMPLE_PROXY_ADDRESS)); -// } -// -// @Override -// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { -// countDownLatch.countDown(); -// } -// }); -// -// final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); -// final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() -// .credential(new AzurePowerShellCredentialBuilder().build()) -// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) -// .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) -// .sender() -// .queueName(queueName) -// .buildAsyncClient(); -// -// toClose(sender); -// StepVerifier.create(sender.sendMessage(message)) -// .expectErrorSatisfies(error -> { -// // The message can vary because it is returned from proton-j, so we don't want to compare against that. -// // This is a transient error from ExceptionUtil.java: line 67. -// LOGGER.log(LogLevel.VERBOSE, () -> "Error", error); -// }) -// .verify(TIMEOUT); -// -// final boolean awaited = countDownLatch.await(2, TimeUnit.SECONDS); -// Assertions.assertTrue(awaited); -// } -//} + Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); + + // doesn't start proxy server and verifies that the connectFailed callback is invoked. + final CountDownLatch countDownLatch = new CountDownLatch(1); + ProxySelector.setDefault(new ProxySelector() { + @Override + public List select(URI uri) { + return Collections.singletonList(new Proxy(Proxy.Type.HTTP, SIMPLE_PROXY_ADDRESS)); + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + countDownLatch.countDown(); + } + }); + + final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); + final ServiceBusSenderAsyncClient sender = getBuilder(USE_CREDENTIALS, logger) + .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) + .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) + .sender() + .queueName(queueName) + .buildAsyncClient(); + + toClose(sender); + StepVerifier.create(sender.sendMessage(message)) + .expectErrorSatisfies(error -> { + // The message can vary because it is returned from proton-j, so we don't want to compare against that. + // This is a transient error from ExceptionUtil.java: line 67. + LOGGER.log(LogLevel.VERBOSE, () -> "Error", error); + }) + .verify(TIMEOUT); + + final boolean awaited = countDownLatch.await(2, TimeUnit.SECONDS); + Assertions.assertTrue(awaited); + } + + private static ServiceBusClientBuilder getBuilder(boolean useCredentials, ClientLogger logger) { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + logger.info("Getting Builder using credentials : [{}] ", useCredentials); + if (useCredentials) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), + "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); + final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + return builder.credential(fullyQualifiedDomainName, tokenCredential); + } else { + return builder.connectionString(getConnectionString()); + } + } +} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index 8b4c53e374a8..d38ef012043c 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -3,104 +3,116 @@ package com.azure.messaging.servicebus; -public class ProxySendTest { +import com.azure.core.amqp.AmqpRetryOptions; +import com.azure.core.amqp.AmqpTransportType; +import com.azure.core.credential.TokenCredential; +import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.AzurePowerShellCredentialBuilder; +import com.azure.messaging.servicebus.jproxy.ProxyServer; +import com.azure.messaging.servicebus.jproxy.SimpleProxy; +import org.apache.qpid.proton.engine.SslDomain; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.test.StepVerifier; -} +import java.io.IOException; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +public class ProxySendTest extends IntegrationTestBase { + private static final int PROXY_PORT = 9101; + private static final int NUMBER_OF_EVENTS = 10; + + private static ProxyServer proxyServer; + private static ProxySelector defaultProxySelector; + + public ProxySendTest() { + super(new ClientLogger(ProxySendTest.class)); + } + + @BeforeEach + public void initialize() throws Exception { + proxyServer = new SimpleProxy(PROXY_PORT); + proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); + + defaultProxySelector = ProxySelector.getDefault(); + ProxySelector.setDefault(new ProxySelector() { + @Override + public List select(URI uri) { + return Collections.singletonList(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + // no-op + } + }); + } -//import com.azure.core.amqp.AmqpRetryOptions; -//import com.azure.core.amqp.AmqpTransportType; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.identity.AzurePowerShellCredentialBuilder; -//import com.azure.messaging.servicebus.jproxy.ProxyServer; -//import com.azure.messaging.servicebus.jproxy.SimpleProxy; -//import org.apache.qpid.proton.engine.SslDomain; -//import org.junit.jupiter.api.AfterEach; -//import org.junit.jupiter.api.Assertions; -//import org.junit.jupiter.api.BeforeEach; -//import org.junit.jupiter.api.Test; -//import reactor.test.StepVerifier; -// -//import java.io.IOException; -//import java.net.Proxy; -//import java.net.ProxySelector; -//import java.net.SocketAddress; -//import java.net.URI; -//import java.time.Duration; -//import java.util.Collections; -//import java.util.List; -//import java.util.UUID; -// -//public class ProxySendTest extends IntegrationTestBase { -// private static final int PROXY_PORT = 9101; -// private static final int NUMBER_OF_EVENTS = 10; -// -// private static ProxyServer proxyServer; -// private static ProxySelector defaultProxySelector; -// -// public ProxySendTest() { -// super(new ClientLogger(ProxySendTest.class)); -// } -// -// @BeforeEach -// public void initialize() throws Exception { -// proxyServer = new SimpleProxy(PROXY_PORT); -// proxyServer.start(error -> logger.error("Exception occurred in proxy.", error)); -// -// defaultProxySelector = ProxySelector.getDefault(); -// ProxySelector.setDefault(new ProxySelector() { -// @Override -// public List select(URI uri) { -// return Collections.singletonList(new Proxy(Proxy.Type.HTTP, proxyServer.getHost())); -// } -// -// @Override -// public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { -// // no-op -// } -// }); -// } -// -// @AfterEach -// public void cleanup() throws Exception { -// ProxySelector.setDefault(defaultProxySelector); -// -// if (proxyServer != null) { -// proxyServer.stop(); -// } -// } -// -// /** -// * Verifies that we can send some number of events. -// */ -// @Test -// public void sendEvents() { -// // Arrange -// final String queueName = getQueueName(TestUtils.USE_CASE_PROXY); -// -// Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); -// -// final String messageId = UUID.randomUUID().toString(); -// -// final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); -// final ServiceBusSenderAsyncClient sender = new ServiceBusClientBuilder() -// .credential(new AzurePowerShellCredentialBuilder().build()) -// .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) -// .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) -// .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) -// .sender() -// .queueName(queueName) -// .buildAsyncClient(); -// toClose(sender); -// // Act & Assert -// StepVerifier.create(sender.createMessageBatch() -// .flatMap(batch -> { -// for (int i = 0; i < messages.size(); i++) { -// Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); -// } -// -// return sender.sendMessages(batch); -// })) -// .expectComplete() -// .verify(Duration.ofSeconds(30)); -// } -//} + @AfterEach + public void cleanup() throws Exception { + ProxySelector.setDefault(defaultProxySelector); + + if (proxyServer != null) { + proxyServer.stop(); + } + } + + /** + * Verifies that we can send some number of events. + */ + @Test + public void sendEvents() { + // Arrange + final String queueName = getQueueName(TestUtils.USE_CASE_PROXY); + + Assertions.assertNotNull(queueName, "'queueName' is not set in environment variable."); + + final String messageId = UUID.randomUUID().toString(); + + final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); + final ServiceBusSenderAsyncClient sender = getBuilder(USE_CREDENTIALS, logger) + .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) + .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) + .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) + .sender() + .queueName(queueName) + .buildAsyncClient(); + toClose(sender); + // Act & Assert + StepVerifier.create(sender.createMessageBatch() + .flatMap(batch -> { + for (int i = 0; i < messages.size(); i++) { + Assertions.assertTrue(batch.tryAddMessage(messages.get(i)), "Unable to add message: " + i); + } + + return sender.sendMessages(batch); + })) + .expectComplete() + .verify(Duration.ofSeconds(30)); + } + + private static ServiceBusClientBuilder getBuilder(boolean useCredentials, ClientLogger logger) { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + logger.info("Getting Builder using credentials : [{}] ", useCredentials); + if (useCredentials) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), + "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); + final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + return builder.credential(fullyQualifiedDomainName, tokenCredential); + } else { + return builder.connectionString(getConnectionString()); + } + } +} From 4ef58b9a5b216947d4ca57fd4040a141ed79c34d Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 19:33:44 -0700 Subject: [PATCH 08/29] add use-cred switch to admin tests --- .../servicebus/IntegrationTestBase.java | 2 +- ...dministrationAsyncClientIntegrationTest.java | 15 ++++++++++++--- ...eBusAdministrationClientIntegrationTest.java | 17 +++++++++++++---- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 9978f7755525..4525ebcae1fb 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -59,7 +59,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; public abstract class IntegrationTestBase extends TestBase { - protected static final boolean USE_CREDENTIALS = true; + public static final boolean USE_CREDENTIALS = true; protected static final Duration OPERATION_TIMEOUT = Duration.ofSeconds(30); protected static final Duration TIMEOUT = Duration.ofSeconds(60); // Tests use timeouts of 20-60 seconds to verify something has happened diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index d197a65758e9..4bcdcd822859 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -60,6 +60,7 @@ //import java.util.regex.Pattern; import java.util.stream.Stream; +import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; @@ -1215,10 +1216,18 @@ void updateRuleResponse(HttpClient httpClient) { } private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() - .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)); + .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)); + + if (USE_CREDENTIALS) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + builder.credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)); + } else { + final String connectionString = interceptorManager.isPlaybackMode() + ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" + : TestUtils.getConnectionString(false); + builder.connectionString(connectionString); + } if (interceptorManager.isPlaybackMode()) { builder.httpClient(interceptorManager.getPlaybackClient()); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 17238526d052..980b48d83b68 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -58,6 +58,7 @@ //import java.util.regex.Matcher; //import java.util.regex.Pattern; +import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; @@ -934,11 +935,19 @@ void listRules() { //endregion private ServiceBusAdministrationClient getClient() { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() - .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)) - .credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)) - .retryOptions(new RetryOptions(new FixedDelayOptions(1, TIMEOUT))); + .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)); + + if (USE_CREDENTIALS) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + builder.credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)); + } else { + final String connectionString = interceptorManager.isPlaybackMode() + ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" + : TestUtils.getConnectionString(false); + builder.connectionString(connectionString); + } + builder.retryOptions(new RetryOptions(new FixedDelayOptions(1, TIMEOUT))); if (interceptorManager.isPlaybackMode()) { builder.httpClient(interceptorManager.getPlaybackClient()); From 25ea00f478ae12f1f363520442dc59c4d3677166 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 1 Jul 2024 22:08:43 -0700 Subject: [PATCH 09/29] repeat --- .../ClaimsBasedSecurityChannel.java | 50 +++++----- .../servicebus/ProxyReceiveTest.java | 2 +- .../messaging/servicebus/ProxySendTest.java | 2 +- .../ServiceBusClientBuilderTest.java | 32 +++---- .../ServiceBusMixClientIntegrationTest.java | 8 +- ...viceBusProcessorClientIntegrationTest.java | 6 +- ...BusReceiverAsyncClientIntegrationTest.java | 68 +++++++------- ...rviceBusReceiverClientIntegrationTest.java | 42 +++++---- ...ceBusSenderAsyncClientIntegrationTest.java | 20 ++-- ...ServiceBusSenderClientIntegrationTest.java | 10 +- ...rviceBusSessionManagerIntegrationTest.java | 8 +- ...inistrationAsyncClientIntegrationTest.java | 92 +++++++++--------- ...usAdministrationClientIntegrationTest.java | 93 ++++++++++--------- 13 files changed, 219 insertions(+), 214 deletions(-) diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java index 2befe95dbbb3..aa7394e7ac17 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java @@ -63,35 +63,37 @@ public ClaimsBasedSecurityChannel(Mono responseChannelMo @Override public Mono authorize(String tokenAudience, String scopes) { return cbsChannelMono.flatMap( - channel -> credential.getToken(new TokenRequestContext().addScopes(scopes)).flatMap(accessToken -> { - final Message request = Proton.message(); - final Map properties = new HashMap<>(); - properties.put(PUT_TOKEN_OPERATION, PUT_TOKEN_OPERATION_VALUE); - properties.put(PUT_TOKEN_EXPIRY, Date.from(accessToken.getExpiresAt().toInstant())); - properties.put(PUT_TOKEN_TYPE, authorizationType.toString()); - properties.put(PUT_TOKEN_AUDIENCE, tokenAudience); + channel -> { + System.out.println(OffsetDateTime.now() + ": Requesting token..."); + return credential.getToken(new TokenRequestContext().addScopes(scopes)).flatMap(accessToken -> { + System.out.println(OffsetDateTime.now() + ": Got token...: " + accessToken.getExpiresAt()); + final Message request = Proton.message(); + final Map properties = new HashMap<>(); + properties.put(PUT_TOKEN_OPERATION, PUT_TOKEN_OPERATION_VALUE); + properties.put(PUT_TOKEN_EXPIRY, Date.from(accessToken.getExpiresAt().toInstant())); + properties.put(PUT_TOKEN_TYPE, authorizationType.toString()); + properties.put(PUT_TOKEN_AUDIENCE, tokenAudience); + final ApplicationProperties applicationProperties = new ApplicationProperties(properties); + request.setApplicationProperties(applicationProperties); + request.setBody(new AmqpValue(accessToken.getToken())); - final ApplicationProperties applicationProperties = new ApplicationProperties(properties); - request.setApplicationProperties(applicationProperties); - request.setBody(new AmqpValue(accessToken.getToken())); + return channel.sendWithAck(request).handle((Message message, SynchronousSink sink) -> { + if (RequestResponseUtils.isSuccessful(message)) { + sink.next(accessToken.getExpiresAt()); + } else { + final String description = getStatusDescription(message); + final AmqpResponseCode statusCode = getStatusCode(message); + final Exception error = amqpResponseCodeToException(statusCode.getValue(), description, + channel.getErrorContext()); - return channel.sendWithAck(request).handle((Message message, SynchronousSink sink) -> { - if (RequestResponseUtils.isSuccessful(message)) { - sink.next(accessToken.getExpiresAt()); - } else { - final String description = getStatusDescription(message); - final AmqpResponseCode statusCode = getStatusCode(message); - final Exception error = amqpResponseCodeToException(statusCode.getValue(), description, - channel.getErrorContext()); - - sink.error(error); - } - }) - .switchIfEmpty(Mono.error(() -> new AmqpException(true, + sink.error(error); + } + }).switchIfEmpty(Mono.error(() -> new AmqpException(true, String.format("No response received from CBS node. tokenAudience: '%s'. scopes: '%s'", tokenAudience, scopes), channel.getErrorContext()))); - })); + }); + }); } @Override diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index cf9dbb9e8f32..3673a5fd2b55 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -73,7 +73,7 @@ public void cleanup() throws Exception { ProxySelector.setDefault(defaultProxySelector); } - @Test + // @Test public void receiveMessage() { // Arrange final String queueName = getQueueName(0); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index d38ef012043c..75825cbba5c6 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -71,7 +71,7 @@ public void cleanup() throws Exception { /** * Verifies that we can send some number of events. */ - @Test + // @Test public void sendEvents() { // Arrange final String queueName = getQueueName(TestUtils.USE_CASE_PROXY); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index 4b3ae1225e05..c971808e8ed4 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -67,7 +67,7 @@ class ServiceBusClientBuilderTest extends IntegrationTestBase { super(new ClientLogger(ServiceBusClientBuilderTest.class)); } - @Test + // @Test void ensureIdentifierString() { final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); final ServiceBusSenderAsyncClient client = toClose(builder @@ -79,7 +79,7 @@ void ensureIdentifierString() { Assertions.assertFalse(CoreUtils.isNullOrEmpty(client.getIdentifier())); } - @Test + // @Test void deadLetterQueueClient() { // Arrange final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() @@ -96,7 +96,7 @@ void deadLetterQueueClient() { assertTrue(client.getEntityPath().endsWith(DEAD_LETTER_QUEUE_NAME_SUFFIX)); } - @Test + // @Test void transferDeadLetterqueueClient() { // Arrange final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() @@ -112,7 +112,7 @@ void transferDeadLetterqueueClient() { assertTrue(client.getEntityPath().endsWith(TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX)); } - @Test + // @Test void missingConnectionString() { assertThrows(IllegalArgumentException.class, () -> { final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); @@ -122,7 +122,7 @@ void missingConnectionString() { }); } - @Test + // @Test void defaultProxyConfigurationBuilder() { final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); final ServiceBusSenderAsyncClient client = builder.connectionString(NAMESPACE_CONNECTION_STRING) @@ -133,7 +133,7 @@ void defaultProxyConfigurationBuilder() { assertNotNull(client); } - @Test + // @Test void customNoneProxyConfigurationBuilder() { // Arrange final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.NONE, PROXY_ADDRESS, @@ -150,7 +150,7 @@ void customNoneProxyConfigurationBuilder() { assertNotNull(builder.buildAsyncClient()); } - @Test + // @Test void throwsWithProxyWhenTransportTypeNotChanged() { assertThrows(IllegalArgumentException.class, () -> { // Arrange @@ -185,7 +185,7 @@ private static Stream invalidEntityPathConfigurations() { /** * Tests different invalid entity path scenarios. */ - @ParameterizedTest + // @ParameterizedTest @MethodSource void invalidEntityPathConfigurations(String connectionString, String topicName, String queueName, String subscriptionName) { @@ -206,7 +206,7 @@ void invalidEntityPathConfigurations(String connectionString, String topicName, /** * Throws when topic name is set for receiver, but no subscription name is set. */ - @Test + // @Test void throwsWhenSubscriptionNameNotSet() { // Arrange final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() @@ -221,7 +221,7 @@ void throwsWhenSubscriptionNameNotSet() { /** * Throws when the prefetch is less than 1. */ - @Test + // @Test void invalidPrefetch() { // Arrange final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() @@ -235,7 +235,7 @@ void invalidPrefetch() { } @MethodSource("getProxyConfigurations") - @ParameterizedTest + // @ParameterizedTest public void testProxyOptionsConfiguration(String proxyConfiguration) { Configuration configuration = TestUtils.getGlobalConfiguration().clone() .put(Configuration.PROPERTY_HTTP_PROXY, proxyConfiguration) @@ -251,7 +251,7 @@ public void testProxyOptionsConfiguration(String proxyConfiguration) { .buildClient()); } - @Test + // @Test public void testConnectionStringWithSas() { String connectionStringWithEntityPath = "Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;" + "SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name"; @@ -267,7 +267,7 @@ public void testConnectionStringWithSas() { .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); } - @Test + // @Test @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureNameKeyCredential() { ConnectionStringProperties properties = getConnectionStringProperties(); @@ -292,7 +292,7 @@ public void testBatchSendEventByAzureNameKeyCredential() { .verify(TIMEOUT); } - @Test + // @Test @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureSasCredential() { ConnectionStringProperties properties = getConnectionStringProperties(true); @@ -318,7 +318,7 @@ public void testBatchSendEventByAzureSasCredential() { .verify(TIMEOUT); } - @Test + // @Test public void testConnectionWithAzureNameKeyCredential() { String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); String sharedAccessKeyName = "SharedAccessKeyName test-value"; @@ -353,7 +353,7 @@ public void testConnectionWithAzureNameKeyCredential() { } - @Test + // @Test public void testConnectionWithAzureSasCredential() { String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); String sharedAccessSignature = "SharedAccessSignature test-value"; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java index bf0e6bfe1f20..a9fffdc0f75f 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java @@ -79,7 +79,7 @@ protected void afterTest() { * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - @ParameterizedTest + // @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { @@ -187,7 +187,7 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - @ParameterizedTest + // @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { @@ -304,7 +304,7 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - @ParameterizedTest + // @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { @@ -391,7 +391,7 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - @ParameterizedTest + // @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index cad23138cf20..d2399eaaa52e 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -55,7 +55,7 @@ protected void afterTest() { * again. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange // The message is locked for this duration at a time. @@ -104,7 +104,7 @@ void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) th LOGGER.info("Message lock has been renewed. Now closing processor"); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; @@ -120,7 +120,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup rollingSessionTest(sender, processorBuilder); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index 7e649c5a82d0..6efc19972d11 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -101,7 +101,7 @@ protected void afterTest() { /** * Verifies that we can create multiple transaction using sender and receiver. */ - @Test + // @Test void createMultipleTransactionTest() { // Arrange setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); @@ -122,7 +122,7 @@ void createMultipleTransactionTest() { * Verifies that we can create transaction and complete. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -164,7 +164,7 @@ void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { * Verifies that we can do following using shared connection and on non session entity. 1. create transaction 2. * receive and settle with transactionContext. 3. commit Rollback this transaction. */ - @ParameterizedTest + // @ParameterizedTest @EnumSource(DispositionStatus.class) void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { @@ -237,7 +237,7 @@ void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { * sender 2. receive and complete with transactionContext. 3. Commit this transaction using sender. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest @Disabled void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { // Arrange @@ -281,7 +281,7 @@ void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { * Verifies that we can send and receive two messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = 0; @@ -321,7 +321,7 @@ void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSe * Verifies that we can send and receive a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = USE_CASE_AUTO_COMPLETE; @@ -363,7 +363,7 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest @Disabled("Investigate: Could not emit tick 0 due to lack of requests (interval doesn't support small downstream requests that replenish slower than the ticks)))") void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange @@ -392,7 +392,7 @@ void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { * Verifies that an empty entity does not error when peeking. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -410,7 +410,7 @@ void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEna * Verifies that we can schedule and receive a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); @@ -438,7 +438,7 @@ void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSe * Verifies that we can cancel a scheduled message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -473,7 +473,7 @@ void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEna * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = 3; @@ -527,7 +527,7 @@ void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSes * Verifies that we can send and peek a batch of messages and the sequence number is tracked correctly. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest public void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange setSender(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); @@ -592,7 +592,7 @@ private Flux peekMessages(int count, String messageId * Verifies that we can send and peek a batch of messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void peekMessagesFromSequence(MessagingEntityType entityType) throws InterruptedException { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_MESSAGE_FROM_SEQUENCE, false); @@ -650,7 +650,7 @@ void peekMessagesFromSequence(MessagingEntityType entityType) throws Interrupted * Verifies that an empty entity does not error when peeking. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -668,7 +668,7 @@ void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean * Verifies that we can dead-letter a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = 0; @@ -695,7 +695,7 @@ void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) * Verifies that we can send and receive a message AMQP Sequence andValue object. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; @@ -762,7 +762,7 @@ void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEn } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); @@ -788,7 +788,7 @@ void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled * Verifies that we can renew message lock on a non-session receiver. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void receiveAndRenewLock(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -831,7 +831,7 @@ void receiveAndRenewLock(MessagingEntityType entityType) { * autoComplete is disabled. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int totalMessages = 5; @@ -861,7 +861,7 @@ void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean * This test takes longer time. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int totalMessages = 2; @@ -894,7 +894,7 @@ void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean * Verifies that the lock can be automatically renewed. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final AtomicInteger lockRenewCount = new AtomicInteger(); @@ -932,7 +932,7 @@ void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSes } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -951,7 +951,7 @@ void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); @@ -986,7 +986,7 @@ void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") - @ParameterizedTest + // @ParameterizedTest void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFERRED_MESSAGE_BY_SEQUENCE_NUMBER, false); @@ -1033,7 +1033,7 @@ void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, Disp } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) { // Arrange final boolean isSessionEnabled = true; @@ -1085,7 +1085,7 @@ void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void setAndGetSessionState(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, true); @@ -1121,7 +1121,7 @@ void setAndGetSessionState(MessagingEntityType entityType) { * Verifies that we can receive a message from dead letter queue. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final Duration shortWait = Duration.ofSeconds(2); @@ -1192,7 +1192,7 @@ void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnab } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { testRenewLock(entityType, Duration.ZERO, (m) -> { toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); @@ -1201,13 +1201,13 @@ void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedEx } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void autoRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { testRenewLock(entityType, Duration.ofSeconds(10), (m) -> Mono.empty()); } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void autoAndManualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { testRenewLock(entityType, Duration.ofSeconds(10), (m) -> { toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); @@ -1258,7 +1258,7 @@ private void testRenewLock(MessagingEntityType entityType, Duration lockRenewalD assertTrue(latch.await(2, TimeUnit.MINUTES)); } - @Test + // @Test @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") void receiveTwice() { setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); @@ -1281,7 +1281,7 @@ void receiveTwice() { .verify(OPERATION_TIMEOUT); } - @Test + // @Test @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") void receiveActiveSubscription() { setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); @@ -1304,7 +1304,7 @@ void receiveActiveSubscription() { * application properties etc). */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void receiveAndValidateProperties(MessagingEntityType entityType) { // Arrange final boolean isSessionEnabled = false; @@ -1422,7 +1422,7 @@ void receiveAndValidateProperties(MessagingEntityType entityType) { * @param entityType Entity Type. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void autoComplete(MessagingEntityType entityType) { // Arrange final Duration shortWait = Duration.ofSeconds(2); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index 7c6fb22ccb82..89adece33021 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -13,6 +13,7 @@ import com.azure.messaging.servicebus.models.CompleteOptions; import com.azure.messaging.servicebus.models.DeadLetterOptions; import com.azure.messaging.servicebus.models.DeferOptions; +import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -78,7 +79,7 @@ protected void afterTest() { * Verifies that we can only call receive() multiple times and with one of the receive does timeout. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); @@ -121,7 +122,7 @@ void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType * Verifies that we can only call receive() multiple times. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -166,7 +167,7 @@ void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSe * Verifies that we can only call receive() multiple times. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -225,7 +226,7 @@ void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSe * Verifies that we can send and receive two messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); @@ -264,7 +265,8 @@ void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSes /** * Verifies that we do not receive any message in given timeout. */ - @Test + // @Test + @RepeatedTest(8000) void receiveNoMessage() { // Arrange boolean isSessionEnabled = false; @@ -283,7 +285,7 @@ void receiveNoMessage() { /** * Verifies that we can send, receive one message and settle on non session entity. */ - @ParameterizedTest + // @ParameterizedTest @EnumSource(DispositionStatus.class) void transactionMessageAndSettle(DispositionStatus dispositionStatus) { // Arrange @@ -346,7 +348,7 @@ void transactionMessageAndSettle(DispositionStatus dispositionStatus) { * Verifies that we can send and receive one messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -378,7 +380,7 @@ void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSession * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -402,7 +404,7 @@ void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { * Verifies that an empty entity does not error when peeked. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -418,7 +420,7 @@ void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEna * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -456,7 +458,7 @@ void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSes * Verifies that we can send and peek a batch of messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange setSender(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); @@ -513,7 +515,7 @@ void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) thro * Verifies that an empty entity does not error when a batch is peeked. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -533,7 +535,7 @@ void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEn * Verifies that we can send and peek a batch of messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void peekMessagesFromSequence(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -564,7 +566,7 @@ void peekMessagesFromSequence(MessagingEntityType entityType) { * Verifies that we can dead-letter a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -592,7 +594,7 @@ void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -623,7 +625,7 @@ void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled * Verifies that we can renew message lock. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedException { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -665,7 +667,7 @@ void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedExcep } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -699,7 +701,7 @@ void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") - @ParameterizedTest + // @ParameterizedTest void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -754,7 +756,7 @@ void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, Disp } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -787,7 +789,7 @@ void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - @ParameterizedTest + // @ParameterizedTest void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index 2e7ae5ee4a9e..a7730953a862 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -91,7 +91,7 @@ static Stream transactionMessageSendAndCompleteTransaction() { * Verifies that we can send a message to a non-session queue. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionQueueSendMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); @@ -109,7 +109,7 @@ void nonSessionQueueSendMessage(MessagingEntityType entityType) { * Verifies that we can send a list of messages to a non-session entity. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionEntitySendMessageList(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); @@ -128,7 +128,7 @@ void nonSessionEntitySendMessageList(MessagingEntityType entityType) { * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionMessageBatch(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); @@ -154,7 +154,7 @@ void nonSessionMessageBatch(MessagingEntityType entityType) { * Verifies that we can send message to final destination using via-queue. */ @Disabled("The send via functionality is removing for first GA release, later we will come back to it.") - @Test + // @Test void viaQueueMessageSendTest() { // Arrange final Duration shortTimeout = Duration.ofSeconds(15); @@ -242,7 +242,7 @@ void viaQueueMessageSendTest() { * Verifies that we can send message to final destination using via-topic. */ @Disabled("The send via functionality is removed for first GA release, later we will come back to it.") - @Test + // @Test void viaTopicMessageSendTest() { // Arrange final Duration shortTimeout = Duration.ofSeconds(15); @@ -329,7 +329,7 @@ void viaTopicMessageSendTest() { * 3. Rollback/commit this transaction. */ @MethodSource - @ParameterizedTest + // @ParameterizedTest void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { // Arrange Duration shortTimeout = Duration.ofSeconds(15); @@ -389,7 +389,7 @@ void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType * Verifies that we can send using credentials. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void sendWithCredentials(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); @@ -412,7 +412,7 @@ void sendWithCredentials(MessagingEntityType entityType) { * Verifies that we can create transaction, scheduleMessage and commit. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void transactionScheduleAndCommitTest(MessagingEntityType entityType) { // Arrange @@ -455,7 +455,7 @@ void transactionScheduleAndCommitTest(MessagingEntityType entityType) { * Verifies that we can create transaction, scheduleMessages and commit. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void transactionScheduleMessagesTest(MessagingEntityType entityType) { // Arrange @@ -511,7 +511,7 @@ void transactionScheduleMessagesTest(MessagingEntityType entityType) { * Verifies that we can schedule messages and cancel them. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - @ParameterizedTest + // @ParameterizedTest void cancelScheduledMessagesTest(MessagingEntityType entityType) { // Arrange diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java index 6ca8c647a87b..553f87a0d5e4 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java @@ -71,7 +71,7 @@ static Stream receiverTypesProvider() { * Verifies that we can send a message to a non-session queue. */ @MethodSource("receiverTypesProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionQueueSendMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -89,7 +89,7 @@ void nonSessionQueueSendMessage(MessagingEntityType entityType) { * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. */ @MethodSource("receiverTypesProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionMessageBatch(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -115,7 +115,7 @@ void nonSessionMessageBatch(MessagingEntityType entityType) { * Verifies that we can send a list of messages to a non-session entity. */ @MethodSource("receiverTypesProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionEntitySendMessageList(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -132,7 +132,7 @@ void nonSessionEntitySendMessageList(MessagingEntityType entityType) { * Verifies that we can schedule a message to a non-session entity. */ @MethodSource("receiverTypesProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionScheduleMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -154,7 +154,7 @@ void nonSessionScheduleMessage(MessagingEntityType entityType) { * Verifies that we can cancel a scheduled a message to a non-session entity. */ @MethodSource("receiverTypesProvider") - @ParameterizedTest + // @ParameterizedTest void nonSessionCancelScheduleMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index 262ad0ec9b78..4c20f51bcc28 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -58,7 +58,7 @@ protected void afterTest() { } } - @ParameterizedTest + // @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void singleUnnamedSession(MessagingEntityType entityType) { // Arrange @@ -100,7 +100,7 @@ void singleUnnamedSession(MessagingEntityType entityType) { .verify(Duration.ofMinutes(2)); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; @@ -117,7 +117,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup rollingSessionTest(); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS3; @@ -153,7 +153,7 @@ private void rollingSessionTest() throws InterruptedException { assertTrue(latch.await(20, TimeUnit.SECONDS)); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS2; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 4bcdcd822859..4e3599fb6fcc 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -114,7 +114,7 @@ public static Stream createHttpClients() { // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below // * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. // */ -// @ParameterizedTest +// // @ParameterizedTest // @MethodSource("createHttpClients") // void azureIdentityCredentials(HttpClient httpClient) { // @@ -191,7 +191,7 @@ public static Stream createHttpClients() { //region Create tests - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createQueue(HttpClient httpClient) { // Arrange @@ -230,7 +230,7 @@ void createQueue(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createQueueExistingName(HttpClient httpClient) { // Arrange @@ -244,7 +244,7 @@ void createQueueExistingName(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createQueueWithForwarding(HttpClient httpClient) { // Arrange @@ -273,7 +273,7 @@ void createQueueWithForwarding(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createQueueAuthorizationRules(HttpClient httpClient) { // Arrange @@ -323,7 +323,7 @@ void createQueueAuthorizationRules(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createRule(HttpClient httpClient) { // Arrange @@ -356,7 +356,7 @@ void createRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createRuleDefaults(HttpClient httpClient) { // Arrange @@ -377,7 +377,7 @@ void createRuleDefaults(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createRuleResponse(HttpClient httpClient) { // Arrange @@ -417,7 +417,7 @@ void createRuleResponse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createSubscription(HttpClient httpClient) { // Arrange @@ -446,7 +446,7 @@ void createSubscription(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createSubscriptionWithRule(HttpClient httpClient) { // Arrange @@ -472,7 +472,7 @@ void createSubscriptionWithRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createSubscriptionExistingName(HttpClient httpClient) { // Arrange @@ -486,7 +486,7 @@ void createSubscriptionExistingName(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createSubscriptionWithForwarding(HttpClient httpClient) { // Arrange @@ -514,7 +514,7 @@ void createSubscriptionWithForwarding(HttpClient httpClient) { .verify(TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createTopicWithResponse(HttpClient httpClient) { // Arrange @@ -551,7 +551,7 @@ void createTopicWithResponse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void createTopicExistingName(HttpClient httpClient) { // Arrange @@ -573,7 +573,7 @@ void createTopicExistingName(HttpClient httpClient) { //region Delete tests - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteQueue(HttpClient httpClient) { // Arrange @@ -590,7 +590,7 @@ void deleteQueue(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteQueueDoesNotExist(HttpClient httpClient) { // Arrange @@ -603,7 +603,7 @@ void deleteQueueDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteRule(HttpClient httpClient) { // Arrange @@ -620,7 +620,7 @@ void deleteRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteRuleDoesNotExist(HttpClient httpClient) { // Arrange @@ -635,7 +635,7 @@ void deleteRuleDoesNotExist(HttpClient httpClient) { .verify(TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteSubscription(HttpClient httpClient) { // Arrange @@ -652,7 +652,7 @@ void deleteSubscription(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteSubscriptionDoesNotExist(HttpClient httpClient) { // Arrange @@ -669,7 +669,7 @@ void deleteSubscriptionDoesNotExist(HttpClient httpClient) { .verify(TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteTopic(HttpClient httpClient) { // Arrange @@ -684,7 +684,7 @@ void deleteTopic(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void deleteTopicDoesNotExist(HttpClient httpClient) { // Arrange @@ -701,7 +701,7 @@ void deleteTopicDoesNotExist(HttpClient httpClient) { //region Get and exists tests - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getQueue(HttpClient httpClient) { // Arrange @@ -727,7 +727,7 @@ void getQueue(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getNamespace(HttpClient httpClient) { // Arrange @@ -746,7 +746,7 @@ void getNamespace(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getQueueDoesNotExist(HttpClient httpClient) { // Arrange @@ -759,7 +759,7 @@ void getQueueDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getQueueExists(HttpClient httpClient) { // Arrange @@ -773,7 +773,7 @@ void getQueueExists(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getQueueExistsFalse(HttpClient httpClient) { // Arrange @@ -787,7 +787,7 @@ void getQueueExistsFalse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getQueueRuntimeProperties(HttpClient httpClient) { // Arrange @@ -808,7 +808,7 @@ void getQueueRuntimeProperties(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getRule(HttpClient httpClient) { // Arrange @@ -838,7 +838,7 @@ void getRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getRuleDoesNotExist(HttpClient httpClient) { // Arrange @@ -854,7 +854,7 @@ void getRuleDoesNotExist(HttpClient httpClient) { .verify(TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getSubscription(HttpClient httpClient) { // Arrange @@ -881,7 +881,7 @@ void getSubscription(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionDoesNotExist(HttpClient httpClient) { // Arrange @@ -895,7 +895,7 @@ void getSubscriptionDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionExists(HttpClient httpClient) { // Arrange @@ -910,7 +910,7 @@ void getSubscriptionExists(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionExistsFalse(HttpClient httpClient) { // Arrange @@ -925,7 +925,7 @@ void getSubscriptionExistsFalse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionRuntimeProperties(HttpClient httpClient) { // Arrange @@ -954,7 +954,7 @@ void getSubscriptionRuntimeProperties(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getTopic(HttpClient httpClient) { // Arrange @@ -982,7 +982,7 @@ void getTopic(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getTopicDoesNotExist(HttpClient httpClient) { // Arrange @@ -1005,7 +1005,7 @@ void getTopicDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getTopicExists(HttpClient httpClient) { // Arrange @@ -1019,7 +1019,7 @@ void getTopicExists(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getTopicExistsFalse(HttpClient httpClient) { // Arrange @@ -1033,7 +1033,7 @@ void getTopicExistsFalse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getTopicRuntimeProperties(HttpClient httpClient) { // Arrange @@ -1059,7 +1059,7 @@ void getTopicRuntimeProperties(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { // Arrange @@ -1098,7 +1098,7 @@ void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { //region List tests - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void listRules(HttpClient httpClient) { // Arrange @@ -1123,7 +1123,7 @@ void listRules(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void listQueues(HttpClient httpClient) { // Arrange @@ -1142,7 +1142,7 @@ void listQueues(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void listSubscriptions(HttpClient httpClient) { // Arrange @@ -1160,7 +1160,7 @@ void listSubscriptions(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void listTopics(HttpClient httpClient) { // Arrange @@ -1180,7 +1180,7 @@ void listTopics(HttpClient httpClient) { //endregion - @ParameterizedTest + // @ParameterizedTest @MethodSource("createHttpClients") void updateRuleResponse(HttpClient httpClient) { // Arrange diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 980b48d83b68..e2bf696631c0 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -43,6 +43,7 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -88,7 +89,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below // * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. // */ -// @Test +// // @Test // void azureIdentityCredentials() { // // Arrange // final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); @@ -129,7 +130,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below // * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. // */ -// @Test +// // @Test // void azureSasCredentialsTest() { // assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); // final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); @@ -151,7 +152,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest //region Create tests - @Test + // @Test void createQueue() { final ServiceBusAdministrationClient client = getClient(); final String queueName = testResourceNamer.randomName("queue", 10); @@ -202,7 +203,7 @@ void createQueue() { assertNotNull(runtimeProperties.getCreatedAt()); } - @Test + // @Test void createQueueWithForwarding() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -229,7 +230,7 @@ void createQueueWithForwarding() { assertNotNull(runtimeProperties.getCreatedAt()); } - @Test + // @Test void createQueueAuthorizationRules() { // Arrange final String keyName = "test-rule"; @@ -277,7 +278,7 @@ void createQueueAuthorizationRules() { assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); } - @Test + // @Test void createTopicWithResponse() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName("test", 10); @@ -304,7 +305,7 @@ void createTopicWithResponse() { assertNotNull(runtimeProperties.getCreatedAt()); } - @Test + // @Test void createTopicExistingName() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -320,7 +321,7 @@ void createTopicExistingName() { () -> client.createTopicWithResponse(topicName, expected, Context.NONE)); } - @Test + // @Test void createSubscription() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -351,7 +352,7 @@ void createSubscription() { } } - @Test + // @Test void createRule() { final ServiceBusAdministrationClient client = getClient(); @@ -375,7 +376,7 @@ void createRule() { assertTrue(actual.getFilter() instanceof FalseRuleFilter); } - @Test + // @Test void createRuleDefaults() { final ServiceBusAdministrationClient client = getClient(); @@ -389,7 +390,7 @@ void createRuleDefaults() { assertTrue(rule.getAction() instanceof EmptyRuleAction); } - @Test + // @Test void createRuleResponse() { final ServiceBusAdministrationClient client = getClient(); @@ -422,7 +423,7 @@ void createRuleResponse() { assertTrue(contents.getAction() instanceof EmptyRuleAction); } - @Test + // @Test void createQueueExistingName() { final String queueName = getEntityName(getQueueBaseName(), 5); final CreateQueueOptions options = new CreateQueueOptions(); @@ -433,7 +434,7 @@ void createQueueExistingName() { "Queue exists exception not thrown when creating a queue with existing name"); } - @Test + // @Test void createSubscriptionExistingName() { final String topicName = getEntityName(getTopicBaseName(), 2); final String subscriptionName = getSubscriptionBaseName(); @@ -444,7 +445,7 @@ void createSubscriptionExistingName() { "Queue exists exception not thrown when creating a queue with existing name"); } - @Test + // @Test void createSubscriptionWithForwarding() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -471,7 +472,7 @@ void createSubscriptionWithForwarding() { //endregion - @Test + // @Test void updateRuleResponse() { final ServiceBusAdministrationClient client = getClient(); @@ -501,7 +502,7 @@ void updateRuleResponse() { //region Get and exists tests - @Test + // @Test void getNamespace() { final ServiceBusAdministrationClient client = getClient(); @@ -513,7 +514,7 @@ void getNamespace() { } } - @Test + // @Test void getQueue() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); @@ -532,7 +533,7 @@ void getQueue() { assertNotNull(runtimeProperties.getAccessedAt()); } - @Test + // @Test void getQueueDoesNotExist() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); @@ -541,7 +542,7 @@ void getQueueDoesNotExist() { "Queue exists! But should not. Incorrect getQueue behavior"); } - @Test + // @Test void getQueueExists() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); @@ -549,7 +550,7 @@ void getQueueExists() { assertTrue(client.getQueueExists(queueName)); } - @Test + // @Test void getQueueExistsFalse() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); @@ -557,7 +558,7 @@ void getQueueExistsFalse() { assertFalse(client.getQueueExists(queueName)); } - @Test + // @Test void getQueueRuntimeProperties() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); @@ -571,7 +572,7 @@ void getQueueRuntimeProperties() { assertNotNull(runtimeProperties.getAccessedAt()); } - @Test + // @Test void getTopic() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -592,7 +593,7 @@ void getTopic() { assertNotNull(runtimeProperties.getAccessedAt()); } - @Test + // @Test void getTopicDoesNotExist() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName("topic", 10); @@ -601,7 +602,7 @@ void getTopicDoesNotExist() { "Topic exists! But should not. Incorrect getTopic behavior"); } - @Test + // @Test void getTopicExists() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -609,7 +610,7 @@ void getTopicExists() { assertTrue(client.getTopicExists(topicName)); } - @Test + // @Test void getTopicExistsFalse() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName(getTopicBaseName(), 10); @@ -617,7 +618,7 @@ void getTopicExistsFalse() { assertFalse(client.getTopicExists(topicName)); } - @Test + // @Test void getTopicRuntimeProperties() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -635,7 +636,7 @@ void getTopicRuntimeProperties() { assertEquals(0, runtimeProperties.getScheduledMessageCount()); } - @Test + // @Test void getSubscription() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -655,7 +656,7 @@ void getSubscription() { assertNotNull(runtimeProperties.getAccessedAt()); } - @Test + // @Test void getSubscriptionDoesNotExist() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -665,7 +666,7 @@ void getSubscriptionDoesNotExist() { "Subscription exists! But should not. Incorrect getSubscription behavior"); } - @Test + // @Test void getSubscriptionExists() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -674,7 +675,7 @@ void getSubscriptionExists() { assertTrue(client.getSubscriptionExists(topicName, subscriptionName)); } - @Test + // @Test void getSubscriptionExistsFalse() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -688,7 +689,7 @@ void getSubscriptionExistsFalse() { assertFalse(response); } - @Test + // @Test void getSubscriptionRuntimeProperties() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -710,7 +711,7 @@ void getSubscriptionRuntimeProperties() { assertNotNull(properties.getAccessedAt()); } - @Test + // @Test void getSubscriptionRuntimePropertiesUnauthorizedClient() { final String connectionString = interceptorManager.isPlaybackMode() ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" @@ -739,7 +740,7 @@ void getSubscriptionRuntimePropertiesUnauthorizedClient() { "Subscription runtime properties accessible by unauthorized client! This should not be possible."); } - @Test + // @Test void getRule() { final ServiceBusAdministrationClient client = getClient(); @@ -761,7 +762,7 @@ void getRule() { assertTrue(contents.getAction() instanceof EmptyRuleAction); } - @Test + // @Test void getRuleDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -779,7 +780,7 @@ void getRuleDoesNotExist() { //region Delete tests - @Test + // @Test void deleteQueue() { final ServiceBusAdministrationClient client = getClient(); final String queueName = testResourceNamer.randomName("queue", 10); @@ -789,7 +790,7 @@ void deleteQueue() { } - @Test + // @Test void deleteQueueDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -799,7 +800,7 @@ void deleteQueueDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> client.deleteQueue(queueName)); } - @Test + // @Test void deleteRule() { final ServiceBusAdministrationClient client = getClient(); final String ruleName = getEntityName(getRuleBaseName(), 9); @@ -810,7 +811,7 @@ void deleteRule() { client.deleteRule(topicName, subscriptionName, ruleName); } - @Test + // @Test void deleteRuleDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -822,7 +823,7 @@ void deleteRuleDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> client.deleteRule(topicName, subscriptionName, ruleName)); } - @Test + // @Test void deleteSubscription() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -833,7 +834,7 @@ void deleteSubscription() { client.deleteSubscription(topicName, subscriptionName); } - @Test + // @Test void deleteSubscriptionDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -847,7 +848,7 @@ void deleteSubscriptionDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> client.deleteSubscription(topicName, subscriptionName)); } - @Test + // @Test void deleteTopic() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName("topic", 10); @@ -856,7 +857,7 @@ void deleteTopic() { client.deleteTopic(topicName); } - @Test + // @Test void deleteTopicDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -870,7 +871,7 @@ void deleteTopicDoesNotExist() { //region List tests - @Test + // @Test void listQueues() { final ServiceBusAdministrationClient client = getClient(); @@ -883,7 +884,7 @@ void listQueues() { assertTrue(queueProperties.stream().findAny().isPresent()); } - @Test + // @Test void listTopics() { final ServiceBusAdministrationClient client = getClient(); @@ -896,7 +897,7 @@ void listTopics() { assertTrue(topics.stream().count() > 1); } - @Test + // @Test void listSubscriptions() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -909,7 +910,7 @@ void listSubscriptions() { assertTrue(subscriptionProperties.stream().findAny().isPresent()); } - @Test + // @Test void listRules() { final ServiceBusAdministrationClient client = getClient(); From 1becca6c1d2c68df577ac89838d604cecfa33d51 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Tue, 2 Jul 2024 08:59:32 -0700 Subject: [PATCH 10/29] attempt cache ps --- .../servicebus/IntegrationTestBase.java | 35 +++++- .../servicebus/ProxyReceiveTest.java | 9 +- .../servicebus/ProxySelectorTest.java | 7 +- .../messaging/servicebus/ProxySendTest.java | 9 +- .../ServiceBusClientBuilderTest.java | 32 +++--- .../ServiceBusMixClientIntegrationTest.java | 8 +- ...viceBusProcessorClientIntegrationTest.java | 6 +- ...BusReceiverAsyncClientIntegrationTest.java | 68 ++++++------ ...rviceBusReceiverClientIntegrationTest.java | 42 ++++---- ...ceBusSenderAsyncClientIntegrationTest.java | 20 ++-- ...ServiceBusSenderClientIntegrationTest.java | 10 +- ...rviceBusSessionManagerIntegrationTest.java | 8 +- ...inistrationAsyncClientIntegrationTest.java | 97 ++++++++--------- ...usAdministrationClientIntegrationTest.java | 100 +++++++++--------- 14 files changed, 239 insertions(+), 212 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 4525ebcae1fb..c79893332dec 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -9,6 +9,7 @@ import com.azure.core.amqp.implementation.ConnectionStringProperties; import com.azure.core.amqp.models.AmqpMessageBody; import com.azure.core.credential.TokenCredential; +import com.azure.core.credential.TokenRequestContext; import com.azure.core.experimental.util.tracing.LoggingTracerProvider; import com.azure.core.test.TestBase; import com.azure.core.test.TestContextManager; @@ -27,6 +28,7 @@ import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; import com.azure.messaging.servicebus.implementation.DispositionStatus; import com.azure.messaging.servicebus.implementation.MessagingEntityType; +import com.azure.messaging.servicebus.implementation.ServiceBusConstants; import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -41,6 +43,7 @@ import java.net.Proxy; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -59,6 +62,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; public abstract class IntegrationTestBase extends TestBase { + public static final SBPowerShellCachedCredentials PS_CREDENTIAL = new SBPowerShellCachedCredentials(); public static final boolean USE_CREDENTIALS = true; protected static final Duration OPERATION_TIMEOUT = Duration.ofSeconds(30); protected static final Duration TIMEOUT = Duration.ofSeconds(60); @@ -225,8 +229,9 @@ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - return builder.credential(fullyQualifiedDomainName, tokenCredential); + // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + // return builder.credential(fullyQualifiedDomainName, tokenCredential); + return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); } else { return builder.connectionString(getConnectionString()); } @@ -534,4 +539,30 @@ protected final Configuration v1OrV2(boolean isV2) { return new ConfigurationBuilder(configSource) .build(); } + + public static final class SBPowerShellCachedCredentials implements TokenCredential { + private final AzurePowerShellCredentialBuilder builder; + private final TokenRequestContext context; + private final Mono cached; + + public SBPowerShellCachedCredentials() { + this.builder = new AzurePowerShellCredentialBuilder(); + this.context = new TokenRequestContext().addScopes(ServiceBusConstants.AZURE_ACTIVE_DIRECTORY_SCOPE); + this.cached = Mono.fromCallable(builder::build) + .flatMap(cred -> { + return cred.getToken(context); + }).doOnNext(token -> { + System.out.println(".....Got Token.....: now=" + OffsetDateTime.now() + " ExpireAt=" + token.getExpiresAt()); + }) + .doOnError(e -> { + System.out.println(".....Fetching token failed.....:" + e); + }) + .cache(t -> Duration.ofMinutes(5), e -> Duration.ZERO, () -> Duration.ZERO); + } + + @Override + public Mono getToken(TokenRequestContext context) { + return this.cached; + } + } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index 3673a5fd2b55..e2ebee982717 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -4,9 +4,7 @@ package com.azure.messaging.servicebus; import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.credential.TokenCredential; import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.jproxy.ProxyServer; import com.azure.messaging.servicebus.jproxy.SimpleProxy; import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; @@ -73,7 +71,7 @@ public void cleanup() throws Exception { ProxySelector.setDefault(defaultProxySelector); } - // @Test + @Test public void receiveMessage() { // Arrange final String queueName = getQueueName(0); @@ -131,8 +129,9 @@ private static ServiceBusClientBuilder getBuilder(boolean useCredentials, Client final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - return builder.credential(fullyQualifiedDomainName, tokenCredential); + // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + // return builder.credential(fullyQualifiedDomainName, tokenCredential); + return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); } else { return builder.connectionString(getConnectionString()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java index 72dca1af7534..9b81e8482ad6 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java @@ -5,11 +5,9 @@ import com.azure.core.amqp.AmqpRetryOptions; import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.credential.TokenCredential; import com.azure.core.util.BinaryData; import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.logging.LogLevel; -import com.azure.identity.AzurePowerShellCredentialBuilder; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -99,8 +97,9 @@ private static ServiceBusClientBuilder getBuilder(boolean useCredentials, Client final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - return builder.credential(fullyQualifiedDomainName, tokenCredential); + // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + // return builder.credential(fullyQualifiedDomainName, tokenCredential); + return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); } else { return builder.connectionString(getConnectionString()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index 75825cbba5c6..1b3c3452b3ba 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -5,9 +5,7 @@ import com.azure.core.amqp.AmqpRetryOptions; import com.azure.core.amqp.AmqpTransportType; -import com.azure.core.credential.TokenCredential; import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.jproxy.ProxyServer; import com.azure.messaging.servicebus.jproxy.SimpleProxy; import org.apache.qpid.proton.engine.SslDomain; @@ -71,7 +69,7 @@ public void cleanup() throws Exception { /** * Verifies that we can send some number of events. */ - // @Test + @Test public void sendEvents() { // Arrange final String queueName = getQueueName(TestUtils.USE_CASE_PROXY); @@ -109,8 +107,9 @@ private static ServiceBusClientBuilder getBuilder(boolean useCredentials, Client final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - return builder.credential(fullyQualifiedDomainName, tokenCredential); + // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); + // return builder.credential(fullyQualifiedDomainName, tokenCredential); + return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); } else { return builder.connectionString(getConnectionString()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index c971808e8ed4..4b3ae1225e05 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -67,7 +67,7 @@ class ServiceBusClientBuilderTest extends IntegrationTestBase { super(new ClientLogger(ServiceBusClientBuilderTest.class)); } - // @Test + @Test void ensureIdentifierString() { final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); final ServiceBusSenderAsyncClient client = toClose(builder @@ -79,7 +79,7 @@ void ensureIdentifierString() { Assertions.assertFalse(CoreUtils.isNullOrEmpty(client.getIdentifier())); } - // @Test + @Test void deadLetterQueueClient() { // Arrange final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() @@ -96,7 +96,7 @@ void deadLetterQueueClient() { assertTrue(client.getEntityPath().endsWith(DEAD_LETTER_QUEUE_NAME_SUFFIX)); } - // @Test + @Test void transferDeadLetterqueueClient() { // Arrange final ServiceBusReceiverClientBuilder builder = new ServiceBusClientBuilder() @@ -112,7 +112,7 @@ void transferDeadLetterqueueClient() { assertTrue(client.getEntityPath().endsWith(TRANSFER_DEAD_LETTER_QUEUE_NAME_SUFFIX)); } - // @Test + @Test void missingConnectionString() { assertThrows(IllegalArgumentException.class, () -> { final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); @@ -122,7 +122,7 @@ void missingConnectionString() { }); } - // @Test + @Test void defaultProxyConfigurationBuilder() { final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); final ServiceBusSenderAsyncClient client = builder.connectionString(NAMESPACE_CONNECTION_STRING) @@ -133,7 +133,7 @@ void defaultProxyConfigurationBuilder() { assertNotNull(client); } - // @Test + @Test void customNoneProxyConfigurationBuilder() { // Arrange final ProxyOptions proxyConfig = new ProxyOptions(ProxyAuthenticationType.NONE, PROXY_ADDRESS, @@ -150,7 +150,7 @@ void customNoneProxyConfigurationBuilder() { assertNotNull(builder.buildAsyncClient()); } - // @Test + @Test void throwsWithProxyWhenTransportTypeNotChanged() { assertThrows(IllegalArgumentException.class, () -> { // Arrange @@ -185,7 +185,7 @@ private static Stream invalidEntityPathConfigurations() { /** * Tests different invalid entity path scenarios. */ - // @ParameterizedTest + @ParameterizedTest @MethodSource void invalidEntityPathConfigurations(String connectionString, String topicName, String queueName, String subscriptionName) { @@ -206,7 +206,7 @@ void invalidEntityPathConfigurations(String connectionString, String topicName, /** * Throws when topic name is set for receiver, but no subscription name is set. */ - // @Test + @Test void throwsWhenSubscriptionNameNotSet() { // Arrange final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() @@ -221,7 +221,7 @@ void throwsWhenSubscriptionNameNotSet() { /** * Throws when the prefetch is less than 1. */ - // @Test + @Test void invalidPrefetch() { // Arrange final ServiceBusReceiverClientBuilder receiverBuilder = new ServiceBusClientBuilder() @@ -235,7 +235,7 @@ void invalidPrefetch() { } @MethodSource("getProxyConfigurations") - // @ParameterizedTest + @ParameterizedTest public void testProxyOptionsConfiguration(String proxyConfiguration) { Configuration configuration = TestUtils.getGlobalConfiguration().clone() .put(Configuration.PROPERTY_HTTP_PROXY, proxyConfiguration) @@ -251,7 +251,7 @@ public void testProxyOptionsConfiguration(String proxyConfiguration) { .buildClient()); } - // @Test + @Test public void testConnectionStringWithSas() { String connectionStringWithEntityPath = "Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;" + "SharedAccessSignature=SharedAccessSignature test-value;EntityPath=sb-name"; @@ -267,7 +267,7 @@ public void testConnectionStringWithSas() { .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); } - // @Test + @Test @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureNameKeyCredential() { ConnectionStringProperties properties = getConnectionStringProperties(); @@ -292,7 +292,7 @@ public void testBatchSendEventByAzureNameKeyCredential() { .verify(TIMEOUT); } - // @Test + @Test @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureSasCredential() { ConnectionStringProperties properties = getConnectionStringProperties(true); @@ -318,7 +318,7 @@ public void testBatchSendEventByAzureSasCredential() { .verify(TIMEOUT); } - // @Test + @Test public void testConnectionWithAzureNameKeyCredential() { String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); String sharedAccessKeyName = "SharedAccessKeyName test-value"; @@ -353,7 +353,7 @@ public void testConnectionWithAzureNameKeyCredential() { } - // @Test + @Test public void testConnectionWithAzureSasCredential() { String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); String sharedAccessSignature = "SharedAccessSignature test-value"; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java index a9fffdc0f75f..bf0e6bfe1f20 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java @@ -79,7 +79,7 @@ protected void afterTest() { * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - // @ParameterizedTest + @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedException { @@ -187,7 +187,7 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - // @ParameterizedTest + @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws InterruptedException { @@ -304,7 +304,7 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - // @ParameterizedTest + @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { @@ -391,7 +391,7 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) * 2. complete the messages from entity A and write to entity B. * 2. commit the transaction. */ - // @ParameterizedTest + @ParameterizedTest @ValueSource(strings = {"true", "false"}) void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionEnabled) throws InterruptedException { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index d2399eaaa52e..cad23138cf20 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -55,7 +55,7 @@ protected void afterTest() { * again. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange // The message is locked for this duration at a time. @@ -104,7 +104,7 @@ void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) th LOGGER.info("Message lock has been renewed. Now closing processor"); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; @@ -120,7 +120,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup rollingSessionTest(sender, processorBuilder); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index 6efc19972d11..7e649c5a82d0 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -101,7 +101,7 @@ protected void afterTest() { /** * Verifies that we can create multiple transaction using sender and receiver. */ - // @Test + @Test void createMultipleTransactionTest() { // Arrange setSenderAndReceiver(MessagingEntityType.QUEUE, 0, isSessionEnabled); @@ -122,7 +122,7 @@ void createMultipleTransactionTest() { * Verifies that we can create transaction and complete. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -164,7 +164,7 @@ void createTransactionAndRollbackMessagesTest(MessagingEntityType entityType) { * Verifies that we can do following using shared connection and on non session entity. 1. create transaction 2. * receive and settle with transactionContext. 3. commit Rollback this transaction. */ - // @ParameterizedTest + @ParameterizedTest @EnumSource(DispositionStatus.class) void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { @@ -237,7 +237,7 @@ void transactionSendReceiveAndCommit(DispositionStatus dispositionStatus) { * sender 2. receive and complete with transactionContext. 3. Commit this transaction using sender. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest @Disabled void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { // Arrange @@ -281,7 +281,7 @@ void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { * Verifies that we can send and receive two messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = 0; @@ -321,7 +321,7 @@ void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSe * Verifies that we can send and receive a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = USE_CASE_AUTO_COMPLETE; @@ -363,7 +363,7 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest @Disabled("Investigate: Could not emit tick 0 due to lack of requests (interval doesn't support small downstream requests that replenish slower than the ticks)))") void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange @@ -392,7 +392,7 @@ void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { * Verifies that an empty entity does not error when peeking. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -410,7 +410,7 @@ void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEna * Verifies that we can schedule and receive a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_SEND_SCHEDULED, isSessionEnabled); @@ -438,7 +438,7 @@ void sendScheduledMessageAndReceive(MessagingEntityType entityType, boolean isSe * Verifies that we can cancel a scheduled message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -473,7 +473,7 @@ void cancelScheduledMessage(MessagingEntityType entityType, boolean isSessionEna * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = 3; @@ -527,7 +527,7 @@ void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSes * Verifies that we can send and peek a batch of messages and the sequence number is tracked correctly. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest public void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange setSender(entityType, USE_CASE_PEEK_BATCH_MESSAGES, isSessionEnabled); @@ -592,7 +592,7 @@ private Flux peekMessages(int count, String messageId * Verifies that we can send and peek a batch of messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void peekMessagesFromSequence(MessagingEntityType entityType) throws InterruptedException { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_PEEK_MESSAGE_FROM_SEQUENCE, false); @@ -650,7 +650,7 @@ void peekMessagesFromSequence(MessagingEntityType entityType) throws Interrupted * Verifies that an empty entity does not error when peeking. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -668,7 +668,7 @@ void peekMessagesFromSequenceEmptyEntity(MessagingEntityType entityType, boolean * Verifies that we can dead-letter a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = 0; @@ -695,7 +695,7 @@ void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) * Verifies that we can send and receive a message AMQP Sequence andValue object. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int entityIndex = TestUtils.USE_CASE_AMQP_TYPES; @@ -762,7 +762,7 @@ void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEn } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, USE_CASE_RECEIVE_AND_COMPLETE, isSessionEnabled); @@ -788,7 +788,7 @@ void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled * Verifies that we can renew message lock on a non-session receiver. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void receiveAndRenewLock(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -831,7 +831,7 @@ void receiveAndRenewLock(MessagingEntityType entityType) { * autoComplete is disabled. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int totalMessages = 5; @@ -861,7 +861,7 @@ void receiveMessagesNoMessageSettlement(MessagingEntityType entityType, boolean * This test takes longer time. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final int totalMessages = 2; @@ -894,7 +894,7 @@ void receiveMessagesLargeProcessingTime(MessagingEntityType entityType, boolean * Verifies that the lock can be automatically renewed. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final AtomicInteger lockRenewCount = new AtomicInteger(); @@ -932,7 +932,7 @@ void autoRenewLockOnReceiveMessage(MessagingEntityType entityType, boolean isSes } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -951,7 +951,7 @@ void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_PEEK_RECEIVE_AND_DEFER, isSessionEnabled); @@ -986,7 +986,7 @@ void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") - // @ParameterizedTest + @ParameterizedTest void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFERRED_MESSAGE_BY_SEQUENCE_NUMBER, false); @@ -1033,7 +1033,7 @@ void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, Disp } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) { // Arrange final boolean isSessionEnabled = true; @@ -1085,7 +1085,7 @@ void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType) } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void setAndGetSessionState(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, true); @@ -1121,7 +1121,7 @@ void setAndGetSessionState(MessagingEntityType entityType) { * Verifies that we can receive a message from dead letter queue. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange final Duration shortWait = Duration.ofSeconds(2); @@ -1192,7 +1192,7 @@ void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnab } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { testRenewLock(entityType, Duration.ZERO, (m) -> { toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); @@ -1201,13 +1201,13 @@ void manualRenewMessageLock(MessagingEntityType entityType) throws InterruptedEx } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void autoRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { testRenewLock(entityType, Duration.ofSeconds(10), (m) -> Mono.empty()); } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void autoAndManualRenewMessageLock(MessagingEntityType entityType) throws InterruptedException { testRenewLock(entityType, Duration.ofSeconds(10), (m) -> { toClose(receiver.renewMessageLock(m, Duration.ofSeconds(10)).subscribe()); @@ -1258,7 +1258,7 @@ private void testRenewLock(MessagingEntityType entityType, Duration lockRenewalD assertTrue(latch.await(2, TimeUnit.MINUTES)); } - // @Test + @Test @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") void receiveTwice() { setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); @@ -1281,7 +1281,7 @@ void receiveTwice() { .verify(OPERATION_TIMEOUT); } - // @Test + @Test @Disabled("V2 low level async-receiver impl is missing a check to error if reactive app subscribed more than once.") void receiveActiveSubscription() { setSenderAndReceiver(MessagingEntityType.QUEUE, TestUtils.USE_CASE_DEFAULT, false); @@ -1304,7 +1304,7 @@ void receiveActiveSubscription() { * application properties etc). */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void receiveAndValidateProperties(MessagingEntityType entityType) { // Arrange final boolean isSessionEnabled = false; @@ -1422,7 +1422,7 @@ void receiveAndValidateProperties(MessagingEntityType entityType) { * @param entityType Entity Type. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void autoComplete(MessagingEntityType entityType) { // Arrange final Duration shortWait = Duration.ofSeconds(2); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index 89adece33021..7c6fb22ccb82 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -13,7 +13,6 @@ import com.azure.messaging.servicebus.models.CompleteOptions; import com.azure.messaging.servicebus.models.DeadLetterOptions; import com.azure.messaging.servicebus.models.DeferOptions; -import org.junit.jupiter.api.RepeatedTest; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -79,7 +78,7 @@ protected void afterTest() { * Verifies that we can only call receive() multiple times and with one of the receive does timeout. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_MULTIPLE_RECEIVE_ONE_TIMEOUT, isSessionEnabled); @@ -122,7 +121,7 @@ void multipleReceiveByOneSubscriberMessageTimeout(MessagingEntityType entityType * Verifies that we can only call receive() multiple times. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -167,7 +166,7 @@ void multipleReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSe * Verifies that we can only call receive() multiple times. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -226,7 +225,7 @@ void parallelReceiveByOneSubscriber(MessagingEntityType entityType, boolean isSe * Verifies that we can send and receive two messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_RECEIVE_MORE_AND_COMPLETE, isSessionEnabled); @@ -265,8 +264,7 @@ void receiveTwoMessagesAndComplete(MessagingEntityType entityType, boolean isSes /** * Verifies that we do not receive any message in given timeout. */ - // @Test - @RepeatedTest(8000) + @Test void receiveNoMessage() { // Arrange boolean isSessionEnabled = false; @@ -285,7 +283,7 @@ void receiveNoMessage() { /** * Verifies that we can send, receive one message and settle on non session entity. */ - // @ParameterizedTest + @ParameterizedTest @EnumSource(DispositionStatus.class) void transactionMessageAndSettle(DispositionStatus dispositionStatus) { // Arrange @@ -348,7 +346,7 @@ void transactionMessageAndSettle(DispositionStatus dispositionStatus) { * Verifies that we can send and receive one messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -380,7 +378,7 @@ void receiveMessageAndComplete(MessagingEntityType entityType, boolean isSession * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -404,7 +402,7 @@ void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { * Verifies that an empty entity does not error when peeked. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -420,7 +418,7 @@ void peekMessageEmptyEntity(MessagingEntityType entityType, boolean isSessionEna * Verifies that we can send and peek a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -458,7 +456,7 @@ void peekFromSequenceNumberMessage(MessagingEntityType entityType, boolean isSes * Verifies that we can send and peek a batch of messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) throws InterruptedException { // Arrange setSender(entityType, USE_CASE_PEEK_BATCH, isSessionEnabled); @@ -515,7 +513,7 @@ void peekMessages(MessagingEntityType entityType, boolean isSessionEnabled) thro * Verifies that an empty entity does not error when a batch is peeked. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setReceiver(entityType, TestUtils.USE_CASE_EMPTY_ENTITY, isSessionEnabled); @@ -535,7 +533,7 @@ void peekMessagesEmptyEntity(MessagingEntityType entityType, boolean isSessionEn * Verifies that we can send and peek a batch of messages. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void peekMessagesFromSequence(MessagingEntityType entityType) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -566,7 +564,7 @@ void peekMessagesFromSequence(MessagingEntityType entityType) { * Verifies that we can dead-letter a message. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -594,7 +592,7 @@ void deadLetterMessage(MessagingEntityType entityType, boolean isSessionEnabled) } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -625,7 +623,7 @@ void receiveAndComplete(MessagingEntityType entityType, boolean isSessionEnabled * Verifies that we can renew message lock. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedException { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -667,7 +665,7 @@ void receiveAndRenewLock(MessagingEntityType entityType) throws InterruptedExcep } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -701,7 +699,7 @@ void receiveAndAbandon(MessagingEntityType entityType, boolean isSessionEnabled) * Test we can receive a deferred message via sequence number and then perform abandon, suspend, or complete on it. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#receiveDeferredMessageBySequenceNumber") - // @ParameterizedTest + @ParameterizedTest void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, DispositionStatus dispositionStatus) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, false); @@ -756,7 +754,7 @@ void receiveDeferredMessageBySequenceNumber(MessagingEntityType entityType, Disp } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_DEFAULT, isSessionEnabled); @@ -789,7 +787,7 @@ void receiveAndDefer(MessagingEntityType entityType, boolean isSessionEnabled) { } @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") - // @ParameterizedTest + @ParameterizedTest void sendReceiveMessageWithVariousPropertyTypes(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, TestUtils.USE_CASE_SEND_RECEIVE_WITH_PROPERTIES, isSessionEnabled); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index a7730953a862..2e7ae5ee4a9e 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -91,7 +91,7 @@ static Stream transactionMessageSendAndCompleteTransaction() { * Verifies that we can send a message to a non-session queue. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionQueueSendMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); @@ -109,7 +109,7 @@ void nonSessionQueueSendMessage(MessagingEntityType entityType) { * Verifies that we can send a list of messages to a non-session entity. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionEntitySendMessageList(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); @@ -128,7 +128,7 @@ void nonSessionEntitySendMessageList(MessagingEntityType entityType) { * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionMessageBatch(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); @@ -154,7 +154,7 @@ void nonSessionMessageBatch(MessagingEntityType entityType) { * Verifies that we can send message to final destination using via-queue. */ @Disabled("The send via functionality is removing for first GA release, later we will come back to it.") - // @Test + @Test void viaQueueMessageSendTest() { // Arrange final Duration shortTimeout = Duration.ofSeconds(15); @@ -242,7 +242,7 @@ void viaQueueMessageSendTest() { * Verifies that we can send message to final destination using via-topic. */ @Disabled("The send via functionality is removed for first GA release, later we will come back to it.") - // @Test + @Test void viaTopicMessageSendTest() { // Arrange final Duration shortTimeout = Duration.ofSeconds(15); @@ -329,7 +329,7 @@ void viaTopicMessageSendTest() { * 3. Rollback/commit this transaction. */ @MethodSource - // @ParameterizedTest + @ParameterizedTest void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { // Arrange Duration shortTimeout = Duration.ofSeconds(15); @@ -389,7 +389,7 @@ void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType * Verifies that we can send using credentials. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void sendWithCredentials(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); @@ -412,7 +412,7 @@ void sendWithCredentials(MessagingEntityType entityType) { * Verifies that we can create transaction, scheduleMessage and commit. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void transactionScheduleAndCommitTest(MessagingEntityType entityType) { // Arrange @@ -455,7 +455,7 @@ void transactionScheduleAndCommitTest(MessagingEntityType entityType) { * Verifies that we can create transaction, scheduleMessages and commit. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void transactionScheduleMessagesTest(MessagingEntityType entityType) { // Arrange @@ -511,7 +511,7 @@ void transactionScheduleMessagesTest(MessagingEntityType entityType) { * Verifies that we can schedule messages and cancel them. */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") - // @ParameterizedTest + @ParameterizedTest void cancelScheduledMessagesTest(MessagingEntityType entityType) { // Arrange diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java index 553f87a0d5e4..6ca8c647a87b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java @@ -71,7 +71,7 @@ static Stream receiverTypesProvider() { * Verifies that we can send a message to a non-session queue. */ @MethodSource("receiverTypesProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionQueueSendMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -89,7 +89,7 @@ void nonSessionQueueSendMessage(MessagingEntityType entityType) { * Verifies that we can send a {@link ServiceBusMessageBatch} to a non-session queue. */ @MethodSource("receiverTypesProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionMessageBatch(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -115,7 +115,7 @@ void nonSessionMessageBatch(MessagingEntityType entityType) { * Verifies that we can send a list of messages to a non-session entity. */ @MethodSource("receiverTypesProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionEntitySendMessageList(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -132,7 +132,7 @@ void nonSessionEntitySendMessageList(MessagingEntityType entityType) { * Verifies that we can schedule a message to a non-session entity. */ @MethodSource("receiverTypesProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionScheduleMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); @@ -154,7 +154,7 @@ void nonSessionScheduleMessage(MessagingEntityType entityType) { * Verifies that we can cancel a scheduled a message to a non-session entity. */ @MethodSource("receiverTypesProvider") - // @ParameterizedTest + @ParameterizedTest void nonSessionCancelScheduleMessage(MessagingEntityType entityType) { // Arrange setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index 4c20f51bcc28..262ad0ec9b78 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -58,7 +58,7 @@ protected void afterTest() { } } - // @ParameterizedTest + @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void singleUnnamedSession(MessagingEntityType entityType) { // Arrange @@ -100,7 +100,7 @@ void singleUnnamedSession(MessagingEntityType entityType) { .verify(Duration.ofMinutes(2)); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS1; @@ -117,7 +117,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup rollingSessionTest(); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws InterruptedException { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS3; @@ -153,7 +153,7 @@ private void rollingSessionTest() throws InterruptedException { assertTrue(latch.await(20, TimeUnit.SECONDS)); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityProvider") void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { final int entityIndex = TestUtils.USE_CASE_MULTIPLE_SESSIONS2; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 4e3599fb6fcc..52b38d9912be 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -21,7 +21,6 @@ import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; import com.azure.core.test.utils.MockTokenCredential; -import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -60,6 +59,7 @@ //import java.util.regex.Pattern; import java.util.stream.Stream; +import static com.azure.messaging.servicebus.IntegrationTestBase.PS_CREDENTIAL; import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; @@ -114,7 +114,7 @@ public static Stream createHttpClients() { // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below // * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. // */ -// // @ParameterizedTest +// @ParameterizedTest // @MethodSource("createHttpClients") // void azureIdentityCredentials(HttpClient httpClient) { // @@ -191,7 +191,7 @@ public static Stream createHttpClients() { //region Create tests - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createQueue(HttpClient httpClient) { // Arrange @@ -230,7 +230,7 @@ void createQueue(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createQueueExistingName(HttpClient httpClient) { // Arrange @@ -244,7 +244,7 @@ void createQueueExistingName(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createQueueWithForwarding(HttpClient httpClient) { // Arrange @@ -273,7 +273,7 @@ void createQueueWithForwarding(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createQueueAuthorizationRules(HttpClient httpClient) { // Arrange @@ -323,7 +323,7 @@ void createQueueAuthorizationRules(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createRule(HttpClient httpClient) { // Arrange @@ -356,7 +356,7 @@ void createRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createRuleDefaults(HttpClient httpClient) { // Arrange @@ -377,7 +377,7 @@ void createRuleDefaults(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createRuleResponse(HttpClient httpClient) { // Arrange @@ -417,7 +417,7 @@ void createRuleResponse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createSubscription(HttpClient httpClient) { // Arrange @@ -446,7 +446,7 @@ void createSubscription(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createSubscriptionWithRule(HttpClient httpClient) { // Arrange @@ -472,7 +472,7 @@ void createSubscriptionWithRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createSubscriptionExistingName(HttpClient httpClient) { // Arrange @@ -486,7 +486,7 @@ void createSubscriptionExistingName(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createSubscriptionWithForwarding(HttpClient httpClient) { // Arrange @@ -514,7 +514,7 @@ void createSubscriptionWithForwarding(HttpClient httpClient) { .verify(TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createTopicWithResponse(HttpClient httpClient) { // Arrange @@ -551,7 +551,7 @@ void createTopicWithResponse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void createTopicExistingName(HttpClient httpClient) { // Arrange @@ -573,7 +573,7 @@ void createTopicExistingName(HttpClient httpClient) { //region Delete tests - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteQueue(HttpClient httpClient) { // Arrange @@ -590,7 +590,7 @@ void deleteQueue(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteQueueDoesNotExist(HttpClient httpClient) { // Arrange @@ -603,7 +603,7 @@ void deleteQueueDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteRule(HttpClient httpClient) { // Arrange @@ -620,7 +620,7 @@ void deleteRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteRuleDoesNotExist(HttpClient httpClient) { // Arrange @@ -635,7 +635,7 @@ void deleteRuleDoesNotExist(HttpClient httpClient) { .verify(TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteSubscription(HttpClient httpClient) { // Arrange @@ -652,7 +652,7 @@ void deleteSubscription(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteSubscriptionDoesNotExist(HttpClient httpClient) { // Arrange @@ -669,7 +669,7 @@ void deleteSubscriptionDoesNotExist(HttpClient httpClient) { .verify(TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteTopic(HttpClient httpClient) { // Arrange @@ -684,7 +684,7 @@ void deleteTopic(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void deleteTopicDoesNotExist(HttpClient httpClient) { // Arrange @@ -701,7 +701,7 @@ void deleteTopicDoesNotExist(HttpClient httpClient) { //region Get and exists tests - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getQueue(HttpClient httpClient) { // Arrange @@ -727,7 +727,7 @@ void getQueue(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getNamespace(HttpClient httpClient) { // Arrange @@ -746,7 +746,7 @@ void getNamespace(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getQueueDoesNotExist(HttpClient httpClient) { // Arrange @@ -759,7 +759,7 @@ void getQueueDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getQueueExists(HttpClient httpClient) { // Arrange @@ -773,7 +773,7 @@ void getQueueExists(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getQueueExistsFalse(HttpClient httpClient) { // Arrange @@ -787,7 +787,7 @@ void getQueueExistsFalse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getQueueRuntimeProperties(HttpClient httpClient) { // Arrange @@ -808,7 +808,7 @@ void getQueueRuntimeProperties(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getRule(HttpClient httpClient) { // Arrange @@ -838,7 +838,7 @@ void getRule(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getRuleDoesNotExist(HttpClient httpClient) { // Arrange @@ -854,7 +854,7 @@ void getRuleDoesNotExist(HttpClient httpClient) { .verify(TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getSubscription(HttpClient httpClient) { // Arrange @@ -881,7 +881,7 @@ void getSubscription(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionDoesNotExist(HttpClient httpClient) { // Arrange @@ -895,7 +895,7 @@ void getSubscriptionDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionExists(HttpClient httpClient) { // Arrange @@ -910,7 +910,7 @@ void getSubscriptionExists(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionExistsFalse(HttpClient httpClient) { // Arrange @@ -925,7 +925,7 @@ void getSubscriptionExistsFalse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionRuntimeProperties(HttpClient httpClient) { // Arrange @@ -954,7 +954,7 @@ void getSubscriptionRuntimeProperties(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getTopic(HttpClient httpClient) { // Arrange @@ -982,7 +982,7 @@ void getTopic(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getTopicDoesNotExist(HttpClient httpClient) { // Arrange @@ -1005,7 +1005,7 @@ void getTopicDoesNotExist(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getTopicExists(HttpClient httpClient) { // Arrange @@ -1019,7 +1019,7 @@ void getTopicExists(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getTopicExistsFalse(HttpClient httpClient) { // Arrange @@ -1033,7 +1033,7 @@ void getTopicExistsFalse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getTopicRuntimeProperties(HttpClient httpClient) { // Arrange @@ -1059,7 +1059,7 @@ void getTopicRuntimeProperties(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { // Arrange @@ -1098,7 +1098,7 @@ void getSubscriptionRuntimePropertiesUnauthorizedClient(HttpClient httpClient) { //region List tests - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void listRules(HttpClient httpClient) { // Arrange @@ -1123,7 +1123,7 @@ void listRules(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void listQueues(HttpClient httpClient) { // Arrange @@ -1142,7 +1142,7 @@ void listQueues(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void listSubscriptions(HttpClient httpClient) { // Arrange @@ -1160,7 +1160,7 @@ void listSubscriptions(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void listTopics(HttpClient httpClient) { // Arrange @@ -1180,7 +1180,7 @@ void listTopics(HttpClient httpClient) { //endregion - // @ParameterizedTest + @ParameterizedTest @MethodSource("createHttpClients") void updateRuleResponse(HttpClient httpClient) { // Arrange @@ -1253,7 +1253,8 @@ private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) */ private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { if (interceptorManager.isLiveMode()) { - return new AzurePowerShellCredentialBuilder().build(); + // return new AzurePowerShellCredentialBuilder().build(); + return PS_CREDENTIAL; } else if (interceptorManager.isRecordMode()) { return new DefaultAzureCredentialBuilder().build(); } else { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index e2bf696631c0..c30fe96373f0 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -19,7 +19,6 @@ import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.utils.MockTokenCredential; import com.azure.core.util.Context; -import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -43,7 +42,6 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -59,6 +57,7 @@ //import java.util.regex.Matcher; //import java.util.regex.Pattern; +import static com.azure.messaging.servicebus.IntegrationTestBase.PS_CREDENTIAL; import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; @@ -89,7 +88,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below // * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. // */ -// // @Test +// @Test // void azureIdentityCredentials() { // // Arrange // final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); @@ -130,7 +129,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest // * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below // * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. // */ -// // @Test +// @Test // void azureSasCredentialsTest() { // assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); // final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); @@ -152,7 +151,7 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest //region Create tests - // @Test + @Test void createQueue() { final ServiceBusAdministrationClient client = getClient(); final String queueName = testResourceNamer.randomName("queue", 10); @@ -203,7 +202,7 @@ void createQueue() { assertNotNull(runtimeProperties.getCreatedAt()); } - // @Test + @Test void createQueueWithForwarding() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -230,7 +229,7 @@ void createQueueWithForwarding() { assertNotNull(runtimeProperties.getCreatedAt()); } - // @Test + @Test void createQueueAuthorizationRules() { // Arrange final String keyName = "test-rule"; @@ -278,7 +277,7 @@ void createQueueAuthorizationRules() { assertAuthorizationRules(expected.getAuthorizationRules(), actual.getAuthorizationRules()); } - // @Test + @Test void createTopicWithResponse() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName("test", 10); @@ -305,7 +304,7 @@ void createTopicWithResponse() { assertNotNull(runtimeProperties.getCreatedAt()); } - // @Test + @Test void createTopicExistingName() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -321,7 +320,7 @@ void createTopicExistingName() { () -> client.createTopicWithResponse(topicName, expected, Context.NONE)); } - // @Test + @Test void createSubscription() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -352,7 +351,7 @@ void createSubscription() { } } - // @Test + @Test void createRule() { final ServiceBusAdministrationClient client = getClient(); @@ -376,7 +375,7 @@ void createRule() { assertTrue(actual.getFilter() instanceof FalseRuleFilter); } - // @Test + @Test void createRuleDefaults() { final ServiceBusAdministrationClient client = getClient(); @@ -390,7 +389,7 @@ void createRuleDefaults() { assertTrue(rule.getAction() instanceof EmptyRuleAction); } - // @Test + @Test void createRuleResponse() { final ServiceBusAdministrationClient client = getClient(); @@ -406,7 +405,7 @@ void createRuleResponse() { .setFilter(filter); final Response response = client.createRuleWithResponse(topicName, subscriptionName, - ruleName, options, null); + ruleName, options, null); assertEquals(201, response.getStatusCode()); final RuleProperties contents = response.getValue(); @@ -423,7 +422,7 @@ void createRuleResponse() { assertTrue(contents.getAction() instanceof EmptyRuleAction); } - // @Test + @Test void createQueueExistingName() { final String queueName = getEntityName(getQueueBaseName(), 5); final CreateQueueOptions options = new CreateQueueOptions(); @@ -434,7 +433,7 @@ void createQueueExistingName() { "Queue exists exception not thrown when creating a queue with existing name"); } - // @Test + @Test void createSubscriptionExistingName() { final String topicName = getEntityName(getTopicBaseName(), 2); final String subscriptionName = getSubscriptionBaseName(); @@ -445,7 +444,7 @@ void createSubscriptionExistingName() { "Queue exists exception not thrown when creating a queue with existing name"); } - // @Test + @Test void createSubscriptionWithForwarding() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -472,7 +471,7 @@ void createSubscriptionWithForwarding() { //endregion - // @Test + @Test void updateRuleResponse() { final ServiceBusAdministrationClient client = getClient(); @@ -502,7 +501,7 @@ void updateRuleResponse() { //region Get and exists tests - // @Test + @Test void getNamespace() { final ServiceBusAdministrationClient client = getClient(); @@ -514,7 +513,7 @@ void getNamespace() { } } - // @Test + @Test void getQueue() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); @@ -533,7 +532,7 @@ void getQueue() { assertNotNull(runtimeProperties.getAccessedAt()); } - // @Test + @Test void getQueueDoesNotExist() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); @@ -542,7 +541,7 @@ void getQueueDoesNotExist() { "Queue exists! But should not. Incorrect getQueue behavior"); } - // @Test + @Test void getQueueExists() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); @@ -550,7 +549,7 @@ void getQueueExists() { assertTrue(client.getQueueExists(queueName)); } - // @Test + @Test void getQueueExistsFalse() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 99); @@ -558,7 +557,7 @@ void getQueueExistsFalse() { assertFalse(client.getQueueExists(queueName)); } - // @Test + @Test void getQueueRuntimeProperties() { final ServiceBusAdministrationClient client = getClient(); final String queueName = getEntityName(TestUtils.getQueueBaseName(), 5); @@ -572,7 +571,7 @@ void getQueueRuntimeProperties() { assertNotNull(runtimeProperties.getAccessedAt()); } - // @Test + @Test void getTopic() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -593,7 +592,7 @@ void getTopic() { assertNotNull(runtimeProperties.getAccessedAt()); } - // @Test + @Test void getTopicDoesNotExist() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName("topic", 10); @@ -602,7 +601,7 @@ void getTopicDoesNotExist() { "Topic exists! But should not. Incorrect getTopic behavior"); } - // @Test + @Test void getTopicExists() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -610,7 +609,7 @@ void getTopicExists() { assertTrue(client.getTopicExists(topicName)); } - // @Test + @Test void getTopicExistsFalse() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName(getTopicBaseName(), 10); @@ -618,7 +617,7 @@ void getTopicExistsFalse() { assertFalse(client.getTopicExists(topicName)); } - // @Test + @Test void getTopicRuntimeProperties() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -636,7 +635,7 @@ void getTopicRuntimeProperties() { assertEquals(0, runtimeProperties.getScheduledMessageCount()); } - // @Test + @Test void getSubscription() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -656,7 +655,7 @@ void getSubscription() { assertNotNull(runtimeProperties.getAccessedAt()); } - // @Test + @Test void getSubscriptionDoesNotExist() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -666,7 +665,7 @@ void getSubscriptionDoesNotExist() { "Subscription exists! But should not. Incorrect getSubscription behavior"); } - // @Test + @Test void getSubscriptionExists() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -675,7 +674,7 @@ void getSubscriptionExists() { assertTrue(client.getSubscriptionExists(topicName, subscriptionName)); } - // @Test + @Test void getSubscriptionExistsFalse() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -689,7 +688,7 @@ void getSubscriptionExistsFalse() { assertFalse(response); } - // @Test + @Test void getSubscriptionRuntimeProperties() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -711,7 +710,7 @@ void getSubscriptionRuntimeProperties() { assertNotNull(properties.getAccessedAt()); } - // @Test + @Test void getSubscriptionRuntimePropertiesUnauthorizedClient() { final String connectionString = interceptorManager.isPlaybackMode() ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" @@ -740,7 +739,7 @@ void getSubscriptionRuntimePropertiesUnauthorizedClient() { "Subscription runtime properties accessible by unauthorized client! This should not be possible."); } - // @Test + @Test void getRule() { final ServiceBusAdministrationClient client = getClient(); @@ -762,7 +761,7 @@ void getRule() { assertTrue(contents.getAction() instanceof EmptyRuleAction); } - // @Test + @Test void getRuleDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -780,7 +779,7 @@ void getRuleDoesNotExist() { //region Delete tests - // @Test + @Test void deleteQueue() { final ServiceBusAdministrationClient client = getClient(); final String queueName = testResourceNamer.randomName("queue", 10); @@ -790,7 +789,7 @@ void deleteQueue() { } - // @Test + @Test void deleteQueueDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -800,7 +799,7 @@ void deleteQueueDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> client.deleteQueue(queueName)); } - // @Test + @Test void deleteRule() { final ServiceBusAdministrationClient client = getClient(); final String ruleName = getEntityName(getRuleBaseName(), 9); @@ -811,7 +810,7 @@ void deleteRule() { client.deleteRule(topicName, subscriptionName, ruleName); } - // @Test + @Test void deleteRuleDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -823,7 +822,7 @@ void deleteRuleDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> client.deleteRule(topicName, subscriptionName, ruleName)); } - // @Test + @Test void deleteSubscription() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -834,7 +833,7 @@ void deleteSubscription() { client.deleteSubscription(topicName, subscriptionName); } - // @Test + @Test void deleteSubscriptionDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -848,7 +847,7 @@ void deleteSubscriptionDoesNotExist() { assertThrows(ResourceNotFoundException.class, () -> client.deleteSubscription(topicName, subscriptionName)); } - // @Test + @Test void deleteTopic() { final ServiceBusAdministrationClient client = getClient(); final String topicName = testResourceNamer.randomName("topic", 10); @@ -857,7 +856,7 @@ void deleteTopic() { client.deleteTopic(topicName); } - // @Test + @Test void deleteTopicDoesNotExist() { // Arrange final ServiceBusAdministrationClient client = getClient(); @@ -871,7 +870,7 @@ void deleteTopicDoesNotExist() { //region List tests - // @Test + @Test void listQueues() { final ServiceBusAdministrationClient client = getClient(); @@ -884,7 +883,7 @@ void listQueues() { assertTrue(queueProperties.stream().findAny().isPresent()); } - // @Test + @Test void listTopics() { final ServiceBusAdministrationClient client = getClient(); @@ -897,7 +896,7 @@ void listTopics() { assertTrue(topics.stream().count() > 1); } - // @Test + @Test void listSubscriptions() { final ServiceBusAdministrationClient client = getClient(); final String topicName = getEntityName(getTopicBaseName(), 2); @@ -910,7 +909,7 @@ void listSubscriptions() { assertTrue(subscriptionProperties.stream().findAny().isPresent()); } - // @Test + @Test void listRules() { final ServiceBusAdministrationClient client = getClient(); @@ -972,7 +971,8 @@ private ServiceBusAdministrationClient getClient() { */ private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { if (interceptorManager.isLiveMode()) { - return new AzurePowerShellCredentialBuilder().build(); + // return new AzurePowerShellCredentialBuilder().build(); + return PS_CREDENTIAL; } else if (interceptorManager.isRecordMode()) { return new DefaultAzureCredentialBuilder().build(); } else { From 7cd9fd20979ab3992b47e4bf0b293fcbbf6afe53 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Tue, 2 Jul 2024 16:02:32 -0700 Subject: [PATCH 11/29] Use pipeline cred --- .../servicebus/IntegrationTestBase.java | 81 +++++-------------- .../servicebus/ProxyReceiveTest.java | 21 +---- .../servicebus/ProxySelectorTest.java | 19 +---- .../messaging/servicebus/ProxySendTest.java | 19 +---- ...viceBusProcessorClientIntegrationTest.java | 50 ++++++++++++ .../azure/messaging/servicebus/TestUtils.java | 45 +++++++++++ ...inistrationAsyncClientIntegrationTest.java | 11 +-- ...usAdministrationClientIntegrationTest.java | 9 ++- 8 files changed, 129 insertions(+), 126 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index c79893332dec..9cc9ae31ebaa 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -22,6 +22,7 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; @@ -46,6 +47,7 @@ import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -62,7 +64,6 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; public abstract class IntegrationTestBase extends TestBase { - public static final SBPowerShellCachedCredentials PS_CREDENTIAL = new SBPowerShellCachedCredentials(); public static final boolean USE_CREDENTIALS = true; protected static final Duration OPERATION_TIMEOUT = Duration.ofSeconds(30); protected static final Duration TIMEOUT = Duration.ofSeconds(60); @@ -77,6 +78,7 @@ public abstract class IntegrationTestBase extends TestBase { private List toClose = new ArrayList<>(); private String testName; private final Scheduler scheduler = Schedulers.parallel(); + private final AtomicReference pipelineCredential = new AtomicReference<>(); protected static final byte[] CONTENTS_BYTES = "Some-contents".getBytes(StandardCharsets.UTF_8); protected String sessionId; @@ -210,31 +212,33 @@ public ProxyOptions getProxyConfiguration() { return new ProxyOptions(authenticationType, proxy, username, password); } + protected ServiceBusClientBuilder getAuthenticatedBuilder(boolean useCredentials) { + final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); + logger.info("Getting Builder using credentials : [{}] ", useCredentials); + if (useCredentials) { + final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); + assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), + "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); + final TokenCredential tokenCredential = TestUtils.getPipelineCredential(pipelineCredential); + return builder.credential(fullyQualifiedDomainName, tokenCredential); + } else { + return builder.connectionString(getConnectionString()); + } + } + /** * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings and uses a * connection string to authenticate if {@code useCredentials} is false. Otherwise, uses a service principal through * {@link com.azure.identity.ClientSecretCredential}. */ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder() + return getAuthenticatedBuilder(useCredentials) .proxyOptions(ProxyOptions.SYSTEM_DEFAULTS) .retryOptions(RETRY_OPTIONS) .clientOptions(optionsWithTracing) .transportType(AmqpTransportType.AMQP) .scheduler(scheduler) .configuration(v1OrV2(true)); - - logger.info("Getting Builder using credentials : [{}] ", useCredentials); - if (useCredentials) { - final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - // return builder.credential(fullyQualifiedDomainName, tokenCredential); - return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); - } else { - return builder.connectionString(getConnectionString()); - } } /** @@ -331,54 +335,6 @@ protected ServiceBusSessionReceiverClientBuilder getSessionReceiverBuilder(boole } } - protected ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection) { - - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); - switch (entityType) { - case QUEUE: - final String queueName = getQueueName(entityIndex); - assertNotNull(queueName, "'queueName' cannot be null."); - - return builder.processor().queueName(queueName); - case SUBSCRIPTION: - final String topicName = getTopicName(entityIndex); - final String subscriptionName = getSubscriptionBaseName(); - assertNotNull(topicName, "'topicName' cannot be null."); - assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - - return builder.processor().topicName(topicName).subscriptionName(subscriptionName); - default: - throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); - } - } - - protected ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessionProcessorBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection, AmqpRetryOptions amqpRetryOptions) { - - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); - builder.retryOptions(amqpRetryOptions); - - switch (entityType) { - case QUEUE: - final String queueName = getSessionQueueName(entityIndex); - assertNotNull(queueName, "'queueName' cannot be null."); - return builder - .sessionProcessor() - .queueName(queueName); - - case SUBSCRIPTION: - final String topicName = getTopicName(entityIndex); - final String subscriptionName = getSessionSubscriptionBaseName(); - assertNotNull(topicName, "'topicName' cannot be null."); - assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - return builder.sessionProcessor() - .topicName(topicName).subscriptionName(subscriptionName); - default: - throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); - } - } - protected static Stream messagingEntityProvider() { return Stream.of( Arguments.of(MessagingEntityType.QUEUE), @@ -546,6 +502,7 @@ public static final class SBPowerShellCachedCredentials implements TokenCredenti private final Mono cached; public SBPowerShellCachedCredentials() { + this.builder = new AzurePowerShellCredentialBuilder(); this.context = new TokenRequestContext().addScopes(ServiceBusConstants.AZURE_ACTIVE_DIRECTORY_SCOPE); this.cached = Mono.fromCallable(builder::build) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index e2ebee982717..86fc9de5f543 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -25,8 +25,6 @@ import java.util.List; import java.util.UUID; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - /** * Verify we can use jproxy hosted locally to receive messages. */ @@ -81,7 +79,7 @@ public void receiveMessage() { final String messageTracking = UUID.randomUUID().toString(); final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageTracking); - final ServiceBusSenderAsyncClient sender = getBuilder(USE_CREDENTIALS, logger) + final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder(USE_CREDENTIALS) .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .sender() @@ -90,7 +88,7 @@ public void receiveMessage() { toClose(sender); - final ServiceBusReceiverAsyncClient receiver = getBuilder(USE_CREDENTIALS, logger) + final ServiceBusReceiverAsyncClient receiver = getAuthenticatedBuilder(USE_CREDENTIALS) .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .receiver() @@ -121,19 +119,4 @@ public void receiveMessage() { dispose(sender, receiver); } } - - private static ServiceBusClientBuilder getBuilder(boolean useCredentials, ClientLogger logger) { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - logger.info("Getting Builder using credentials : [{}] ", useCredentials); - if (useCredentials) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - // return builder.credential(fullyQualifiedDomainName, tokenCredential); - return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); - } else { - return builder.connectionString(getConnectionString()); - } - } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java index 9b81e8482ad6..443f7838e8a2 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java @@ -25,8 +25,6 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - public class ProxySelectorTest extends IntegrationTestBase { private static final ClientLogger LOGGER = new ClientLogger(ProxySelectorTest.class); @@ -70,7 +68,7 @@ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { }); final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); - final ServiceBusSenderAsyncClient sender = getBuilder(USE_CREDENTIALS, logger) + final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder(USE_CREDENTIALS) .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) .sender() @@ -89,19 +87,4 @@ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { final boolean awaited = countDownLatch.await(2, TimeUnit.SECONDS); Assertions.assertTrue(awaited); } - - private static ServiceBusClientBuilder getBuilder(boolean useCredentials, ClientLogger logger) { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - logger.info("Getting Builder using credentials : [{}] ", useCredentials); - if (useCredentials) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - // return builder.credential(fullyQualifiedDomainName, tokenCredential); - return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); - } else { - return builder.connectionString(getConnectionString()); - } - } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index 1b3c3452b3ba..d7c90f2028c7 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -25,8 +25,6 @@ import java.util.List; import java.util.UUID; -import static org.junit.jupiter.api.Assumptions.assumeTrue; - public class ProxySendTest extends IntegrationTestBase { private static final int PROXY_PORT = 9101; private static final int NUMBER_OF_EVENTS = 10; @@ -79,7 +77,7 @@ public void sendEvents() { final String messageId = UUID.randomUUID().toString(); final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); - final ServiceBusSenderAsyncClient sender = getBuilder(USE_CREDENTIALS, logger) + final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder(USE_CREDENTIALS) .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) @@ -99,19 +97,4 @@ public void sendEvents() { .expectComplete() .verify(Duration.ofSeconds(30)); } - - private static ServiceBusClientBuilder getBuilder(boolean useCredentials, ClientLogger logger) { - final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - logger.info("Getting Builder using credentials : [{}] ", useCredentials); - if (useCredentials) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - // final TokenCredential tokenCredential = new AzurePowerShellCredentialBuilder().build(); - // return builder.credential(fullyQualifiedDomainName, tokenCredential); - return builder.credential(fullyQualifiedDomainName, PS_CREDENTIAL); - } else { - return builder.connectionString(getConnectionString()); - } - } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index cad23138cf20..e1c7df6d596c 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -22,6 +22,8 @@ import java.util.concurrent.atomic.AtomicReference; import static com.azure.messaging.servicebus.TestUtils.getServiceBusMessage; +import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; +import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -194,6 +196,54 @@ private void processError(ServiceBusErrorContext context, CountDownLatch countdo context.getFullyQualifiedNamespace(), context.getEntityPath()); } + private ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBuilder(boolean useCredentials, + MessagingEntityType entityType, int entityIndex, boolean sharedConnection) { + + ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + switch (entityType) { + case QUEUE: + final String queueName = getQueueName(entityIndex); + assertNotNull(queueName, "'queueName' cannot be null."); + + return builder.processor().queueName(queueName); + case SUBSCRIPTION: + final String topicName = getTopicName(entityIndex); + final String subscriptionName = getSubscriptionBaseName(); + assertNotNull(topicName, "'topicName' cannot be null."); + assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); + + return builder.processor().topicName(topicName).subscriptionName(subscriptionName); + default: + throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); + } + } + + private ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessionProcessorBuilder(boolean useCredentials, + MessagingEntityType entityType, int entityIndex, boolean sharedConnection, AmqpRetryOptions amqpRetryOptions) { + + ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + builder.retryOptions(amqpRetryOptions); + + switch (entityType) { + case QUEUE: + final String queueName = getSessionQueueName(entityIndex); + assertNotNull(queueName, "'queueName' cannot be null."); + return builder + .sessionProcessor() + .queueName(queueName); + + case SUBSCRIPTION: + final String topicName = getTopicName(entityIndex); + final String subscriptionName = getSessionSubscriptionBaseName(); + assertNotNull(topicName, "'topicName' cannot be null."); + assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); + return builder.sessionProcessor() + .topicName(topicName).subscriptionName(subscriptionName); + default: + throw logger.logExceptionAsError(new IllegalArgumentException("Unknown entity type: " + entityType)); + } + } + private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { final boolean shareConnection = false; return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java index 0bb44625ed38..399fb4b63673 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java @@ -10,6 +10,8 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.logging.LogLevel; +import com.azure.identity.AzurePipelinesCredential; +import com.azure.identity.AzurePipelinesCredentialBuilder; import com.azure.messaging.servicebus.administration.models.AccessRights; import com.azure.messaging.servicebus.administration.models.AuthorizationRule; import org.apache.qpid.proton.Proton; @@ -36,6 +38,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -46,6 +49,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class TestUtils { private static final ClientLogger LOGGER = new ClientLogger(TestUtils.class); @@ -222,6 +226,47 @@ public static String getSessionSubscriptionBaseName() { return getPropertyValue("AZURE_SERVICEBUS_SESSION_SUBSCRIPTION_NAME", "subscription-session"); } + /** + * Obtain a {@link com.azure.identity.AzurePowerShellCredentialBuilder} when running in Azure pipelines that is + * configured with service connections federated identity. + * + * @return A {@link com.azure.identity.AzurePowerShellCredentialBuilder} when running in Azure pipelines that is + * configured with service connections federated identity, {@code null} otherwise. + */ + public static AzurePipelinesCredentialBuilder getAzurePipelinesCredentialBuilder() { + final String serviceConnectionId = getPropertyValue("AZURESUBSCRIPTION_SERVICE_CONNECTION_ID"); + final String clientId = getPropertyValue("AZURESUBSCRIPTION_CLIENT_ID"); + final String tenantId = getPropertyValue("AZURESUBSCRIPTION_TENANT_ID"); + final String systemAccessToken = getPropertyValue("SYSTEM_ACCESSTOKEN"); + if (CoreUtils.isNullOrEmpty(serviceConnectionId) || CoreUtils.isNullOrEmpty(clientId) + || CoreUtils.isNullOrEmpty(tenantId) || CoreUtils.isNullOrEmpty(systemAccessToken)) { + return null; + } + return new AzurePipelinesCredentialBuilder().systemAccessToken(systemAccessToken) + .clientId(clientId) + .tenantId(tenantId) + .serviceConnectionId(serviceConnectionId); + } + + /** + * Obtain the Azure Pipelines credential if running in Azure Pipelines configured with service connections federated identity. + * + * @return the Azure Pipelines credential. + */ + public static AzurePipelinesCredential getPipelineCredential(AtomicReference pipelineCredential) { + return pipelineCredential.updateAndGet(credential -> { + if (credential == null) { + final AzurePipelinesCredentialBuilder builder = TestUtils.getAzurePipelinesCredentialBuilder(); + if (builder == null) { + assumeTrue(false, "Test required to run on Azure Pipelines that is configured with service connections federated identity."); + return null; + } + return builder.build(); + } + return credential; + }); + } + /** * Gets the name of an entity based on its base name. * diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 52b38d9912be..6135f71ec7e7 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -21,6 +21,7 @@ import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; import com.azure.core.test.utils.MockTokenCredential; +import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -57,12 +58,11 @@ import java.util.List; //import java.util.regex.Matcher; //import java.util.regex.Pattern; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; -import static com.azure.messaging.servicebus.IntegrationTestBase.PS_CREDENTIAL; import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; -//import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; @@ -104,6 +104,8 @@ class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBa TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); } + private final AtomicReference pipelineCredential = new AtomicReference<>(); + public static Stream createHttpClients() { return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); } @@ -1251,10 +1253,9 @@ private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) * @param interceptorManager the interceptor manager * @return The appropriate token credential */ - private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { + private TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { if (interceptorManager.isLiveMode()) { - // return new AzurePowerShellCredentialBuilder().build(); - return PS_CREDENTIAL; + return TestUtils.getPipelineCredential(pipelineCredential); } else if (interceptorManager.isRecordMode()) { return new DefaultAzureCredentialBuilder().build(); } else { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index c30fe96373f0..260ff8ea2a5f 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -19,6 +19,7 @@ import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.utils.MockTokenCredential; import com.azure.core.util.Context; +import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -54,10 +55,10 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; //import java.util.regex.Matcher; //import java.util.regex.Pattern; -import static com.azure.messaging.servicebus.IntegrationTestBase.PS_CREDENTIAL; import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; @@ -81,6 +82,7 @@ @Execution(ExecutionMode.SAME_THREAD) public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTestBase { private static final Duration TIMEOUT = Duration.ofSeconds(20); + private final AtomicReference pipelineCredential = new AtomicReference<>(); // /** // * Test to connect to the service bus with an azure identity TokenCredential. @@ -969,10 +971,9 @@ private ServiceBusAdministrationClient getClient() { * @param interceptorManager the interceptor manager * @return The appropriate token credential */ - private static TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { + private TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { if (interceptorManager.isLiveMode()) { - // return new AzurePowerShellCredentialBuilder().build(); - return PS_CREDENTIAL; + return TestUtils.getPipelineCredential(pipelineCredential); } else if (interceptorManager.isRecordMode()) { return new DefaultAzureCredentialBuilder().build(); } else { From e7e3824ffa275900ba1607a3497224eeb5c9d76a Mon Sep 17 00:00:00 2001 From: anuchandy Date: Tue, 2 Jul 2024 18:03:03 -0700 Subject: [PATCH 12/29] offload the token reterival to blockable thread --- .../servicebus/IntegrationTestBase.java | 3 +-- .../azure/messaging/servicebus/TestUtils.java | 17 +++++++++++++++-- ...dministrationAsyncClientIntegrationTest.java | 3 +-- ...eBusAdministrationClientIntegrationTest.java | 3 +-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 9cc9ae31ebaa..7268751b438d 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -22,7 +22,6 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; @@ -78,7 +77,7 @@ public abstract class IntegrationTestBase extends TestBase { private List toClose = new ArrayList<>(); private String testName; private final Scheduler scheduler = Schedulers.parallel(); - private final AtomicReference pipelineCredential = new AtomicReference<>(); + private final AtomicReference pipelineCredential = new AtomicReference<>(); protected static final byte[] CONTENTS_BYTES = "Some-contents".getBytes(StandardCharsets.UTF_8); protected String sessionId; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java index 399fb4b63673..e9bcdf552e8d 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java @@ -5,6 +5,9 @@ import com.azure.core.amqp.exception.AmqpResponseCode; import com.azure.core.amqp.implementation.ConnectionStringProperties; +import com.azure.core.credential.AccessToken; +import com.azure.core.credential.TokenCredential; +import com.azure.core.credential.TokenRequestContext; import com.azure.core.util.BinaryData; import com.azure.core.util.Configuration; import com.azure.core.util.CoreUtils; @@ -21,6 +24,8 @@ import org.apache.qpid.proton.amqp.messaging.Data; import org.apache.qpid.proton.amqp.messaging.MessageAnnotations; import org.apache.qpid.proton.message.Message; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -253,7 +258,7 @@ public static AzurePipelinesCredentialBuilder getAzurePipelinesCredentialBuilder * * @return the Azure Pipelines credential. */ - public static AzurePipelinesCredential getPipelineCredential(AtomicReference pipelineCredential) { + public static TokenCredential getPipelineCredential(AtomicReference pipelineCredential) { return pipelineCredential.updateAndGet(credential -> { if (credential == null) { final AzurePipelinesCredentialBuilder builder = TestUtils.getAzurePipelinesCredentialBuilder(); @@ -261,7 +266,15 @@ public static AzurePipelinesCredential getPipelineCredential(AtomicReference getToken(TokenRequestContext request) { + return Mono.defer(() -> { + return pipelinesCredential.getToken(request); + }).subscribeOn(Schedulers.boundedElastic()); + } + }; } return credential; }); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 6135f71ec7e7..5d1d92bc80c5 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -21,7 +21,6 @@ import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; import com.azure.core.test.utils.MockTokenCredential; -import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -104,7 +103,7 @@ class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBa TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); } - private final AtomicReference pipelineCredential = new AtomicReference<>(); + private final AtomicReference pipelineCredential = new AtomicReference<>(); public static Stream createHttpClients() { return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 260ff8ea2a5f..5ac22f176473 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -19,7 +19,6 @@ import com.azure.core.test.TestProxyTestBase; import com.azure.core.test.utils.MockTokenCredential; import com.azure.core.util.Context; -import com.azure.identity.AzurePipelinesCredential; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -82,7 +81,7 @@ @Execution(ExecutionMode.SAME_THREAD) public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTestBase { private static final Duration TIMEOUT = Duration.ofSeconds(20); - private final AtomicReference pipelineCredential = new AtomicReference<>(); + private final AtomicReference pipelineCredential = new AtomicReference<>(); // /** // * Test to connect to the service bus with an azure identity TokenCredential. From 60aebe3b44eb4244397bc9d41c21986a18807f36 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Tue, 2 Jul 2024 18:44:20 -0700 Subject: [PATCH 13/29] test with Premium --- sdk/servicebus/test-resources.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index c3a442dbada6..717792dfa590 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -69,7 +69,7 @@ "name": "[variables('namespaceName')]", "location": "[parameters('location')]", "sku": { - "name": "Standard" + "name": "Premium" }, "properties": {}, "resources": [ From 274478faf2dee99b982590ae06a75eb8f4f18ea1 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Wed, 3 Jul 2024 09:37:43 -0700 Subject: [PATCH 14/29] enable tracing integration tests --- .../servicebus/TracingIntegrationTests.java | 1973 ++++++++--------- 1 file changed, 985 insertions(+), 988 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java index f86e6b8c8971..2b6b83081fb9 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java @@ -3,993 +3,990 @@ package com.azure.messaging.servicebus; -public class TracingIntegrationTests { +import com.azure.core.tracing.opentelemetry.OpenTelemetryTracingOptions; +import com.azure.core.util.ClientOptions; +import com.azure.core.util.IterableStream; +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.implementation.instrumentation.ServiceBusTracer; +import com.azure.messaging.servicebus.models.DeferOptions; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.trace.IdGenerator; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.data.LinkData; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import reactor.core.Disposable; +import reactor.core.scheduler.Schedulers; +import reactor.test.StepVerifier; +import java.time.Duration; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +@Execution(ExecutionMode.SAME_THREAD) +public class TracingIntegrationTests extends IntegrationTestBase { + private ClientOptions clientOptions; + private TestSpanProcessor spanProcessor; + private ServiceBusSenderAsyncClient sender; + private ServiceBusReceiverAsyncClient receiver; + private ServiceBusReceiverClient receiverSync; + private ServiceBusProcessorClient processor; + + public TracingIntegrationTests() { + super(new ClientLogger(TracingIntegrationTests.class)); + } + + @Override + protected void beforeTest() { + spanProcessor = new TestSpanProcessor(getFullyQualifiedDomainName(), getQueueName(0)); + OpenTelemetryTracingOptions tracingOptions = new OpenTelemetryTracingOptions() + .setOpenTelemetry(OpenTelemetrySdk.builder() + .setTracerProvider( + SdkTracerProvider.builder() + .addSpanProcessor(spanProcessor) + .build()) + .build()); + clientOptions = new ClientOptions().setTracingOptions(tracingOptions); + + final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + sender = toClose(senderBuilder + .clientOptions(clientOptions) + .sender() + .queueName(getQueueName(0)) + .buildAsyncClient()); + + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + receiver = toClose(receiverBuilder + .clientOptions(clientOptions) + .receiver() + .maxAutoLockRenewDuration(Duration.ZERO) + .queueName(getQueueName(0)) + .disableAutoComplete() + .buildAsyncClient()); + + final ServiceBusClientBuilder receiverSyncBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + receiverSync = toClose(receiverSyncBuilder + .clientOptions(clientOptions) + .receiver() + .queueName(getQueueName(0)) + .buildClient()); + } + + @Override + protected void afterTest() { + GlobalOpenTelemetry.resetForTest(); + sharedBuilder = null; + } + + @Test + public void sendAndReceive() throws InterruptedException { + ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); + ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); + List messages = Arrays.asList(message1, message2); + StepVerifier.create(sender.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(2); + spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); + + List received = new ArrayList<>(); + Disposable subscription = receiver.receiveMessages() + .take(2) + .doOnNext(msg -> { + received.add(msg); + String traceparent = (String) msg.getApplicationProperties().get("traceparent"); + String traceId = Span.current().getSpanContext().getTraceId(); + + // context created for the message and current are the same + assertTrue(traceparent.startsWith("00-" + traceId)); + assertFalse(((ReadableSpan) Span.current()).hasEnded()); + receiver.complete(msg).block(); + }) + .subscribe(); + toClose(subscription); + assertTrue(processedFound.await(20, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + + List messageSpans = findSpans(spans, "ServiceBus.message"); + assertMessageSpan(messageSpans.get(0), message1); + assertMessageSpan(messageSpans.get(1), message2); + + List send = findSpans(spans, "ServiceBus.send"); + assertClientProducerSpan(send.get(0), messages, "ServiceBus.send", "publish"); + + List processed = findSpans(spans, "ServiceBus.process"); + assertConsumerSpan(processed.get(0), received.get(0), "ServiceBus.process"); + assertConsumerSpan(processed.get(1), received.get(1), "ServiceBus.process"); + + List completed = findSpans(spans, "ServiceBus.complete"); + assertClientSpan(completed.get(0), Collections.singletonList(received.get(0)), "ServiceBus.complete", "settle"); + assertClientSpan(completed.get(1), Collections.singletonList(received.get(1)), "ServiceBus.complete", "settle"); + assertSettledVsProcessed(completed, processed, messages.size()); + } + + @Test + public void receiveAndRenewLockWithDuration() throws InterruptedException { + ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); + StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(2); + spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewMessageLock")); + + AtomicReference received = new AtomicReference<>(); + StepVerifier.create(receiver.receiveMessages() + .next() + .flatMap(msg -> receiver.renewMessageLock(msg, Duration.ofSeconds(2)) + .thenReturn(msg))) + .assertNext(msg -> received.compareAndSet(null, msg)) + .expectComplete() + .verify(TIMEOUT); + assertTrue(processedFound.await(30, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + + List processed = findSpans(spans, "ServiceBus.process"); + assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); + + List renewLock = findSpans(spans, "ServiceBus.renewMessageLock"); + assertClientSpan(renewLock.get(0), Collections.singletonList(received.get()), "ServiceBus.renewMessageLock", null); + } + + @Test + public void receiveAndRenewSessionLockWithDuration() throws InterruptedException { + String sessionId = "10"; + ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) + .setSessionId(sessionId); + + OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), getSessionQueueName(0)); + final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + sender = toClose(senderBuilder + .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) + .sender() + .queueName(getSessionQueueName(0)) + .buildAsyncClient()); + + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(receiverBuilder + .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) + .sessionReceiver() + .disableAutoComplete() + .queueName(getSessionQueueName(0)) + .buildAsyncClient()); + + StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(2); + spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewSessionLock")); + + AtomicReference received = new AtomicReference<>(); + StepVerifier.create( + sessionReceiver + .acceptSession(sessionId) + .flatMapMany(rec -> rec + .renewSessionLock() + .then(rec.receiveMessages().next()))) + .assertNext(msg -> { + received.set(msg); + logger.atInfo() + .addKeyValue("lockedUntil", msg.getLockedUntil()) + .addKeyValue("sessionId", msg.getSessionId()) + .log("message received"); + }) + .expectComplete() + .verify(TIMEOUT); + + assertTrue(processedFound.await(30, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + + List processed = findSpans(spans, "ServiceBus.process"); + assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); + + List acceptSession = findSpans(spans, "ServiceBus.acceptSession"); + assertClientSpan(acceptSession.get(0), Collections.emptyList(), "ServiceBus.acceptSession", null); + + List renewLock = findSpans(spans, "ServiceBus.renewSessionLock"); + assertClientSpan(renewLock.get(0), Collections.emptyList(), "ServiceBus.renewSessionLock", null); + } + + @Test + public void receiveCheckSubscribe() throws InterruptedException { + ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); + ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); + List messages = Arrays.asList(message1, message2); + StepVerifier.create(sender.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(2); + spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); + + Disposable subscription = receiver.receiveMessages() + .take(messages.size()) + .subscribe(msg -> { + String traceparent = (String) msg.getApplicationProperties().get("traceparent"); + String traceId = Span.current().getSpanContext().getTraceId(); + + // context created for the message and current are the same + assertTrue(traceparent.startsWith("00-" + traceId)); + assertFalse(((ReadableSpan) Span.current()).hasEnded()); + receiver.complete(msg).block(); + }); + toClose(subscription); + assertTrue(processedFound.await(20, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messages.size()); + } + + @Test + public void sendAndReceiveParallelNoAutoCompleteAndLockRenewal() throws InterruptedException { + int messageCount = 5; + StepVerifier.create(sender.createMessageBatch() + .doOnNext(batch -> { + for (int i = 0; i < messageCount; i++) { + batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); + } + }) + .flatMap(batch -> sender.sendMessages(batch))) + .expectComplete() + .verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(messageCount); + spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); + + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(receiverBuilder + .clientOptions(clientOptions) + .receiver() + .queueName(getQueueName(0)) + .disableAutoComplete() + .buildAsyncClient()); + + StepVerifier.create( + receiverWithLockRenewal.receiveMessages() + .take(messageCount) + .doOnNext(msg -> { + if (Span.current().getSpanContext().isValid()) { + String traceparent = (String) msg.getApplicationProperties().get("traceparent"); + String traceId = Span.current().getSpanContext().getTraceId(); + + // context created for the message and current are the same + assertTrue(traceparent.startsWith("00-" + traceId)); + assertFalse(((ReadableSpan) Span.current()).hasEnded()); + } + receiver.complete(msg).block(); + }) + .parallel(messageCount, 1) + .runOn(Schedulers.boundedElastic(), 1)) + .expectNextCount(messageCount) + .expectComplete() + .verify(TIMEOUT); + + assertTrue(processedFound.await(20, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + + // all completed spans should have a parent, but complete call may start after the parent span has ended + // the last part heavily depends on how above code is written wrt parallelization. + // in the current form (receive -> doonnext (complete) -> parallel) + // complete is happens synchronously from the receive perspective + // so complete will finish before processing is completed. + // + // if complete call is done differently (e.g. receive -> parallel -> runon -> doonnext (complete)) + // then doonnext callbacks become async and may happen after receiver call has completed + // then complete will be a child of process, but will last longer than processing + // TODO (limolkova): this is another good reason to rename receiver's span to delivery instead of processing. + assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); + } + + @Test + public void sendAndReceiveParallelAutoComplete() throws InterruptedException { + int messageCount = 5; + StepVerifier.create(sender.createMessageBatch() + .doOnNext(batch -> { + for (int i = 0; i < messageCount; i++) { + batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); + } + }) + .flatMap(batch -> sender.sendMessages(batch))) + .expectComplete() + .verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(messageCount); + spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); + + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(receiverBuilder + .clientOptions(clientOptions) + .receiver() + .queueName(getQueueName(0)) + .buildAsyncClient()); + + StepVerifier.create( + receiverAutoComplete.receiveMessages() + .take(messageCount) + .doOnNext(msg -> { + if (Span.current().getSpanContext().isValid()) { + String traceparent = (String) msg.getApplicationProperties().get("traceparent"); + String traceId = Span.current().getSpanContext().getTraceId(); + + // context created for the message and current are the same + assertTrue(traceparent.startsWith("00-" + traceId)); + assertFalse(((ReadableSpan) Span.current()).hasEnded()); + } + }) + .parallel(messageCount, 1) + .runOn(Schedulers.boundedElastic(), 1)) + .expectNextCount(messageCount) + .expectComplete() + .verify(TIMEOUT); + assertTrue(processedFound.await(20, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); + } + + @Test + public void sendReceiveRenewLockAndDefer() throws InterruptedException { + String traceId = IdGenerator.random().generateTraceId(); + String traceparent = "00-" + traceId + "-" + IdGenerator.random().generateSpanId() + "-01"; + ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); + AtomicReference receivedMessage = new AtomicReference<>(); + message.getApplicationProperties().put("traceparent", traceparent); + + StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); + + CountDownLatch latch = new CountDownLatch(1); + spanProcessor.notifyIfCondition(latch, s -> s.getName().equals("ServiceBus.receiveDeferredMessage")); + toClose(receiver.receiveMessages() + .filter(m -> traceparent.equals(m.getApplicationProperties().get("traceparent"))) + .flatMap(m -> receiver.renewMessageLock(m).thenReturn(m)) + .flatMap(m -> receiver.defer(m, new DeferOptions()).thenReturn(m)) + .flatMap(m -> receiver.receiveDeferredMessage(m.getSequenceNumber()).thenReturn(m)) + .subscribe(m -> { + receivedMessage.compareAndSet(null, m); + })); + assertTrue(latch.await(120, TimeUnit.SECONDS)); + + List spans = spanProcessor.getEndedSpans(); + + assertEquals(0, findSpans(spans, "ServiceBus.message").size()); + + List send = findSpans(spans, "ServiceBus.send"); + assertClientProducerSpan(send.get(0), Collections.singletonList(message), "ServiceBus.send", "publish"); + + List process = findSpans(spans, "ServiceBus.process", traceId); + assertConsumerSpan(process.get(0), receivedMessage.get(), "ServiceBus.process"); + + List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock", traceId); + assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.renewMessageLock", null); + assertParent(renewMessageLock.get(0), process.get(0)); + + // for correlation to work after first async call, we need to enable otel rector instrumentations, + // so no correlation beyond this point + List defer = findSpans(spans, "ServiceBus.defer"); + assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.defer", "settle"); + + List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); + assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.receiveDeferredMessage", "receive"); + } + + @Test + public void sendReceiveRenewLockAndDeferSync() { + StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) + .expectComplete() + .verify(TIMEOUT); + + ServiceBusReceivedMessage receivedMessage = null; + while (receivedMessage == null) { + IterableStream messages = receiverSync.receiveMessages(1, Duration.ofSeconds(10)); + if (messages.iterator().hasNext()) { + receivedMessage = messages.iterator().next(); + } + } + + receiverSync.renewMessageLock(receivedMessage); + receiverSync.defer(receivedMessage, new DeferOptions()); + receiverSync.receiveDeferredMessage(receivedMessage.getSequenceNumber()); + + List spans = spanProcessor.getEndedSpans(); + + List received = findSpans(spans, "ServiceBus.receiveMessages"); + assertClientSpan(received.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveMessages", "receive"); + + List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock"); + assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage), "ServiceBus.renewMessageLock", null); + + List defer = findSpans(spans, "ServiceBus.defer"); + assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage), "ServiceBus.defer", "settle"); + + List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); + assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveDeferredMessage", "receive"); + } + + @Test + public void syncReceive() { + List messages = new ArrayList<>(); + messages.add(new ServiceBusMessage(CONTENTS_BYTES)); + messages.add(new ServiceBusMessage(CONTENTS_BYTES)); + + StepVerifier.create(sender.sendMessages(messages)) + .expectComplete() + .verify(TIMEOUT); + + List receivedMessages = receiverSync.receiveMessages(2, Duration.ofSeconds(10)) + .stream().collect(Collectors.toList()); + receivedMessages.forEach(receiverSync::complete); + + List spans = spanProcessor.getEndedSpans(); + + List received = findSpans(spans, "ServiceBus.receiveMessages"); + assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); + + assertEquals(0, findSpans(spans, "ServiceBus.process").size()); + + List completed = findSpans(spans, "ServiceBus.complete"); + assertClientSpan(completed.get(0), Collections.singletonList(receivedMessages.get(0)), "ServiceBus.complete", "settle"); + assertClientSpan(completed.get(1), Collections.singletonList(receivedMessages.get(1)), "ServiceBus.complete", "settle"); + } + + @Test + public void syncReceiveTimeout() { + List receivedMessages = receiverSync.receiveMessages(100, Duration.ofMillis(1)) + .stream().collect(Collectors.toList()); + + List spans = spanProcessor.getEndedSpans(); + + List received = findSpans(spans, "ServiceBus.receiveMessages"); + assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); + assertEquals(StatusCode.UNSET, received.get(0).toSpanData().getStatus().getStatusCode()); + + assertEquals(0, findSpans(spans, "ServiceBus.process").size()); + } + + @Test + public void peekMessage() { + StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) + .expectComplete() + .verify(TIMEOUT); + + StepVerifier.create(receiver.peekMessage()) + .assertNext(receivedMessage -> { + ReadableSpan received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage").get(0); + if (receivedMessage.getApplicationProperties().containsKey("traceparent")) { + logger.atInfo() + .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) + .log("span should have link"); + assertClientSpan(received, Collections.singletonList(receivedMessage), "ServiceBus.peekMessage", "receive"); + } else { + assertEquals("ServiceBus.peekMessage", received.getName()); + assertEquals(SpanKind.CLIENT, received.getKind()); + assertEquals(0, received.toSpanData().getLinks().size()); + assertEquals("receive", received.getAttribute(AttributeKey.stringKey("messaging.operation"))); + } + }) + .expectComplete() + .verify(TIMEOUT); + } + + @Test + public void peekNonExistingMessage() { + StepVerifier.create(receiver.peekMessage(Long.MAX_VALUE - 1)) + .expectComplete() + .verify(TIMEOUT); + + List received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage"); + assertClientSpan(received.get(0), Collections.emptyList(), "ServiceBus.peekMessage", "receive"); + } + + @Test + public void sendAndProcessNoAutoComplete() throws InterruptedException { + String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) + .setMessageId(messageId); + + StepVerifier.create(sender.sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + + String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); + CountDownLatch processFound = new CountDownLatch(1); + spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") && span.getParentSpanContext().getSpanId().equals(message1SpanId)); + + AtomicReference currentInProcess = new AtomicReference<>(); + AtomicReference receivedMessage = new AtomicReference<>(); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + processor = toClose(processorBuilder + .clientOptions(clientOptions) + .processor() + .queueName(getQueueName(0)) + .processMessage(mc -> { + if (mc.getMessage().getMessageId().equals(messageId)) { + currentInProcess.compareAndSet(null, Span.current()); + receivedMessage.compareAndSet(null, mc.getMessage()); + } + mc.complete(); + }) + .processError(e -> fail("unexpected error", e.getException())) + .buildProcessorClient()); + + toClose((AutoCloseable) () -> processor.stop()); + processor.start(); + assertTrue(processFound.await(20, TimeUnit.SECONDS)); + processor.stop(); + + assertTrue(currentInProcess.get().getSpanContext().isValid()); + List spans = spanProcessor.getEndedSpans(); + + assertMessageSpan(spans.get(0), message); + assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.send", "publish"); + + assertEquals(0, findSpans(spans, "ServiceBus.consume").size()); + List processed = findSpans(spans, "ServiceBus.process") + .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); + assertEquals(1, processed.size()); + assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); + + List completed = findSpans(spans, "ServiceBus.complete").stream() + .filter(c -> { + List links = c.toSpanData().getLinks(); + return !links.isEmpty() && links.get(0).getSpanContext().getSpanId().equals(message1SpanId); + }) + .collect(Collectors.toList()); + assertEquals(1, completed.size()); + assertClientProducerSpan(completed.get(0), Collections.singletonList(message), "ServiceBus.complete", "settle"); + + assertSettledVsProcessed(completed, processed, 1); + } + + @Test + public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { + String sessionQueueName = getSessionQueueName(0); + String sessionId = UUID.randomUUID().toString(); + ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES).setSessionId(sessionId); + + OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), sessionQueueName); + clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); + final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + sender = toClose(senderBuilder + .clientOptions(clientOptions) + .sender() + .queueName(sessionQueueName) + .buildAsyncClient()); + + StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); + + CountDownLatch processFound = new CountDownLatch(2); + spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); + + AtomicReference currentInProcess = new AtomicReference<>(); + AtomicReference receivedMessage = new AtomicReference<>(); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + processor = toClose(processorBuilder + .clientOptions(clientOptions) + .sessionProcessor() + .maxConcurrentSessions(1) + .queueName(sessionQueueName) + .disableAutoComplete() + .processMessage(mc -> { + currentInProcess.compareAndSet(null, Span.current()); + receivedMessage.compareAndSet(null, mc.getMessage()); + mc.complete(); + }) + .processError(e -> fail("unexpected error", e.getException())) + .buildProcessorClient()); + + toClose((AutoCloseable) () -> processor.stop()); + processor.start(); + assertTrue(processFound.await(20, TimeUnit.SECONDS)); + processor.stop(); + + assertTrue(currentInProcess.get().getSpanContext().isValid()); + List spans = spanProcessor.getEndedSpans(); + + List processed = findSpans(spans, "ServiceBus.process") + .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); + assertEquals(1, processed.size()); + assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); + + List completed = findSpans(spans, "ServiceBus.complete"); + assertEquals(1, completed.size()); + assertClientSpan(completed.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.complete", "settle"); + assertSettledVsProcessed(completed, processed, 1); + } + + @Test + public void sendAndProcessParallel() throws InterruptedException { + int messageCount = 10; + StepVerifier.create(sender.createMessageBatch() + .doOnNext(batch -> { + for (int i = 0; i < messageCount; i++) { + batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES) + .setMessageId(UUID.randomUUID().toString())); + } + }) + .flatMap(batch -> { + logMessages(batch.getMessages(), sender.getEntityPath(), "sending"); + return sender.sendMessages(batch); + })) + .expectComplete() + .verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(messageCount * 2); + spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); + + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + processor = toClose(processorBuilder + .clientOptions(clientOptions) + .processor() + .queueName(getQueueName(0)) + .maxConcurrentCalls(messageCount) + .processMessage(mc -> { + logMessage(mc.getMessage(), processor.getQueueName(), "processing"); + String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); + String traceId = Span.current().getSpanContext().getTraceId(); + + // context created for the message and current are the same + assertTrue(traceparent.startsWith("00-" + traceId)); + assertFalse(((ReadableSpan) Span.current()).hasEnded()); + }) + .processError(e -> fail("unexpected error", e.getException())) + .buildProcessorClient()); + toClose((AutoCloseable) () -> processor.stop()); + processor.start(); + assertTrue(processedFound.await(30, TimeUnit.SECONDS)); + processor.stop(); + + List spans = spanProcessor.getEndedSpans(); + assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); + } + + @Test + public void sendAndProcessParallelNoAutoComplete() throws InterruptedException { + int messageCount = 5; + StepVerifier.create(sender.createMessageBatch() + .doOnNext(batch -> { + for (int i = 0; i < messageCount; i++) { + batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); + } + }) + .flatMap(batch -> sender.sendMessages(batch))) + .expectComplete() + .verify(TIMEOUT); + + CountDownLatch processedFound = new CountDownLatch(messageCount); + spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); + + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + processor = toClose(processorBuilder + .clientOptions(clientOptions) + .processor() + .queueName(getQueueName(0)) + .maxConcurrentCalls(messageCount) + .disableAutoComplete() + .processMessage(mc -> { + String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); + String traceId = Span.current().getSpanContext().getTraceId(); + + // context created for the message and current are the same + assertTrue(traceparent.startsWith("00-" + traceId)); + mc.complete(); + }) + .processError(e -> fail("unexpected error", e.getException())) + .buildProcessorClient()); + toClose((AutoCloseable) () -> processor.stop()); + processor.start(); + assertTrue(processedFound.await(20, TimeUnit.SECONDS)); + processor.stop(); + + List spans = spanProcessor.getEndedSpans(); + assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); + } + + @Test + public void sendProcessAndFail() throws InterruptedException { + String messageId = UUID.randomUUID().toString(); + ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) + .setMessageId(messageId); + + StepVerifier.create(sender.sendMessage(message)) + .expectComplete() + .verify(TIMEOUT); + + String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); + + CountDownLatch messageProcessed = new CountDownLatch(1); + spanProcessor.notifyIfCondition(messageProcessed, span -> + "ServiceBus.process".equals(span.getName()) && span.getParentSpanContext().getSpanId().equals(message1SpanId)); + + AtomicReference receivedMessage = new AtomicReference<>(); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + processor = toClose(processorBuilder + .clientOptions(clientOptions) + .processor() + .queueName(getQueueName(0)) + .processMessage(mc -> { + if (mc.getMessage().getMessageId().equals(messageId)) { + receivedMessage.compareAndSet(null, mc.getMessage()); + throw new RuntimeException("foo"); + } + }) + .processError(e -> { }) + .buildProcessorClient()); + toClose((AutoCloseable) () -> processor.stop()); + processor.start(); + assertTrue(messageProcessed.await(30, TimeUnit.SECONDS)); + processor.stop(); + + List spans = spanProcessor.getEndedSpans(); + List processed = findSpans(spans, "ServiceBus.process") + .stream().filter(p -> p.getParentSpanContext().isValid()) + .filter(p -> p.toSpanData().getStatus().getStatusCode() == StatusCode.ERROR) + .collect(Collectors.toList()); + assertEquals(1, processed.size()); + assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); + + List abandoned = findSpans(spans, "ServiceBus.abandon").stream() + .filter(c -> c.toSpanData().getLinks().get(0).getSpanContext().getSpanId().equals(message1SpanId)) + .collect(Collectors.toList()); + assertEquals(1, abandoned.size()); + assertClientProducerSpan(abandoned.get(0), Collections.singletonList(message), "ServiceBus.abandon", "settle"); + assertSettledVsProcessed(abandoned, processed, 1); + } + + @Test + public void scheduleAndCancelMessage() { + ServiceBusMessage message = new ServiceBusMessage("m"); + StepVerifier.create( + sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(100)) + .flatMap(l -> sender.cancelScheduledMessage(l))) + .expectComplete() + .verify(TIMEOUT); + + List spans = spanProcessor.getEndedSpans(); + assertMessageSpan(spans.get(0), message); + assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.scheduleMessage", "publish"); + assertClientProducerSpan(spans.get(2), Collections.emptyList(), "ServiceBus.cancelScheduledMessage", null); + } + + private void assertMessageSpan(ReadableSpan actual, ServiceBusMessage message) { + assertEquals("ServiceBus.message", actual.getName()); + assertEquals(SpanKind.PRODUCER, actual.getKind()); + assertNull(actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); + String traceparent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getSpanContext().getSpanId() + "-01"; + assertEquals(message.getApplicationProperties().get("Diagnostic-Id"), traceparent); + assertEquals(message.getApplicationProperties().get("traceparent"), traceparent); + } + + private void assertClientProducerSpan(ReadableSpan actual, List messages, String spanName, String operationName) { + assertEquals(spanName, actual.getName()); + assertEquals(SpanKind.CLIENT, actual.getKind()); + List links = actual.toSpanData().getLinks(); + assertEquals(messages.size(), links.size()); + assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); + if (messages.size() > 1) { + assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); + } + + for (int i = 0; i < links.size(); i++) { + String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); + SpanContext linkContext = links.get(i).getSpanContext(); + String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; + assertEquals(messageTraceparent, linkTraceparent); + } + } + + private void assertClientSpan(ReadableSpan actual, List messages, String spanName, String operationName) { + assertEquals(spanName, actual.getName()); + assertEquals(SpanKind.CLIENT, actual.getKind()); + List links = actual.toSpanData().getLinks(); + assertEquals(messages.size(), links.size()); + assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); + if (messages.size() > 1) { + assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); + } + for (int i = 0; i < links.size(); i++) { + String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); + SpanContext linkContext = links.get(i).getSpanContext(); + String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; + assertEquals(messageTraceparent, linkTraceparent); + assertNotNull(links.get(i).getAttributes().get(AttributeKey.longKey(ServiceBusTracer.MESSAGE_ENQUEUED_TIME_ATTRIBUTE_NAME))); + } + } + + private void assertConsumerSpan(ReadableSpan actual, ServiceBusReceivedMessage message, String spanName) { + assertEquals(spanName, actual.getName()); + assertEquals(SpanKind.CONSUMER, actual.getKind()); + assertEquals(0, actual.toSpanData().getLinks().size()); + assertEquals("process", actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); + String messageTraceparent = (String) message.getApplicationProperties().get("traceparent"); + String parent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getParentSpanContext().getSpanId() + "-01"; + assertEquals(messageTraceparent, parent); + } + + private void assertParent(ReadableSpan child, ReadableSpan parent) { + assertEquals(child.getParentSpanContext().getTraceId(), parent.getSpanContext().getTraceId()); + assertEquals(child.getParentSpanContext().getSpanId(), parent.getSpanContext().getSpanId()); + } + + private void assertSettledVsProcessed(List settled, List processed, int expectedCount) { + assertTrue(settled.size() >= expectedCount, + String.format("Expected at least %d completed spans, but found %d", expectedCount, settled.size())); + assertTrue(processed.size() >= expectedCount, + String.format("Expected at least %d processed spans, but found %d", expectedCount, processed.size())); + + // there could be more completed spans than processed because completion happens before processing, and we can have more messages in the queue than we expected. + assertTrue(settled.size() >= processed.size(), + String.format("Expected at least as many completed spans as processed spans, but found %d completed and %d processed", settled.size(), processed.size())); + + int processedFound = 0; + for (ReadableSpan readableSpan : settled) { + ReadableSpan parent = findParent(readableSpan, processed); + if (parent != null) { + processedFound++; + assertTrue(readableSpan.getLatencyNanos() <= parent.getLatencyNanos(), () -> + String.format("Expected settled span to have less latency than processed span, but found %d vs %d", + readableSpan.getLatencyNanos(), parent.getLatencyNanos())); + } + } + + assertEquals(expectedCount, processedFound); + } + + private ReadableSpan findParent(ReadableSpan child, List possibleParents) { + String traceId = child.getParentSpanContext().getTraceId(); + String parentId = child.getParentSpanContext().getSpanId(); + for (ReadableSpan p : possibleParents) { + if (traceId.equals(p.getSpanContext().getTraceId()) + && parentId.equals(p.getSpanContext().getSpanId())) { + return p; + } + } + + return null; + } + + private List findSpans(List spans, String spanName) { + return spans.stream() + .filter(s -> s.getName().equals(spanName)) + .collect(Collectors.toList()); + } + + private List findSpans(List spans, String spanName, String traceId) { + return spans.stream() + .filter(s -> s.getName().equals(spanName)) + .filter(s -> s.getSpanContext().getTraceId().equals(traceId)) + .collect(Collectors.toList()); + } + + private OpenTelemetry configureOTel(String namespace, String entityName) { + GlobalOpenTelemetry.resetForTest(); + spanProcessor = new TestSpanProcessor(namespace, entityName); + return OpenTelemetrySdk.builder().setTracerProvider( + SdkTracerProvider.builder() + .addSpanProcessor(spanProcessor) + .build()).build(); + } + + static class TestSpanProcessor implements SpanProcessor { + private static final ClientLogger LOGGER = new ClientLogger(TestSpanProcessor.class); + private static final AttributeKey AZ_NAMESPACE = AttributeKey.stringKey("az.namespace"); + private static final AttributeKey MESSAGING_SYSTEM = AttributeKey.stringKey("messaging.system"); + private static final AttributeKey MESSAGING_DESTINATION_NAME + = AttributeKey.stringKey("messaging.destination.name"); + private static final AttributeKey NET_PEER_NAME = AttributeKey.stringKey("net.peer.name"); + private static final AttributeKey SERVER_ADDRESS = AttributeKey.stringKey("server.address"); + + private final ConcurrentLinkedDeque spans = new ConcurrentLinkedDeque<>(); + private final String entityName; + private final String namespace; + + private final AtomicReference> notifier = new AtomicReference<>(); + + TestSpanProcessor(String namespace, String entityName) { + this.namespace = namespace; + this.entityName = entityName; + } + public List getEndedSpans() { + return spans.stream().collect(Collectors.toList()); + } + + @Override + public void onStart(Context context, ReadWriteSpan readWriteSpan) { + } + + @Override + public boolean isStartRequired() { + return false; + } + + @Override + public void onEnd(ReadableSpan readableSpan) { + LOGGER.info(readableSpan.toString()); + assertEquals("Microsoft.ServiceBus", readableSpan.getAttribute(AZ_NAMESPACE)); + assertEquals("servicebus", readableSpan.getAttribute(MESSAGING_SYSTEM)); + assertEquals(entityName, readableSpan.getAttribute(MESSAGING_DESTINATION_NAME)); + + // Depending on the version of OpenTelemetry being used, the attribute name for the peer name may be + // different. The attribute name was changed from "net.peer.name" to "server.address". + String actualNamespace = readableSpan.getAttribute(NET_PEER_NAME); + if (actualNamespace == null) { + actualNamespace = readableSpan.getAttribute(SERVER_ADDRESS); + } + + assertEquals(namespace, actualNamespace); + + spans.add(readableSpan); + Consumer filter = notifier.get(); + if (filter != null) { + filter.accept(readableSpan); + } + } + + public void notifyIfCondition(CountDownLatch countDownLatch, Predicate filter) { + notifier.set((span) -> { + if (filter.test(span)) { + countDownLatch.countDown(); + } + }); + } + + @Override + public boolean isEndRequired() { + return true; + } + } } -//import com.azure.core.tracing.opentelemetry.OpenTelemetryTracingOptions; -//import com.azure.core.util.ClientOptions; -//import com.azure.core.util.IterableStream; -//import com.azure.core.util.logging.ClientLogger; -//import com.azure.messaging.servicebus.implementation.instrumentation.ServiceBusTracer; -//import com.azure.messaging.servicebus.models.DeferOptions; -//import io.opentelemetry.api.GlobalOpenTelemetry; -//import io.opentelemetry.api.OpenTelemetry; -//import io.opentelemetry.api.common.AttributeKey; -//import io.opentelemetry.api.trace.Span; -//import io.opentelemetry.api.trace.SpanContext; -//import io.opentelemetry.api.trace.SpanKind; -//import io.opentelemetry.api.trace.StatusCode; -//import io.opentelemetry.context.Context; -//import io.opentelemetry.sdk.OpenTelemetrySdk; -//import io.opentelemetry.sdk.trace.IdGenerator; -//import io.opentelemetry.sdk.trace.ReadWriteSpan; -//import io.opentelemetry.sdk.trace.ReadableSpan; -//import io.opentelemetry.sdk.trace.SdkTracerProvider; -//import io.opentelemetry.sdk.trace.SpanProcessor; -//import io.opentelemetry.sdk.trace.data.LinkData; -//import org.junit.jupiter.api.Test; -//import org.junit.jupiter.api.parallel.Execution; -//import org.junit.jupiter.api.parallel.ExecutionMode; -//import reactor.core.Disposable; -//import reactor.core.scheduler.Schedulers; -//import reactor.test.StepVerifier; -// -//import java.time.Duration; -//import java.time.OffsetDateTime; -//import java.util.ArrayList; -//import java.util.Arrays; -//import java.util.Collections; -//import java.util.List; -//import java.util.UUID; -//import java.util.concurrent.ConcurrentLinkedDeque; -//import java.util.concurrent.CountDownLatch; -//import java.util.concurrent.TimeUnit; -//import java.util.concurrent.atomic.AtomicReference; -//import java.util.function.Consumer; -//import java.util.function.Predicate; -//import java.util.stream.Collectors; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -//import static org.junit.jupiter.api.Assertions.assertFalse; -//import static org.junit.jupiter.api.Assertions.assertNotNull; -//import static org.junit.jupiter.api.Assertions.assertNull; -//import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assertions.fail; -// -//@Execution(ExecutionMode.SAME_THREAD) -//public class TracingIntegrationTests extends IntegrationTestBase { -// private ClientOptions clientOptions; -// private TestSpanProcessor spanProcessor; -// private ServiceBusSenderAsyncClient sender; -// private ServiceBusReceiverAsyncClient receiver; -// private ServiceBusReceiverClient receiverSync; -// private ServiceBusProcessorClient processor; -// -// public TracingIntegrationTests() { -// super(new ClientLogger(TracingIntegrationTests.class)); -// } -// -// @Override -// protected void beforeTest() { -// spanProcessor = new TestSpanProcessor(getFullyQualifiedDomainName(), getQueueName(0)); -// OpenTelemetryTracingOptions tracingOptions = new OpenTelemetryTracingOptions() -// .setOpenTelemetry(OpenTelemetrySdk.builder() -// .setTracerProvider( -// SdkTracerProvider.builder() -// .addSpanProcessor(spanProcessor) -// .build()) -// .build()); -// clientOptions = new ClientOptions().setTracingOptions(tracingOptions); -// -// final ServiceBusClientBuilder senderBuilder = getBuilder(); -// sender = toClose(senderBuilder -// .clientOptions(clientOptions) -// .sender() -// .queueName(getQueueName(0)) -// .buildAsyncClient()); -// -// final ServiceBusClientBuilder receiverBuilder = getBuilder(); -// receiver = toClose(receiverBuilder -// .clientOptions(clientOptions) -// .receiver() -// .maxAutoLockRenewDuration(Duration.ZERO) -// .queueName(getQueueName(0)) -// .disableAutoComplete() -// .buildAsyncClient()); -// -// final ServiceBusClientBuilder receiverSyncBuilder = getBuilder(); -// receiverSync = toClose(receiverSyncBuilder -// .clientOptions(clientOptions) -// .receiver() -// .queueName(getQueueName(0)) -// .buildClient()); -// } -// -// @Override -// protected void afterTest() { -// GlobalOpenTelemetry.resetForTest(); -// sharedBuilder = null; -// } -// -// @Test -// public void sendAndReceive() throws InterruptedException { -// ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); -// ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); -// List messages = Arrays.asList(message1, message2); -// StepVerifier.create(sender.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(2); -// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); -// -// List received = new ArrayList<>(); -// Disposable subscription = receiver.receiveMessages() -// .take(2) -// .doOnNext(msg -> { -// received.add(msg); -// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); -// String traceId = Span.current().getSpanContext().getTraceId(); -// -// // context created for the message and current are the same -// assertTrue(traceparent.startsWith("00-" + traceId)); -// assertFalse(((ReadableSpan) Span.current()).hasEnded()); -// receiver.complete(msg).block(); -// }) -// .subscribe(); -// toClose(subscription); -// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// -// List messageSpans = findSpans(spans, "ServiceBus.message"); -// assertMessageSpan(messageSpans.get(0), message1); -// assertMessageSpan(messageSpans.get(1), message2); -// -// List send = findSpans(spans, "ServiceBus.send"); -// assertClientProducerSpan(send.get(0), messages, "ServiceBus.send", "publish"); -// -// List processed = findSpans(spans, "ServiceBus.process"); -// assertConsumerSpan(processed.get(0), received.get(0), "ServiceBus.process"); -// assertConsumerSpan(processed.get(1), received.get(1), "ServiceBus.process"); -// -// List completed = findSpans(spans, "ServiceBus.complete"); -// assertClientSpan(completed.get(0), Collections.singletonList(received.get(0)), "ServiceBus.complete", "settle"); -// assertClientSpan(completed.get(1), Collections.singletonList(received.get(1)), "ServiceBus.complete", "settle"); -// assertSettledVsProcessed(completed, processed, messages.size()); -// } -// -// @Test -// public void receiveAndRenewLockWithDuration() throws InterruptedException { -// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); -// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(2); -// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewMessageLock")); -// -// AtomicReference received = new AtomicReference<>(); -// StepVerifier.create(receiver.receiveMessages() -// .next() -// .flatMap(msg -> receiver.renewMessageLock(msg, Duration.ofSeconds(2)) -// .thenReturn(msg))) -// .assertNext(msg -> received.compareAndSet(null, msg)) -// .expectComplete() -// .verify(TIMEOUT); -// assertTrue(processedFound.await(30, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// -// List processed = findSpans(spans, "ServiceBus.process"); -// assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); -// -// List renewLock = findSpans(spans, "ServiceBus.renewMessageLock"); -// assertClientSpan(renewLock.get(0), Collections.singletonList(received.get()), "ServiceBus.renewMessageLock", null); -// } -// -// @Test -// public void receiveAndRenewSessionLockWithDuration() throws InterruptedException { -// String sessionId = "10"; -// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) -// .setSessionId(sessionId); -// -// OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), getSessionQueueName(0)); -// final ServiceBusClientBuilder senderBuilder = getBuilder(); -// sender = toClose(senderBuilder -// .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) -// .sender() -// .queueName(getSessionQueueName(0)) -// .buildAsyncClient()); -// -// final ServiceBusClientBuilder receiverBuilder = getBuilder(); -// ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(receiverBuilder -// .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) -// .sessionReceiver() -// .disableAutoComplete() -// .queueName(getSessionQueueName(0)) -// .buildAsyncClient()); -// -// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(2); -// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process") || s.getName().equals("ServiceBus.renewSessionLock")); -// -// AtomicReference received = new AtomicReference<>(); -// StepVerifier.create( -// sessionReceiver -// .acceptSession(sessionId) -// .flatMapMany(rec -> rec -// .renewSessionLock() -// .then(rec.receiveMessages().next()))) -// .assertNext(msg -> { -// received.set(msg); -// logger.atInfo() -// .addKeyValue("lockedUntil", msg.getLockedUntil()) -// .addKeyValue("sessionId", msg.getSessionId()) -// .log("message received"); -// }) -// .expectComplete() -// .verify(TIMEOUT); -// -// assertTrue(processedFound.await(30, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// -// List processed = findSpans(spans, "ServiceBus.process"); -// assertConsumerSpan(processed.get(0), received.get(), "ServiceBus.process"); -// -// List acceptSession = findSpans(spans, "ServiceBus.acceptSession"); -// assertClientSpan(acceptSession.get(0), Collections.emptyList(), "ServiceBus.acceptSession", null); -// -// List renewLock = findSpans(spans, "ServiceBus.renewSessionLock"); -// assertClientSpan(renewLock.get(0), Collections.emptyList(), "ServiceBus.renewSessionLock", null); -// } -// -// @Test -// public void receiveCheckSubscribe() throws InterruptedException { -// ServiceBusMessage message1 = new ServiceBusMessage(CONTENTS_BYTES); -// ServiceBusMessage message2 = new ServiceBusMessage(CONTENTS_BYTES); -// List messages = Arrays.asList(message1, message2); -// StepVerifier.create(sender.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(2); -// spanProcessor.notifyIfCondition(processedFound, s -> s.getName().equals("ServiceBus.process")); -// -// Disposable subscription = receiver.receiveMessages() -// .take(messages.size()) -// .subscribe(msg -> { -// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); -// String traceId = Span.current().getSpanContext().getTraceId(); -// -// // context created for the message and current are the same -// assertTrue(traceparent.startsWith("00-" + traceId)); -// assertFalse(((ReadableSpan) Span.current()).hasEnded()); -// receiver.complete(msg).block(); -// }); -// toClose(subscription); -// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messages.size()); -// } -// -// @Test -// public void sendAndReceiveParallelNoAutoCompleteAndLockRenewal() throws InterruptedException { -// int messageCount = 5; -// StepVerifier.create(sender.createMessageBatch() -// .doOnNext(batch -> { -// for (int i = 0; i < messageCount; i++) { -// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); -// } -// }) -// .flatMap(batch -> sender.sendMessages(batch))) -// .expectComplete() -// .verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(messageCount); -// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); -// -// final ServiceBusClientBuilder receiverBuilder = getBuilder(); -// ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(receiverBuilder -// .clientOptions(clientOptions) -// .receiver() -// .queueName(getQueueName(0)) -// .disableAutoComplete() -// .buildAsyncClient()); -// -// StepVerifier.create( -// receiverWithLockRenewal.receiveMessages() -// .take(messageCount) -// .doOnNext(msg -> { -// if (Span.current().getSpanContext().isValid()) { -// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); -// String traceId = Span.current().getSpanContext().getTraceId(); -// -// // context created for the message and current are the same -// assertTrue(traceparent.startsWith("00-" + traceId)); -// assertFalse(((ReadableSpan) Span.current()).hasEnded()); -// } -// receiver.complete(msg).block(); -// }) -// .parallel(messageCount, 1) -// .runOn(Schedulers.boundedElastic(), 1)) -// .expectNextCount(messageCount) -// .expectComplete() -// .verify(TIMEOUT); -// -// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// -// // all completed spans should have a parent, but complete call may start after the parent span has ended -// // the last part heavily depends on how above code is written wrt parallelization. -// // in the current form (receive -> doonnext (complete) -> parallel) -// // complete is happens synchronously from the receive perspective -// // so complete will finish before processing is completed. -// // -// // if complete call is done differently (e.g. receive -> parallel -> runon -> doonnext (complete)) -// // then doonnext callbacks become async and may happen after receiver call has completed -// // then complete will be a child of process, but will last longer than processing -// // TODO (limolkova): this is another good reason to rename receiver's span to delivery instead of processing. -// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); -// } -// -// @Test -// public void sendAndReceiveParallelAutoComplete() throws InterruptedException { -// int messageCount = 5; -// StepVerifier.create(sender.createMessageBatch() -// .doOnNext(batch -> { -// for (int i = 0; i < messageCount; i++) { -// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); -// } -// }) -// .flatMap(batch -> sender.sendMessages(batch))) -// .expectComplete() -// .verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(messageCount); -// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); -// -// final ServiceBusClientBuilder receiverBuilder = getBuilder(); -// ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(receiverBuilder -// .clientOptions(clientOptions) -// .receiver() -// .queueName(getQueueName(0)) -// .buildAsyncClient()); -// -// StepVerifier.create( -// receiverAutoComplete.receiveMessages() -// .take(messageCount) -// .doOnNext(msg -> { -// if (Span.current().getSpanContext().isValid()) { -// String traceparent = (String) msg.getApplicationProperties().get("traceparent"); -// String traceId = Span.current().getSpanContext().getTraceId(); -// -// // context created for the message and current are the same -// assertTrue(traceparent.startsWith("00-" + traceId)); -// assertFalse(((ReadableSpan) Span.current()).hasEnded()); -// } -// }) -// .parallel(messageCount, 1) -// .runOn(Schedulers.boundedElastic(), 1)) -// .expectNextCount(messageCount) -// .expectComplete() -// .verify(TIMEOUT); -// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); -// } -// -// @Test -// public void sendReceiveRenewLockAndDefer() throws InterruptedException { -// String traceId = IdGenerator.random().generateTraceId(); -// String traceparent = "00-" + traceId + "-" + IdGenerator.random().generateSpanId() + "-01"; -// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES); -// AtomicReference receivedMessage = new AtomicReference<>(); -// message.getApplicationProperties().put("traceparent", traceparent); -// -// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); -// -// CountDownLatch latch = new CountDownLatch(1); -// spanProcessor.notifyIfCondition(latch, s -> s.getName().equals("ServiceBus.receiveDeferredMessage")); -// toClose(receiver.receiveMessages() -// .filter(m -> traceparent.equals(m.getApplicationProperties().get("traceparent"))) -// .flatMap(m -> receiver.renewMessageLock(m).thenReturn(m)) -// .flatMap(m -> receiver.defer(m, new DeferOptions()).thenReturn(m)) -// .flatMap(m -> receiver.receiveDeferredMessage(m.getSequenceNumber()).thenReturn(m)) -// .subscribe(m -> { -// receivedMessage.compareAndSet(null, m); -// })); -// assertTrue(latch.await(120, TimeUnit.SECONDS)); -// -// List spans = spanProcessor.getEndedSpans(); -// -// assertEquals(0, findSpans(spans, "ServiceBus.message").size()); -// -// List send = findSpans(spans, "ServiceBus.send"); -// assertClientProducerSpan(send.get(0), Collections.singletonList(message), "ServiceBus.send", "publish"); -// -// List process = findSpans(spans, "ServiceBus.process", traceId); -// assertConsumerSpan(process.get(0), receivedMessage.get(), "ServiceBus.process"); -// -// List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock", traceId); -// assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.renewMessageLock", null); -// assertParent(renewMessageLock.get(0), process.get(0)); -// -// // for correlation to work after first async call, we need to enable otel rector instrumentations, -// // so no correlation beyond this point -// List defer = findSpans(spans, "ServiceBus.defer"); -// assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.defer", "settle"); -// -// List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); -// assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.receiveDeferredMessage", "receive"); -// } -// -// @Test -// public void sendReceiveRenewLockAndDeferSync() { -// StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) -// .expectComplete() -// .verify(TIMEOUT); -// -// ServiceBusReceivedMessage receivedMessage = null; -// while (receivedMessage == null) { -// IterableStream messages = receiverSync.receiveMessages(1, Duration.ofSeconds(10)); -// if (messages.iterator().hasNext()) { -// receivedMessage = messages.iterator().next(); -// } -// } -// -// receiverSync.renewMessageLock(receivedMessage); -// receiverSync.defer(receivedMessage, new DeferOptions()); -// receiverSync.receiveDeferredMessage(receivedMessage.getSequenceNumber()); -// -// List spans = spanProcessor.getEndedSpans(); -// -// List received = findSpans(spans, "ServiceBus.receiveMessages"); -// assertClientSpan(received.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveMessages", "receive"); -// -// List renewMessageLock = findSpans(spans, "ServiceBus.renewMessageLock"); -// assertClientSpan(renewMessageLock.get(0), Collections.singletonList(receivedMessage), "ServiceBus.renewMessageLock", null); -// -// List defer = findSpans(spans, "ServiceBus.defer"); -// assertClientSpan(defer.get(0), Collections.singletonList(receivedMessage), "ServiceBus.defer", "settle"); -// -// List receiveDeferredMessage = findSpans(spans, "ServiceBus.receiveDeferredMessage"); -// assertClientSpan(receiveDeferredMessage.get(0), Collections.singletonList(receivedMessage), "ServiceBus.receiveDeferredMessage", "receive"); -// } -// -// @Test -// public void syncReceive() { -// List messages = new ArrayList<>(); -// messages.add(new ServiceBusMessage(CONTENTS_BYTES)); -// messages.add(new ServiceBusMessage(CONTENTS_BYTES)); -// -// StepVerifier.create(sender.sendMessages(messages)) -// .expectComplete() -// .verify(TIMEOUT); -// -// List receivedMessages = receiverSync.receiveMessages(2, Duration.ofSeconds(10)) -// .stream().collect(Collectors.toList()); -// receivedMessages.forEach(receiverSync::complete); -// -// List spans = spanProcessor.getEndedSpans(); -// -// List received = findSpans(spans, "ServiceBus.receiveMessages"); -// assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); -// -// assertEquals(0, findSpans(spans, "ServiceBus.process").size()); -// -// List completed = findSpans(spans, "ServiceBus.complete"); -// assertClientSpan(completed.get(0), Collections.singletonList(receivedMessages.get(0)), "ServiceBus.complete", "settle"); -// assertClientSpan(completed.get(1), Collections.singletonList(receivedMessages.get(1)), "ServiceBus.complete", "settle"); -// } -// -// @Test -// public void syncReceiveTimeout() { -// List receivedMessages = receiverSync.receiveMessages(100, Duration.ofMillis(1)) -// .stream().collect(Collectors.toList()); -// -// List spans = spanProcessor.getEndedSpans(); -// -// List received = findSpans(spans, "ServiceBus.receiveMessages"); -// assertClientSpan(received.get(0), receivedMessages, "ServiceBus.receiveMessages", "receive"); -// assertEquals(StatusCode.UNSET, received.get(0).toSpanData().getStatus().getStatusCode()); -// -// assertEquals(0, findSpans(spans, "ServiceBus.process").size()); -// } -// -// @Test -// public void peekMessage() { -// StepVerifier.create(sender.sendMessage(new ServiceBusMessage(CONTENTS_BYTES))) -// .expectComplete() -// .verify(TIMEOUT); -// -// StepVerifier.create(receiver.peekMessage()) -// .assertNext(receivedMessage -> { -// ReadableSpan received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage").get(0); -// if (receivedMessage.getApplicationProperties().containsKey("traceparent")) { -// logger.atInfo() -// .addKeyValue("traceparent", receivedMessage.getApplicationProperties().get("traceparent")) -// .log("span should have link"); -// assertClientSpan(received, Collections.singletonList(receivedMessage), "ServiceBus.peekMessage", "receive"); -// } else { -// assertEquals("ServiceBus.peekMessage", received.getName()); -// assertEquals(SpanKind.CLIENT, received.getKind()); -// assertEquals(0, received.toSpanData().getLinks().size()); -// assertEquals("receive", received.getAttribute(AttributeKey.stringKey("messaging.operation"))); -// } -// }) -// .expectComplete() -// .verify(TIMEOUT); -// } -// -// @Test -// public void peekNonExistingMessage() { -// StepVerifier.create(receiver.peekMessage(Long.MAX_VALUE - 1)) -// .expectComplete() -// .verify(TIMEOUT); -// -// List received = findSpans(spanProcessor.getEndedSpans(), "ServiceBus.peekMessage"); -// assertClientSpan(received.get(0), Collections.emptyList(), "ServiceBus.peekMessage", "receive"); -// } -// -// @Test -// public void sendAndProcessNoAutoComplete() throws InterruptedException { -// String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) -// .setMessageId(messageId); -// -// StepVerifier.create(sender.sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// -// String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); -// CountDownLatch processFound = new CountDownLatch(1); -// spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") && span.getParentSpanContext().getSpanId().equals(message1SpanId)); -// -// AtomicReference currentInProcess = new AtomicReference<>(); -// AtomicReference receivedMessage = new AtomicReference<>(); -// final ServiceBusClientBuilder processorBuilder = getBuilder(); -// processor = toClose(processorBuilder -// .clientOptions(clientOptions) -// .processor() -// .queueName(getQueueName(0)) -// .processMessage(mc -> { -// if (mc.getMessage().getMessageId().equals(messageId)) { -// currentInProcess.compareAndSet(null, Span.current()); -// receivedMessage.compareAndSet(null, mc.getMessage()); -// } -// mc.complete(); -// }) -// .processError(e -> fail("unexpected error", e.getException())) -// .buildProcessorClient()); -// -// toClose((AutoCloseable) () -> processor.stop()); -// processor.start(); -// assertTrue(processFound.await(20, TimeUnit.SECONDS)); -// processor.stop(); -// -// assertTrue(currentInProcess.get().getSpanContext().isValid()); -// List spans = spanProcessor.getEndedSpans(); -// -// assertMessageSpan(spans.get(0), message); -// assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.send", "publish"); -// -// assertEquals(0, findSpans(spans, "ServiceBus.consume").size()); -// List processed = findSpans(spans, "ServiceBus.process") -// .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); -// assertEquals(1, processed.size()); -// assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); -// -// List completed = findSpans(spans, "ServiceBus.complete").stream() -// .filter(c -> { -// List links = c.toSpanData().getLinks(); -// return !links.isEmpty() && links.get(0).getSpanContext().getSpanId().equals(message1SpanId); -// }) -// .collect(Collectors.toList()); -// assertEquals(1, completed.size()); -// assertClientProducerSpan(completed.get(0), Collections.singletonList(message), "ServiceBus.complete", "settle"); -// -// assertSettledVsProcessed(completed, processed, 1); -// } -// -// @Test -// public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { -// String sessionQueueName = getSessionQueueName(0); -// String sessionId = UUID.randomUUID().toString(); -// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES).setSessionId(sessionId); -// -// OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), sessionQueueName); -// clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); -// final ServiceBusClientBuilder senderBuilder = getBuilder(); -// sender = toClose(senderBuilder -// .clientOptions(clientOptions) -// .sender() -// .queueName(sessionQueueName) -// .buildAsyncClient()); -// -// StepVerifier.create(sender.sendMessage(message)).expectComplete().verify(TIMEOUT); -// -// CountDownLatch processFound = new CountDownLatch(2); -// spanProcessor.notifyIfCondition(processFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); -// -// AtomicReference currentInProcess = new AtomicReference<>(); -// AtomicReference receivedMessage = new AtomicReference<>(); -// final ServiceBusClientBuilder processorBuilder = getBuilder(); -// processor = toClose(processorBuilder -// .clientOptions(clientOptions) -// .sessionProcessor() -// .maxConcurrentSessions(1) -// .queueName(sessionQueueName) -// .disableAutoComplete() -// .processMessage(mc -> { -// currentInProcess.compareAndSet(null, Span.current()); -// receivedMessage.compareAndSet(null, mc.getMessage()); -// mc.complete(); -// }) -// .processError(e -> fail("unexpected error", e.getException())) -// .buildProcessorClient()); -// -// toClose((AutoCloseable) () -> processor.stop()); -// processor.start(); -// assertTrue(processFound.await(20, TimeUnit.SECONDS)); -// processor.stop(); -// -// assertTrue(currentInProcess.get().getSpanContext().isValid()); -// List spans = spanProcessor.getEndedSpans(); -// -// List processed = findSpans(spans, "ServiceBus.process") -// .stream().filter(p -> p.equals(currentInProcess.get())).collect(Collectors.toList()); -// assertEquals(1, processed.size()); -// assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); -// -// List completed = findSpans(spans, "ServiceBus.complete"); -// assertEquals(1, completed.size()); -// assertClientSpan(completed.get(0), Collections.singletonList(receivedMessage.get()), "ServiceBus.complete", "settle"); -// assertSettledVsProcessed(completed, processed, 1); -// } -// -// @Test -// public void sendAndProcessParallel() throws InterruptedException { -// int messageCount = 10; -// StepVerifier.create(sender.createMessageBatch() -// .doOnNext(batch -> { -// for (int i = 0; i < messageCount; i++) { -// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES) -// .setMessageId(UUID.randomUUID().toString())); -// } -// }) -// .flatMap(batch -> { -// logMessages(batch.getMessages(), sender.getEntityPath(), "sending"); -// return sender.sendMessages(batch); -// })) -// .expectComplete() -// .verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(messageCount * 2); -// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); -// -// final ServiceBusClientBuilder processorBuilder = getBuilder(); -// processor = toClose(processorBuilder -// .clientOptions(clientOptions) -// .processor() -// .queueName(getQueueName(0)) -// .maxConcurrentCalls(messageCount) -// .processMessage(mc -> { -// logMessage(mc.getMessage(), processor.getQueueName(), "processing"); -// String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); -// String traceId = Span.current().getSpanContext().getTraceId(); -// -// // context created for the message and current are the same -// assertTrue(traceparent.startsWith("00-" + traceId)); -// assertFalse(((ReadableSpan) Span.current()).hasEnded()); -// }) -// .processError(e -> fail("unexpected error", e.getException())) -// .buildProcessorClient()); -// toClose((AutoCloseable) () -> processor.stop()); -// processor.start(); -// assertTrue(processedFound.await(30, TimeUnit.SECONDS)); -// processor.stop(); -// -// List spans = spanProcessor.getEndedSpans(); -// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); -// } -// -// @Test -// public void sendAndProcessParallelNoAutoComplete() throws InterruptedException { -// int messageCount = 5; -// StepVerifier.create(sender.createMessageBatch() -// .doOnNext(batch -> { -// for (int i = 0; i < messageCount; i++) { -// batch.tryAddMessage(new ServiceBusMessage(CONTENTS_BYTES)); -// } -// }) -// .flatMap(batch -> sender.sendMessages(batch))) -// .expectComplete() -// .verify(TIMEOUT); -// -// CountDownLatch processedFound = new CountDownLatch(messageCount); -// spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); -// -// final ServiceBusClientBuilder processorBuilder = getBuilder(); -// processor = toClose(processorBuilder -// .clientOptions(clientOptions) -// .processor() -// .queueName(getQueueName(0)) -// .maxConcurrentCalls(messageCount) -// .disableAutoComplete() -// .processMessage(mc -> { -// String traceparent = (String) mc.getMessage().getApplicationProperties().get("traceparent"); -// String traceId = Span.current().getSpanContext().getTraceId(); -// -// // context created for the message and current are the same -// assertTrue(traceparent.startsWith("00-" + traceId)); -// mc.complete(); -// }) -// .processError(e -> fail("unexpected error", e.getException())) -// .buildProcessorClient()); -// toClose((AutoCloseable) () -> processor.stop()); -// processor.start(); -// assertTrue(processedFound.await(20, TimeUnit.SECONDS)); -// processor.stop(); -// -// List spans = spanProcessor.getEndedSpans(); -// assertSettledVsProcessed(findSpans(spans, "ServiceBus.complete"), findSpans(spans, "ServiceBus.process"), messageCount); -// } -// -// @Test -// public void sendProcessAndFail() throws InterruptedException { -// String messageId = UUID.randomUUID().toString(); -// ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) -// .setMessageId(messageId); -// -// StepVerifier.create(sender.sendMessage(message)) -// .expectComplete() -// .verify(TIMEOUT); -// -// String message1SpanId = message.getApplicationProperties().get("traceparent").toString().substring(36, 52); -// -// CountDownLatch messageProcessed = new CountDownLatch(1); -// spanProcessor.notifyIfCondition(messageProcessed, span -> -// "ServiceBus.process".equals(span.getName()) && span.getParentSpanContext().getSpanId().equals(message1SpanId)); -// -// AtomicReference receivedMessage = new AtomicReference<>(); -// final ServiceBusClientBuilder processorBuilder = getBuilder(); -// processor = toClose(processorBuilder -// .clientOptions(clientOptions) -// .processor() -// .queueName(getQueueName(0)) -// .processMessage(mc -> { -// if (mc.getMessage().getMessageId().equals(messageId)) { -// receivedMessage.compareAndSet(null, mc.getMessage()); -// throw new RuntimeException("foo"); -// } -// }) -// .processError(e -> { }) -// .buildProcessorClient()); -// toClose((AutoCloseable) () -> processor.stop()); -// processor.start(); -// assertTrue(messageProcessed.await(30, TimeUnit.SECONDS)); -// processor.stop(); -// -// List spans = spanProcessor.getEndedSpans(); -// List processed = findSpans(spans, "ServiceBus.process") -// .stream().filter(p -> p.getParentSpanContext().isValid()) -// .filter(p -> p.toSpanData().getStatus().getStatusCode() == StatusCode.ERROR) -// .collect(Collectors.toList()); -// assertEquals(1, processed.size()); -// assertConsumerSpan(processed.get(0), receivedMessage.get(), "ServiceBus.process"); -// -// List abandoned = findSpans(spans, "ServiceBus.abandon").stream() -// .filter(c -> c.toSpanData().getLinks().get(0).getSpanContext().getSpanId().equals(message1SpanId)) -// .collect(Collectors.toList()); -// assertEquals(1, abandoned.size()); -// assertClientProducerSpan(abandoned.get(0), Collections.singletonList(message), "ServiceBus.abandon", "settle"); -// assertSettledVsProcessed(abandoned, processed, 1); -// } -// -// @Test -// public void scheduleAndCancelMessage() { -// ServiceBusMessage message = new ServiceBusMessage("m"); -// StepVerifier.create( -// sender.scheduleMessage(message, OffsetDateTime.now().plusSeconds(100)) -// .flatMap(l -> sender.cancelScheduledMessage(l))) -// .expectComplete() -// .verify(TIMEOUT); -// -// List spans = spanProcessor.getEndedSpans(); -// assertMessageSpan(spans.get(0), message); -// assertClientProducerSpan(spans.get(1), Collections.singletonList(message), "ServiceBus.scheduleMessage", "publish"); -// assertClientProducerSpan(spans.get(2), Collections.emptyList(), "ServiceBus.cancelScheduledMessage", null); -// } -// -// private void assertMessageSpan(ReadableSpan actual, ServiceBusMessage message) { -// assertEquals("ServiceBus.message", actual.getName()); -// assertEquals(SpanKind.PRODUCER, actual.getKind()); -// assertNull(actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); -// String traceparent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getSpanContext().getSpanId() + "-01"; -// assertEquals(message.getApplicationProperties().get("Diagnostic-Id"), traceparent); -// assertEquals(message.getApplicationProperties().get("traceparent"), traceparent); -// } -// -// private void assertClientProducerSpan(ReadableSpan actual, List messages, String spanName, String operationName) { -// assertEquals(spanName, actual.getName()); -// assertEquals(SpanKind.CLIENT, actual.getKind()); -// List links = actual.toSpanData().getLinks(); -// assertEquals(messages.size(), links.size()); -// assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); -// if (messages.size() > 1) { -// assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); -// } -// -// for (int i = 0; i < links.size(); i++) { -// String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); -// SpanContext linkContext = links.get(i).getSpanContext(); -// String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; -// assertEquals(messageTraceparent, linkTraceparent); -// } -// } -// -// private void assertClientSpan(ReadableSpan actual, List messages, String spanName, String operationName) { -// assertEquals(spanName, actual.getName()); -// assertEquals(SpanKind.CLIENT, actual.getKind()); -// List links = actual.toSpanData().getLinks(); -// assertEquals(messages.size(), links.size()); -// assertEquals(operationName, actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); -// if (messages.size() > 1) { -// assertEquals(messages.size(), actual.getAttribute(AttributeKey.longKey("messaging.batch.message_count"))); -// } -// for (int i = 0; i < links.size(); i++) { -// String messageTraceparent = (String) messages.get(i).getApplicationProperties().get("traceparent"); -// SpanContext linkContext = links.get(i).getSpanContext(); -// String linkTraceparent = "00-" + linkContext.getTraceId() + "-" + linkContext.getSpanId() + "-01"; -// assertEquals(messageTraceparent, linkTraceparent); -// assertNotNull(links.get(i).getAttributes().get(AttributeKey.longKey(ServiceBusTracer.MESSAGE_ENQUEUED_TIME_ATTRIBUTE_NAME))); -// } -// } -// -// private void assertConsumerSpan(ReadableSpan actual, ServiceBusReceivedMessage message, String spanName) { -// assertEquals(spanName, actual.getName()); -// assertEquals(SpanKind.CONSUMER, actual.getKind()); -// assertEquals(0, actual.toSpanData().getLinks().size()); -// assertEquals("process", actual.getAttribute(AttributeKey.stringKey("messaging.operation"))); -// String messageTraceparent = (String) message.getApplicationProperties().get("traceparent"); -// String parent = "00-" + actual.getSpanContext().getTraceId() + "-" + actual.getParentSpanContext().getSpanId() + "-01"; -// assertEquals(messageTraceparent, parent); -// } -// -// private void assertParent(ReadableSpan child, ReadableSpan parent) { -// assertEquals(child.getParentSpanContext().getTraceId(), parent.getSpanContext().getTraceId()); -// assertEquals(child.getParentSpanContext().getSpanId(), parent.getSpanContext().getSpanId()); -// } -// -// private void assertSettledVsProcessed(List settled, List processed, int expectedCount) { -// assertTrue(settled.size() >= expectedCount, -// String.format("Expected at least %d completed spans, but found %d", expectedCount, settled.size())); -// assertTrue(processed.size() >= expectedCount, -// String.format("Expected at least %d processed spans, but found %d", expectedCount, processed.size())); -// -// // there could be more completed spans than processed because completion happens before processing, and we can have more messages in the queue than we expected. -// assertTrue(settled.size() >= processed.size(), -// String.format("Expected at least as many completed spans as processed spans, but found %d completed and %d processed", settled.size(), processed.size())); -// -// int processedFound = 0; -// for (ReadableSpan readableSpan : settled) { -// ReadableSpan parent = findParent(readableSpan, processed); -// if (parent != null) { -// processedFound++; -// assertTrue(readableSpan.getLatencyNanos() <= parent.getLatencyNanos(), () -> -// String.format("Expected settled span to have less latency than processed span, but found %d vs %d", -// readableSpan.getLatencyNanos(), parent.getLatencyNanos())); -// } -// } -// -// assertEquals(expectedCount, processedFound); -// } -// -// private ReadableSpan findParent(ReadableSpan child, List possibleParents) { -// String traceId = child.getParentSpanContext().getTraceId(); -// String parentId = child.getParentSpanContext().getSpanId(); -// for (ReadableSpan p : possibleParents) { -// if (traceId.equals(p.getSpanContext().getTraceId()) -// && parentId.equals(p.getSpanContext().getSpanId())) { -// return p; -// } -// } -// -// return null; -// } -// -// private List findSpans(List spans, String spanName) { -// return spans.stream() -// .filter(s -> s.getName().equals(spanName)) -// .collect(Collectors.toList()); -// } -// -// private List findSpans(List spans, String spanName, String traceId) { -// return spans.stream() -// .filter(s -> s.getName().equals(spanName)) -// .filter(s -> s.getSpanContext().getTraceId().equals(traceId)) -// .collect(Collectors.toList()); -// } -// -// private OpenTelemetry configureOTel(String namespace, String entityName) { -// GlobalOpenTelemetry.resetForTest(); -// spanProcessor = new TestSpanProcessor(namespace, entityName); -// return OpenTelemetrySdk.builder().setTracerProvider( -// SdkTracerProvider.builder() -// .addSpanProcessor(spanProcessor) -// .build()).build(); -// } -// -// static class TestSpanProcessor implements SpanProcessor { -// private static final ClientLogger LOGGER = new ClientLogger(TestSpanProcessor.class); -// private static final AttributeKey AZ_NAMESPACE = AttributeKey.stringKey("az.namespace"); -// private static final AttributeKey MESSAGING_SYSTEM = AttributeKey.stringKey("messaging.system"); -// private static final AttributeKey MESSAGING_DESTINATION_NAME -// = AttributeKey.stringKey("messaging.destination.name"); -// private static final AttributeKey NET_PEER_NAME = AttributeKey.stringKey("net.peer.name"); -// private static final AttributeKey SERVER_ADDRESS = AttributeKey.stringKey("server.address"); -// -// private final ConcurrentLinkedDeque spans = new ConcurrentLinkedDeque<>(); -// private final String entityName; -// private final String namespace; -// -// private final AtomicReference> notifier = new AtomicReference<>(); -// -// TestSpanProcessor(String namespace, String entityName) { -// this.namespace = namespace; -// this.entityName = entityName; -// } -// public List getEndedSpans() { -// return spans.stream().collect(Collectors.toList()); -// } -// -// @Override -// public void onStart(Context context, ReadWriteSpan readWriteSpan) { -// } -// -// @Override -// public boolean isStartRequired() { -// return false; -// } -// -// @Override -// public void onEnd(ReadableSpan readableSpan) { -// LOGGER.info(readableSpan.toString()); -// assertEquals("Microsoft.ServiceBus", readableSpan.getAttribute(AZ_NAMESPACE)); -// assertEquals("servicebus", readableSpan.getAttribute(MESSAGING_SYSTEM)); -// assertEquals(entityName, readableSpan.getAttribute(MESSAGING_DESTINATION_NAME)); -// -// // Depending on the version of OpenTelemetry being used, the attribute name for the peer name may be -// // different. The attribute name was changed from "net.peer.name" to "server.address". -// String actualNamespace = readableSpan.getAttribute(NET_PEER_NAME); -// if (actualNamespace == null) { -// actualNamespace = readableSpan.getAttribute(SERVER_ADDRESS); -// } -// -// assertEquals(namespace, actualNamespace); -// -// spans.add(readableSpan); -// Consumer filter = notifier.get(); -// if (filter != null) { -// filter.accept(readableSpan); -// } -// } -// -// public void notifyIfCondition(CountDownLatch countDownLatch, Predicate filter) { -// notifier.set((span) -> { -// if (filter.test(span)) { -// countDownLatch.countDown(); -// } -// }); -// } -// -// @Override -// public boolean isEndRequired() { -// return true; -// } -// } -//} From 828efaf37e0d8fd9541b1e7b0f5118ea56912387 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 7 Jul 2024 12:11:06 -0700 Subject: [PATCH 15/29] revert --- .../ClaimsBasedSecurityChannel.java | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java index aa7394e7ac17..2befe95dbbb3 100644 --- a/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java +++ b/sdk/core/azure-core-amqp/src/main/java/com/azure/core/amqp/implementation/ClaimsBasedSecurityChannel.java @@ -63,37 +63,35 @@ public ClaimsBasedSecurityChannel(Mono responseChannelMo @Override public Mono authorize(String tokenAudience, String scopes) { return cbsChannelMono.flatMap( - channel -> { - System.out.println(OffsetDateTime.now() + ": Requesting token..."); - return credential.getToken(new TokenRequestContext().addScopes(scopes)).flatMap(accessToken -> { - System.out.println(OffsetDateTime.now() + ": Got token...: " + accessToken.getExpiresAt()); - final Message request = Proton.message(); - final Map properties = new HashMap<>(); - properties.put(PUT_TOKEN_OPERATION, PUT_TOKEN_OPERATION_VALUE); - properties.put(PUT_TOKEN_EXPIRY, Date.from(accessToken.getExpiresAt().toInstant())); - properties.put(PUT_TOKEN_TYPE, authorizationType.toString()); - properties.put(PUT_TOKEN_AUDIENCE, tokenAudience); - final ApplicationProperties applicationProperties = new ApplicationProperties(properties); - request.setApplicationProperties(applicationProperties); - request.setBody(new AmqpValue(accessToken.getToken())); + channel -> credential.getToken(new TokenRequestContext().addScopes(scopes)).flatMap(accessToken -> { + final Message request = Proton.message(); + final Map properties = new HashMap<>(); + properties.put(PUT_TOKEN_OPERATION, PUT_TOKEN_OPERATION_VALUE); + properties.put(PUT_TOKEN_EXPIRY, Date.from(accessToken.getExpiresAt().toInstant())); + properties.put(PUT_TOKEN_TYPE, authorizationType.toString()); + properties.put(PUT_TOKEN_AUDIENCE, tokenAudience); - return channel.sendWithAck(request).handle((Message message, SynchronousSink sink) -> { - if (RequestResponseUtils.isSuccessful(message)) { - sink.next(accessToken.getExpiresAt()); - } else { - final String description = getStatusDescription(message); - final AmqpResponseCode statusCode = getStatusCode(message); - final Exception error = amqpResponseCodeToException(statusCode.getValue(), description, - channel.getErrorContext()); + final ApplicationProperties applicationProperties = new ApplicationProperties(properties); + request.setApplicationProperties(applicationProperties); + request.setBody(new AmqpValue(accessToken.getToken())); - sink.error(error); - } - }).switchIfEmpty(Mono.error(() -> new AmqpException(true, + return channel.sendWithAck(request).handle((Message message, SynchronousSink sink) -> { + if (RequestResponseUtils.isSuccessful(message)) { + sink.next(accessToken.getExpiresAt()); + } else { + final String description = getStatusDescription(message); + final AmqpResponseCode statusCode = getStatusCode(message); + final Exception error = amqpResponseCodeToException(statusCode.getValue(), description, + channel.getErrorContext()); + + sink.error(error); + } + }) + .switchIfEmpty(Mono.error(() -> new AmqpException(true, String.format("No response received from CBS node. tokenAudience: '%s'. scopes: '%s'", tokenAudience, scopes), channel.getErrorContext()))); - }); - }); + })); } @Override From c144540d0b08e69f16ebf7345e21c8695b81d7c4 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 7 Jul 2024 12:20:47 -0700 Subject: [PATCH 16/29] check the mode --- .../servicebus/IntegrationTestBase.java | 33 +------------------ 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 7268751b438d..2ef6289737b1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -9,7 +9,6 @@ import com.azure.core.amqp.implementation.ConnectionStringProperties; import com.azure.core.amqp.models.AmqpMessageBody; import com.azure.core.credential.TokenCredential; -import com.azure.core.credential.TokenRequestContext; import com.azure.core.experimental.util.tracing.LoggingTracerProvider; import com.azure.core.test.TestBase; import com.azure.core.test.TestContextManager; @@ -22,13 +21,11 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; -import com.azure.identity.AzurePowerShellCredentialBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; import com.azure.messaging.servicebus.implementation.DispositionStatus; import com.azure.messaging.servicebus.implementation.MessagingEntityType; -import com.azure.messaging.servicebus.implementation.ServiceBusConstants; import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -43,7 +40,6 @@ import java.net.Proxy; import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -212,8 +208,8 @@ public ProxyOptions getProxyConfiguration() { } protected ServiceBusClientBuilder getAuthenticatedBuilder(boolean useCredentials) { + System.out.println("TestMode:---" + super.getTestMode()); final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - logger.info("Getting Builder using credentials : [{}] ", useCredentials); if (useCredentials) { final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), @@ -494,31 +490,4 @@ protected final Configuration v1OrV2(boolean isV2) { return new ConfigurationBuilder(configSource) .build(); } - - public static final class SBPowerShellCachedCredentials implements TokenCredential { - private final AzurePowerShellCredentialBuilder builder; - private final TokenRequestContext context; - private final Mono cached; - - public SBPowerShellCachedCredentials() { - - this.builder = new AzurePowerShellCredentialBuilder(); - this.context = new TokenRequestContext().addScopes(ServiceBusConstants.AZURE_ACTIVE_DIRECTORY_SCOPE); - this.cached = Mono.fromCallable(builder::build) - .flatMap(cred -> { - return cred.getToken(context); - }).doOnNext(token -> { - System.out.println(".....Got Token.....: now=" + OffsetDateTime.now() + " ExpireAt=" + token.getExpiresAt()); - }) - .doOnError(e -> { - System.out.println(".....Fetching token failed.....:" + e); - }) - .cache(t -> Duration.ofMinutes(5), e -> Duration.ZERO, () -> Duration.ZERO); - } - - @Override - public Mono getToken(TokenRequestContext context) { - return this.cached; - } - } } From ea111b27fa93502ffb0923c81feb9bbcd3a28213 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 7 Jul 2024 14:32:17 -0700 Subject: [PATCH 17/29] configure cred based on the test mode / env --- .../servicebus/IntegrationTestBase.java | 94 ++++++++----------- .../servicebus/ProxyReceiveTest.java | 4 +- .../servicebus/ProxySelectorTest.java | 2 +- .../messaging/servicebus/ProxySendTest.java | 2 +- .../ServiceBusClientBuilderTest.java | 8 +- .../ServiceBusMixClientIntegrationTest.java | 22 ++--- ...viceBusProcessorClientIntegrationTest.java | 22 ++--- ...BusReceiverAsyncClientIntegrationTest.java | 34 +++---- ...rviceBusReceiverClientIntegrationTest.java | 6 +- ...ceBusSenderAsyncClientIntegrationTest.java | 34 +++---- ...rviceBusSessionManagerIntegrationTest.java | 15 ++- .../azure/messaging/servicebus/TestUtils.java | 54 ++++++----- .../servicebus/TracingIntegrationTests.java | 32 +++---- ...inistrationAsyncClientIntegrationTest.java | 56 +++++------ ...usAdministrationClientIntegrationTest.java | 49 +--------- 15 files changed, 184 insertions(+), 250 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 2ef6289737b1..3d1e6dfcab16 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -6,7 +6,6 @@ import com.azure.core.amqp.AmqpTransportType; import com.azure.core.amqp.ProxyAuthenticationType; import com.azure.core.amqp.ProxyOptions; -import com.azure.core.amqp.implementation.ConnectionStringProperties; import com.azure.core.amqp.models.AmqpMessageBody; import com.azure.core.credential.TokenCredential; import com.azure.core.experimental.util.tracing.LoggingTracerProvider; @@ -21,6 +20,7 @@ import com.azure.core.util.CoreUtils; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; +import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusReceiverClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSenderClientBuilder; import com.azure.messaging.servicebus.ServiceBusClientBuilder.ServiceBusSessionReceiverClientBuilder; @@ -30,6 +30,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.provider.Arguments; +import org.opentest4j.TestAbortedException; import reactor.core.Disposable; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; @@ -59,7 +60,6 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; public abstract class IntegrationTestBase extends TestBase { - public static final boolean USE_CREDENTIALS = true; protected static final Duration OPERATION_TIMEOUT = Duration.ofSeconds(30); protected static final Duration TIMEOUT = Duration.ofSeconds(60); // Tests use timeouts of 20-60 seconds to verify something has happened @@ -73,7 +73,7 @@ public abstract class IntegrationTestBase extends TestBase { private List toClose = new ArrayList<>(); private String testName; private final Scheduler scheduler = Schedulers.parallel(); - private final AtomicReference pipelineCredential = new AtomicReference<>(); + private final AtomicReference credentialCached = new AtomicReference<>(); protected static final byte[] CONTENTS_BYTES = "Some-contents".getBytes(StandardCharsets.UTF_8); protected String sessionId; @@ -125,26 +125,6 @@ public TestMode getTestMode() { // return CoreUtils.isNullOrEmpty(getConnectionString()) ? TestMode.PLAYBACK : TestMode.RECORD; } - public static String getConnectionString() { - return TestUtils.getConnectionString(false); - } - - public static String getConnectionString(boolean withSas) { - return TestUtils.getConnectionString(withSas); - } - - protected static ConnectionStringProperties getConnectionStringProperties() { - return new ConnectionStringProperties(getConnectionString(false)); - } - - protected static ConnectionStringProperties getConnectionStringProperties(boolean withSas) { - return new ConnectionStringProperties(getConnectionString(withSas)); - } - - public String getFullyQualifiedDomainName() { - return TestUtils.getFullyQualifiedDomainName(); - } - /** * Gets the name of the queue. * @@ -207,27 +187,39 @@ public ProxyOptions getProxyConfiguration() { return new ProxyOptions(authenticationType, proxy, username, password); } - protected ServiceBusClientBuilder getAuthenticatedBuilder(boolean useCredentials) { - System.out.println("TestMode:---" + super.getTestMode()); + /** + * Creates a new instance of {@link ServiceBusClientBuilder} with authentication set up in {@link TestMode#LIVE} and + * {@link TestMode#RECORD} modes. + * + * @return the builder with authentication set up. + * @throws org.opentest4j.TestAbortedException if the test mode is {@link TestMode#PLAYBACK}. + */ + protected ServiceBusClientBuilder getAuthenticatedBuilder() { + final TestMode mode = super.getTestMode(); final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); - if (useCredentials) { - final String fullyQualifiedDomainName = getFullyQualifiedDomainName(); - assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), - "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); - final TokenCredential tokenCredential = TestUtils.getPipelineCredential(pipelineCredential); - return builder.credential(fullyQualifiedDomainName, tokenCredential); + if (mode == TestMode.LIVE) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final TokenCredential credential = TestUtils.getPipelineCredential(credentialCached); + return builder.credential(fullyQualifiedDomainName, credential); + } else if (mode == TestMode.RECORD) { + final String connectionString = TestUtils.getConnectionString(false); + if (CoreUtils.isNullOrEmpty(connectionString)) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); + return builder.credential(fullyQualifiedDomainName, credential); + } else { + return builder.connectionString(connectionString); + } } else { - return builder.connectionString(getConnectionString()); + throw new TestAbortedException("Integration tests are not enabled in playback mode."); } } /** - * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings and uses a - * connection string to authenticate if {@code useCredentials} is false. Otherwise, uses a service principal through - * {@link com.azure.identity.ClientSecretCredential}. + * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings. */ - protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { - return getAuthenticatedBuilder(useCredentials) + protected ServiceBusClientBuilder getBuilder() { + return getAuthenticatedBuilder() .proxyOptions(ProxyOptions.SYSTEM_DEFAULTS) .retryOptions(RETRY_OPTIONS) .clientOptions(optionsWithTracing) @@ -236,31 +228,23 @@ protected ServiceBusClientBuilder getBuilder(boolean useCredentials) { .configuration(v1OrV2(true)); } - /** - * Creates a new instance of {@link ServiceBusClientBuilder} with the default integration test settings and uses a - * token credentials to authenticate. - */ - protected ServiceBusClientBuilder getBuilder() { - return getBuilder(USE_CREDENTIALS); - } - - protected ServiceBusClientBuilder getBuilder(boolean useCredentials, boolean sharedConnection) { + protected ServiceBusClientBuilder getBuilder(boolean sharedConnection) { ServiceBusClientBuilder builder; if (sharedConnection && sharedBuilder == null) { - sharedBuilder = getBuilder(useCredentials); + sharedBuilder = getBuilder(); builder = sharedBuilder; } else if (sharedConnection) { builder = sharedBuilder; } else { - builder = getBuilder(useCredentials); + builder = getBuilder(); } return builder; } - protected ServiceBusSenderClientBuilder getSenderBuilder(boolean useCredentials, MessagingEntityType entityType, + protected ServiceBusSenderClientBuilder getSenderBuilder(MessagingEntityType entityType, int entityIndex, boolean isSessionAware, boolean sharedConnection) { - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + ServiceBusClientBuilder builder = getBuilder(sharedConnection); switch (entityType) { case QUEUE: final String queueName = isSessionAware ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); @@ -277,10 +261,10 @@ protected ServiceBusSenderClientBuilder getSenderBuilder(boolean useCredentials, } } - protected ServiceBusReceiverClientBuilder getReceiverBuilder(boolean useCredentials, MessagingEntityType entityType, + protected ServiceBusReceiverClientBuilder getReceiverBuilder(MessagingEntityType entityType, int entityIndex, boolean sharedConnection) { - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + ServiceBusClientBuilder builder = getBuilder(sharedConnection); switch (entityType) { case QUEUE: final String queueName = getQueueName(entityIndex); @@ -300,10 +284,10 @@ protected ServiceBusReceiverClientBuilder getReceiverBuilder(boolean useCredenti } } - protected ServiceBusSessionReceiverClientBuilder getSessionReceiverBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection, AmqpRetryOptions retryOptions) { + protected ServiceBusSessionReceiverClientBuilder getSessionReceiverBuilder(MessagingEntityType entityType, + int entityIndex, boolean sharedConnection, AmqpRetryOptions retryOptions) { - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + ServiceBusClientBuilder builder = getBuilder(sharedConnection); switch (entityType) { case QUEUE: diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java index 86fc9de5f543..9909ca951f25 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxyReceiveTest.java @@ -79,7 +79,7 @@ public void receiveMessage() { final String messageTracking = UUID.randomUUID().toString(); final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageTracking); - final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder(USE_CREDENTIALS) + final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder() .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .sender() @@ -88,7 +88,7 @@ public void receiveMessage() { toClose(sender); - final ServiceBusReceiverAsyncClient receiver = getAuthenticatedBuilder(USE_CREDENTIALS) + final ServiceBusReceiverAsyncClient receiver = getAuthenticatedBuilder() .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .receiver() diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java index 443f7838e8a2..64b67c3ba64b 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySelectorTest.java @@ -68,7 +68,7 @@ public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { }); final ServiceBusMessage message = new ServiceBusMessage(BinaryData.fromString("Hello")); - final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder(USE_CREDENTIALS) + final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder() .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) .sender() diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java index d7c90f2028c7..51b7583ca4c5 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ProxySendTest.java @@ -77,7 +77,7 @@ public void sendEvents() { final String messageId = UUID.randomUUID().toString(); final List messages = TestUtils.getServiceBusMessages(NUMBER_OF_EVENTS, messageId); - final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder(USE_CREDENTIALS) + final ServiceBusSenderAsyncClient sender = getAuthenticatedBuilder() .transportType(AmqpTransportType.AMQP_WEB_SOCKETS) .verifyMode(SslDomain.VerifyMode.ANONYMOUS_PEER) .retryOptions(new AmqpRetryOptions().setTryTimeout(Duration.ofSeconds(10))) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index 4b3ae1225e05..813a493f28a1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -270,8 +270,8 @@ public void testConnectionStringWithSas() { @Test @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureNameKeyCredential() { - ConnectionStringProperties properties = getConnectionStringProperties(); - String fullyQualifiedNamespace = getFullyQualifiedDomainName(); + ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(false)); + String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); String sharedAccessKeyName = properties.getSharedAccessKeyName(); String sharedAccessKey = properties.getSharedAccessKey(); String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); @@ -295,8 +295,8 @@ public void testBatchSendEventByAzureNameKeyCredential() { @Test @Disabled("Convert to use AzurePowerShellCredentials?") public void testBatchSendEventByAzureSasCredential() { - ConnectionStringProperties properties = getConnectionStringProperties(true); - String fullyQualifiedNamespace = getFullyQualifiedDomainName(); + ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(true)); + String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); String sharedAccessSignature = properties.getSharedAccessSignature(); String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java index bf0e6bfe1f20..316731660eda 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusMixClientIntegrationTest.java @@ -98,7 +98,7 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder().enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); @@ -170,7 +170,7 @@ void crossEntityQueueTransaction(boolean isSessionEnabled) throws InterruptedExc // Verify that message is received by queue B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + setSenderAndReceiver(entityType, sendQueueBIndex); StepVerifier.create(receiver.receiveMessages().take(1)) .assertNext(receivedMessage -> { assertMessageEquals(receivedMessage, messageId, isSessionEnabled); @@ -207,7 +207,7 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder().enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); @@ -287,7 +287,7 @@ void crossEntitySubscriptionTransaction(boolean isSessionEnabled) throws Interru // Verify that message is received by queue B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + setSenderAndReceiver(entityType, sendQueueBIndex); StepVerifier.create(receiver.receiveMessages().take(1)) .assertNext(receivedMessage -> { assertMessageEquals(receivedMessage, messageId, isSessionEnabled); @@ -323,7 +323,7 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder().enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().queueName(queueA).buildAsyncClient()); @@ -373,7 +373,7 @@ void crossEntityQueueTransactionWithReceiverSenderTest(boolean isSessionEnabled) // Assert // Verify that message is received by entity B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + setSenderAndReceiver(entityType, sendQueueBIndex); StepVerifier.create(receiver.receiveMessages() .filter(receiveMessage -> messageId.equals(receiveMessage.getMessageId())).take(1)) .assertNext(receivedMessage -> { @@ -410,7 +410,7 @@ void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionE message.setSessionId(sessionId); final List messages = Arrays.asList(message); - ServiceBusClientBuilder builder = getBuilder(USE_CREDENTIALS).enableCrossEntityTransactions(); + ServiceBusClientBuilder builder = getBuilder().enableCrossEntityTransactions(); // Initialize sender final ServiceBusSenderAsyncClient senderAsyncA = toClose(builder.sender().topicName(topicA).buildAsyncClient()); @@ -458,7 +458,7 @@ void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionE // Assert // Verify that message is received by entity B if (!isSessionEnabled) { - setSenderAndReceiver(entityType, sendQueueBIndex, USE_CREDENTIALS); + setSenderAndReceiver(entityType, sendQueueBIndex); StepVerifier.create(receiver.receiveMessages().take(1)) .assertNext(receivedMessage -> { assertMessageEquals(receivedMessage, messageId, isSessionEnabled); @@ -472,13 +472,13 @@ void crossEntitySubscriptionTransactionWithReceiverSenderTest(boolean isSessionE /** * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. */ - private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { + private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex) { final boolean isSessionAware = false; final boolean sharedConnection = true; - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionAware, sharedConnection) .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, sharedConnection) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .disableAutoComplete() .buildAsyncClient()); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java index e1c7df6d596c..bcaad916bdc1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusProcessorClientIntegrationTest.java @@ -82,7 +82,7 @@ void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) th assertNotNull(sessionId, "'sessionId' should have been set."); AmqpRetryOptions amqpRetryOptions = new AmqpRetryOptions() .setTryTimeout(Duration.ofSeconds(2 * lockTimeoutDurationSeconds)); - processor = toClose(getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, amqpRetryOptions) + processor = toClose(getSessionProcessorBuilder(entityType, entityIndex, false, amqpRetryOptions) .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) .disableAutoComplete() .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) @@ -90,7 +90,7 @@ void receiveMessage(MessagingEntityType entityType, boolean isSessionEnabled) th .buildProcessorClient()); } else { - processor = toClose(getProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false) + processor = toClose(getProcessorBuilder(entityType, entityIndex, false) .maxAutoLockRenewDuration(expectedMaxAutoLockRenew) .disableAutoComplete() .processMessage(context -> processMessage(context, countDownLatch, messageId, lastMessageReceivedTime, lockTimeoutDurationSeconds)) @@ -115,7 +115,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = - getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, RETRY_OPTIONS) + getSessionProcessorBuilder(entityType, entityIndex, false, RETRY_OPTIONS) .sessionIdleTimeout(sessionIdleTimeout) .disableAutoComplete(); @@ -130,7 +130,7 @@ void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws Interrupt ServiceBusSenderAsyncClient sender = createSender(entityType, entityIndex, true); ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder processorBuilder = - getSessionProcessorBuilder(USE_CREDENTIALS, entityType, entityIndex, false, + getSessionProcessorBuilder(entityType, entityIndex, false, new AmqpRetryOptions().setTryTimeout(tryTimeout)) .disableAutoComplete(); @@ -196,10 +196,10 @@ private void processError(ServiceBusErrorContext context, CountDownLatch countdo context.getFullyQualifiedNamespace(), context.getEntityPath()); } - private ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection) { + private ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBuilder(MessagingEntityType entityType, + int entityIndex, boolean sharedConnection) { - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + ServiceBusClientBuilder builder = getBuilder(sharedConnection); switch (entityType) { case QUEUE: final String queueName = getQueueName(entityIndex); @@ -218,10 +218,10 @@ private ServiceBusClientBuilder.ServiceBusProcessorClientBuilder getProcessorBui } } - private ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessionProcessorBuilder(boolean useCredentials, - MessagingEntityType entityType, int entityIndex, boolean sharedConnection, AmqpRetryOptions amqpRetryOptions) { + private ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessionProcessorBuilder(MessagingEntityType entityType, + int entityIndex, boolean sharedConnection, AmqpRetryOptions amqpRetryOptions) { - ServiceBusClientBuilder builder = getBuilder(useCredentials, sharedConnection); + ServiceBusClientBuilder builder = getBuilder(sharedConnection); builder.retryOptions(amqpRetryOptions); switch (entityType) { @@ -246,7 +246,7 @@ private ServiceBusClientBuilder.ServiceBusSessionProcessorClientBuilder getSessi private ServiceBusSenderAsyncClient createSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { final boolean shareConnection = false; - return toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + return toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index 7e649c5a82d0..1e54aba7183f 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -243,9 +243,9 @@ void transactionReceiveCompleteCommitMixClient(MessagingEntityType entityType) { // Arrange final boolean shareConnection = true; final int entityIndex = 0; - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, shareConnection) .buildAsyncClient()); final String messageId = UUID.randomUUID().toString(); @@ -288,7 +288,7 @@ void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSe final boolean shareConnection = false; final Duration shortWait = Duration.ofSeconds(3); - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); final String messageId = UUID.randomUUID().toString(); @@ -298,11 +298,11 @@ void receiveTwoMessagesAutoComplete(MessagingEntityType entityType, boolean isSe // Now create receiver if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + this.sessionReceiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .buildAsyncClient()); this.receiver = toClose(sessionReceiver.acceptSession(sessionId).block()); } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, shareConnection) .buildAsyncClient()); } @@ -327,7 +327,7 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio final int entityIndex = USE_CASE_AUTO_COMPLETE; final boolean shareConnection = false; - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); final String messageId = CoreUtils.randomUuid().toString(); final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); @@ -339,11 +339,11 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio // Now create receiver if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + this.sessionReceiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .buildAsyncClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, shareConnection) .buildAsyncClient()); } @@ -703,7 +703,7 @@ void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEn final Duration shortWait = Duration.ofSeconds(3); final Long expectedLongValue = Long.parseLong("6"); - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); // Send value Object @@ -725,11 +725,11 @@ void receiveMessageAmqpTypes(MessagingEntityType entityType, boolean isSessionEn // Now create receiver if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + this.sessionReceiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .buildAsyncClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, shareConnection) .buildAsyncClient()); } @@ -1154,7 +1154,7 @@ void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnab final String queueName = isSessionEnabled ? getSessionQueueName(entityIndex) : getQueueName(entityIndex); assertNotNull(queueName, "'queueName' cannot be null."); - deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() + deadLetterReceiver = toClose(getBuilder().receiver() .queueName(queueName) .subQueue(SubQueue.DEAD_LETTER_QUEUE) .buildAsyncClient()); @@ -1165,7 +1165,7 @@ void receiveFromDeadLetter(MessagingEntityType entityType, boolean isSessionEnab assertNotNull(topicName, "'topicName' cannot be null."); assertNotNull(subscriptionName, "'subscriptionName' cannot be null."); - deadLetterReceiver = toClose(getBuilder(USE_CREDENTIALS).receiver() + deadLetterReceiver = toClose(getBuilder().receiver() .topicName(topicName) .subscriptionName(subscriptionName) .subQueue(SubQueue.DEAD_LETTER_QUEUE) @@ -1440,7 +1440,7 @@ void autoComplete(MessagingEntityType entityType) { .verifyComplete(); final ServiceBusReceiverAsyncClient autoCompleteReceiver = - toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, index, false) + toClose(getReceiverBuilder(entityType, index, false) .buildAsyncClient()); Set sequenceNumbers = new HashSet<>(); @@ -1493,7 +1493,7 @@ private ServiceBusReceiverAsyncClient createReceiver(MessagingEntityType entityT final boolean shareConnection = false; if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) + sessionReceiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, shareConnection, DEFAULT_RETRY_OPTIONS) .maxAutoLockRenewDuration(options.getMaxAutoLockRenewDuration()) .sessionIdleTimeout(options.getSessionIdleTimeout()) .disableAutoComplete() @@ -1501,7 +1501,7 @@ private ServiceBusReceiverAsyncClient createReceiver(MessagingEntityType entityT return toClose(sessionReceiver.acceptSession(sessionId).block()); } - return toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, shareConnection) + return toClose(getReceiverBuilder(entityType, entityIndex, shareConnection) .maxAutoLockRenewDuration(options.getMaxAutoLockRenewDuration()) .disableAutoComplete() .buildAsyncClient()); @@ -1509,7 +1509,7 @@ private ServiceBusReceiverAsyncClient createReceiver(MessagingEntityType entityT private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled) { final boolean shareConnection = false; - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, shareConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, shareConnection) .buildAsyncClient()); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index 7c6fb22ccb82..6d9ed2c3d089 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -856,18 +856,18 @@ private void setSender(MessagingEntityType entityType, int entityIndex, boolean } private void setSender(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionEnabled, sharedConnection).buildClient()); } private void setReceiver(MessagingEntityType entityType, int entityIndex, boolean isSessionEnabled, boolean sharedConnection) { if (isSessionEnabled) { assertNotNull(sessionId, "'sessionId' should have been set."); - this.sessionReceiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection, null) + this.sessionReceiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, sharedConnection, null) .buildClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId)); } else { - this.receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, entityIndex, sharedConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, sharedConnection) .buildClient()); } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index 2e7ae5ee4a9e..b835ec486fb6 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -94,7 +94,7 @@ static Stream transactionMessageSendAndCompleteTransaction() { @ParameterizedTest void nonSessionQueueSendMessage(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); + setSenderAndReceiver(entityType, 0); final String messageId = UUID.randomUUID().toString(); final ServiceBusMessage message = TestUtils.getServiceBusMessage(CONTENTS_BYTES, messageId); @@ -112,7 +112,7 @@ void nonSessionQueueSendMessage(MessagingEntityType entityType) { @ParameterizedTest void nonSessionEntitySendMessageList(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); int count = 4; final List messages = TestUtils.getServiceBusMessages(count, UUID.randomUUID().toString(), CONTENTS_BYTES); @@ -131,7 +131,7 @@ void nonSessionEntitySendMessageList(MessagingEntityType entityType) { @ParameterizedTest void nonSessionMessageBatch(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT, USE_CREDENTIALS); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_DEFAULT); final String messageId = UUID.randomUUID().toString(); final CreateMessageBatchOptions options = new CreateMessageBatchOptions().setMaximumSizeInBytes(1024); @@ -169,13 +169,13 @@ void viaQueueMessageSendTest() { final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); final String viaQueueName = getQueueName(viaIntermediateEntity); - setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); + setSenderAndReceiver(entityType, viaIntermediateEntity); - final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, + final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(entityType, destinationEntity, false, shareConnection) //.viaQueueName(viaQueueName) .buildAsyncClient()); - final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, + final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(entityType, destinationEntity, shareConnection) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .disableAutoComplete() @@ -257,16 +257,16 @@ void viaTopicMessageSendTest() { final List messages = TestUtils.getServiceBusMessages(total, messageId, CONTENTS_BYTES); final String viaTopicName = getTopicName(viaIntermediateEntity); - setSenderAndReceiver(entityType, viaIntermediateEntity, USE_CREDENTIALS); + setSenderAndReceiver(entityType, viaIntermediateEntity); final ServiceBusReceiverAsyncClient intermediateReceiver = receiver; final ServiceBusSenderAsyncClient intermediateSender = sender; - final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, + final ServiceBusSenderAsyncClient destination1ViaSender = toClose(getSenderBuilder(entityType, destinationEntity, false, shareConnection) //.viaTopicName(viaTopicName) .buildAsyncClient()); - final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(USE_CREDENTIALS, entityType, + final ServiceBusReceiverAsyncClient destination1Receiver = toClose(getReceiverBuilder(entityType, destinationEntity, shareConnection) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .disableAutoComplete() @@ -333,7 +333,7 @@ void viaTopicMessageSendTest() { void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType, boolean isCommit) { // Arrange Duration shortTimeout = Duration.ofSeconds(15); - setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES, USE_CREDENTIALS); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_SEND_READ_BACK_MESSAGES); final boolean isSessionEnabled = false; final String messageId = UUID.randomUUID().toString(); final int total = 3; @@ -392,7 +392,7 @@ void transactionMessageSendAndCompleteTransaction(MessagingEntityType entityType @ParameterizedTest void sendWithCredentials(MessagingEntityType entityType) { // Arrange - setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); + setSenderAndReceiver(entityType, 0); final String messageId = UUID.randomUUID().toString(); final List messages = TestUtils.getServiceBusMessages(5, messageId, CONTENTS_BYTES); @@ -417,7 +417,7 @@ void transactionScheduleAndCommitTest(MessagingEntityType entityType) { // Arrange boolean isSessionEnabled = false; - setSenderAndReceiver(entityType, 0, USE_CREDENTIALS); + setSenderAndReceiver(entityType, 0); final Duration scheduleDuration = Duration.ofSeconds(3); final String messageId = UUID.randomUUID().toString(); final ServiceBusMessage message = getMessage(messageId, isSessionEnabled); @@ -463,7 +463,7 @@ void transactionScheduleMessagesTest(MessagingEntityType entityType) { final int total = 2; final Duration shortWait = Duration.ofSeconds(3); - setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES, USE_CREDENTIALS); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_SCHEDULE_MESSAGES); final Duration scheduleDuration = Duration.ofSeconds(5); final String messageId = UUID.randomUUID().toString(); @@ -518,7 +518,7 @@ void cancelScheduledMessagesTest(MessagingEntityType entityType) { final boolean isSessionEnabled = false; final Duration shortWaitTime = Duration.ofSeconds(5); final int total = 2; - setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES, USE_CREDENTIALS); + setSenderAndReceiver(entityType, TestUtils.USE_CASE_CANCEL_MESSAGES); final Duration scheduleDuration = Duration.ofSeconds(15); final String messageId = UUID.randomUUID().toString(); final List messages = new ArrayList<>(); @@ -543,13 +543,13 @@ void cancelScheduledMessagesTest(MessagingEntityType entityType) { /** * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. */ - private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex, boolean useCredentials) { + private void setSenderAndReceiver(MessagingEntityType entityType, int entityIndex) { final boolean isSessionAware = false; final boolean sharedConnection = true; - this.sender = toClose(getSenderBuilder(useCredentials, entityType, entityIndex, isSessionAware, sharedConnection) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, isSessionAware, sharedConnection) .buildAsyncClient()); - this.receiver = toClose(getReceiverBuilder(useCredentials, entityType, entityIndex, sharedConnection) + this.receiver = toClose(getReceiverBuilder(entityType, entityIndex, sharedConnection) .receiveMode(ServiceBusReceiveMode.RECEIVE_AND_DELETE) .disableAutoComplete() .buildAsyncClient()); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index 262ad0ec9b78..5167e05bde58 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -107,8 +107,7 @@ void rollingSessionOnIdleTimeout(MessagingEntityType entityType) throws Interrup final Duration sessionIdleTimeout = Duration.ofSeconds(3); setSender(entityType, entityIndex); - this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) + this.receiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS) .disableAutoComplete() .maxConcurrentSessions(1) .sessionIdleTimeout(sessionIdleTimeout) @@ -125,8 +124,7 @@ void rollingSessionOnTryTimeout(MessagingEntityType entityType) throws Interrupt final AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); setSender(entityType, entityIndex); - this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, retryOptions) + this.receiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, false, retryOptions) .disableAutoComplete() .maxConcurrentSessions(1) .buildAsyncClientForProcessor()); @@ -166,8 +164,7 @@ void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { ServiceBusMessage message1 = getServiceBusMessage(contents, randomPrefix + "1").setSessionId(randomPrefix + "1"); AmqpRetryOptions retryOptions = new AmqpRetryOptions().setTryTimeout(tryTimeout); - this.receiver = toClose(getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, retryOptions) + this.receiver = toClose(getSessionReceiverBuilder(entityType, entityIndex, false, retryOptions) .disableAutoComplete() .sessionIdleTimeout(sessionIdleTimeout) .buildAsyncClientForProcessor()); @@ -192,14 +189,14 @@ void noRollingSessionWhenNoConcurrentSessions(MessagingEntityType entityType) { * Sets the sender and receiver. If session is enabled, then a single-named session receiver is created. */ private void setSender(MessagingEntityType entityType, int entityIndex) { - this.sender = toClose(getSenderBuilder(USE_CREDENTIALS, entityType, entityIndex, true, false) + this.sender = toClose(getSenderBuilder(entityType, entityIndex, true, false) .buildAsyncClient()); } private void setReceiver(MessagingEntityType entityType, int entityIndex, Function onBuild) { - ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(USE_CREDENTIALS, - entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); + ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(entityType, entityIndex, + false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); this.sessionReceiver = toClose(onBuild.apply(sessionBuilder).buildAsyncClient()); this.receiver = toClose(this.sessionReceiver.acceptSession(sessionId).block()); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java index e9bcdf552e8d..e4f0ae34eb51 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java @@ -5,9 +5,7 @@ import com.azure.core.amqp.exception.AmqpResponseCode; import com.azure.core.amqp.implementation.ConnectionStringProperties; -import com.azure.core.credential.AccessToken; import com.azure.core.credential.TokenCredential; -import com.azure.core.credential.TokenRequestContext; import com.azure.core.util.BinaryData; import com.azure.core.util.Configuration; import com.azure.core.util.CoreUtils; @@ -24,6 +22,7 @@ import org.apache.qpid.proton.amqp.messaging.Data; import org.apache.qpid.proton.amqp.messaging.MessageAnnotations; import org.apache.qpid.proton.message.Message; +import org.opentest4j.TestAbortedException; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; @@ -54,7 +53,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; public class TestUtils { private static final ClientLogger LOGGER = new ClientLogger(TestUtils.class); @@ -173,6 +171,20 @@ public static String getFullyQualifiedDomainName() { return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME", "REDACTED.servicebus.windows.net"); } + /** + * Gets the fully qualified domain name for the service bus resource. + * + * @return the fully qualified domain name for the service bus resource. + * @throws org.opentest4j.TestAbortedException if the environment variable is not set. + */ + public static String getFullyQualifiedDomainNameWithAssertion() { + final String fullyQualifiedDomainName = getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME"); + if (CoreUtils.isNullOrEmpty(fullyQualifiedDomainName)) { + throw new TestAbortedException("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set."); + } + return fullyQualifiedDomainName; + } + public static String getEndpoint() { return getPropertyValue("AZURE_SERVICEBUS_ENDPOINT_SUFFIX", ".servicebus.windows.net"); } @@ -232,13 +244,13 @@ public static String getSessionSubscriptionBaseName() { } /** - * Obtain a {@link com.azure.identity.AzurePowerShellCredentialBuilder} when running in Azure pipelines that is + * Obtain a {@link com.azure.identity.AzurePipelinesCredentialBuilder} when running in Azure pipelines that is * configured with service connections federated identity. * - * @return A {@link com.azure.identity.AzurePowerShellCredentialBuilder} when running in Azure pipelines that is + * @return A {@link com.azure.identity.AzurePipelinesCredentialBuilder} when running in Azure pipelines that is * configured with service connections federated identity, {@code null} otherwise. */ - public static AzurePipelinesCredentialBuilder getAzurePipelinesCredentialBuilder() { + public static AzurePipelinesCredentialBuilder getPipelineCredentialBuilder() { final String serviceConnectionId = getPropertyValue("AZURESUBSCRIPTION_SERVICE_CONNECTION_ID"); final String clientId = getPropertyValue("AZURESUBSCRIPTION_CLIENT_ID"); final String tenantId = getPropertyValue("AZURESUBSCRIPTION_TENANT_ID"); @@ -257,26 +269,20 @@ public static AzurePipelinesCredentialBuilder getAzurePipelinesCredentialBuilder * Obtain the Azure Pipelines credential if running in Azure Pipelines configured with service connections federated identity. * * @return the Azure Pipelines credential. + * @throws TestAbortedException if the test is not running in Azure Pipelines configured with service connections federated identity. */ - public static TokenCredential getPipelineCredential(AtomicReference pipelineCredential) { - return pipelineCredential.updateAndGet(credential -> { - if (credential == null) { - final AzurePipelinesCredentialBuilder builder = TestUtils.getAzurePipelinesCredentialBuilder(); - if (builder == null) { - assumeTrue(false, "Test required to run on Azure Pipelines that is configured with service connections federated identity."); - return null; - } - final AzurePipelinesCredential pipelinesCredential = builder.build(); - return new TokenCredential() { - @Override - public Mono getToken(TokenRequestContext request) { - return Mono.defer(() -> { - return pipelinesCredential.getToken(request); - }).subscribeOn(Schedulers.boundedElastic()); - } - }; + public static TokenCredential getPipelineCredential(AtomicReference credentialCached) { + return credentialCached.updateAndGet(cached -> { + if (cached != null) { + return cached; + } + final AzurePipelinesCredentialBuilder builder = TestUtils.getPipelineCredentialBuilder(); + if (builder == null) { + throw new TestAbortedException("Test required to run on Azure Pipelines that is configured with service connections federated identity."); } - return credential; + final AzurePipelinesCredential pipelinesCredential = builder.build(); + return request -> Mono.defer(() -> pipelinesCredential.getToken(request)) + .subscribeOn(Schedulers.boundedElastic()); }); } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java index 2b6b83081fb9..1c122d17a729 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java @@ -68,7 +68,7 @@ public TracingIntegrationTests() { @Override protected void beforeTest() { - spanProcessor = new TestSpanProcessor(getFullyQualifiedDomainName(), getQueueName(0)); + spanProcessor = new TestSpanProcessor(TestUtils.getFullyQualifiedDomainName(), getQueueName(0)); OpenTelemetryTracingOptions tracingOptions = new OpenTelemetryTracingOptions() .setOpenTelemetry(OpenTelemetrySdk.builder() .setTracerProvider( @@ -78,14 +78,14 @@ protected void beforeTest() { .build()); clientOptions = new ClientOptions().setTracingOptions(tracingOptions); - final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(); sender = toClose(senderBuilder .clientOptions(clientOptions) .sender() .queueName(getQueueName(0)) .buildAsyncClient()); - final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(); receiver = toClose(receiverBuilder .clientOptions(clientOptions) .receiver() @@ -94,7 +94,7 @@ protected void beforeTest() { .disableAutoComplete() .buildAsyncClient()); - final ServiceBusClientBuilder receiverSyncBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder receiverSyncBuilder = getAuthenticatedBuilder(); receiverSync = toClose(receiverSyncBuilder .clientOptions(clientOptions) .receiver() @@ -189,15 +189,15 @@ public void receiveAndRenewSessionLockWithDuration() throws InterruptedException ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) .setSessionId(sessionId); - OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), getSessionQueueName(0)); - final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + OpenTelemetry otel = configureOTel(TestUtils.getFullyQualifiedDomainName(), getSessionQueueName(0)); + final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(); sender = toClose(senderBuilder .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) .sender() .queueName(getSessionQueueName(0)) .buildAsyncClient()); - final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(); ServiceBusSessionReceiverAsyncClient sessionReceiver = toClose(receiverBuilder .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) .sessionReceiver() @@ -287,7 +287,7 @@ public void sendAndReceiveParallelNoAutoCompleteAndLockRenewal() throws Interrup CountDownLatch processedFound = new CountDownLatch(messageCount); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(); ServiceBusReceiverAsyncClient receiverWithLockRenewal = toClose(receiverBuilder .clientOptions(clientOptions) .receiver() @@ -348,7 +348,7 @@ public void sendAndReceiveParallelAutoComplete() throws InterruptedException { CountDownLatch processedFound = new CountDownLatch(messageCount); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder receiverBuilder = getAuthenticatedBuilder(); ServiceBusReceiverAsyncClient receiverAutoComplete = toClose(receiverBuilder .clientOptions(clientOptions) .receiver() @@ -548,7 +548,7 @@ public void sendAndProcessNoAutoComplete() throws InterruptedException { AtomicReference currentInProcess = new AtomicReference<>(); AtomicReference receivedMessage = new AtomicReference<>(); - final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(); processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() @@ -598,9 +598,9 @@ public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { String sessionId = UUID.randomUUID().toString(); ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES).setSessionId(sessionId); - OpenTelemetry otel = configureOTel(getFullyQualifiedDomainName(), sessionQueueName); + OpenTelemetry otel = configureOTel(TestUtils.getFullyQualifiedDomainName(), sessionQueueName); clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); - final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(); sender = toClose(senderBuilder .clientOptions(clientOptions) .sender() @@ -614,7 +614,7 @@ public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { AtomicReference currentInProcess = new AtomicReference<>(); AtomicReference receivedMessage = new AtomicReference<>(); - final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(); processor = toClose(processorBuilder .clientOptions(clientOptions) .sessionProcessor() @@ -668,7 +668,7 @@ public void sendAndProcessParallel() throws InterruptedException { CountDownLatch processedFound = new CountDownLatch(messageCount * 2); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process") || span.getName().equals("ServiceBus.complete")); - final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(); processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() @@ -710,7 +710,7 @@ public void sendAndProcessParallelNoAutoComplete() throws InterruptedException { CountDownLatch processedFound = new CountDownLatch(messageCount); spanProcessor.notifyIfCondition(processedFound, span -> span.getName().equals("ServiceBus.process")); - final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(); processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() @@ -753,7 +753,7 @@ public void sendProcessAndFail() throws InterruptedException { "ServiceBus.process".equals(span.getName()) && span.getParentSpanContext().getSpanId().equals(message1SpanId)); AtomicReference receivedMessage = new AtomicReference<>(); - final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(USE_CREDENTIALS); + final ServiceBusClientBuilder processorBuilder = getAuthenticatedBuilder(); processor = toClose(processorBuilder .clientOptions(clientOptions) .processor() diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 5d1d92bc80c5..11be81e836d5 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -21,6 +21,7 @@ import com.azure.core.test.models.TestProxySanitizer; import com.azure.core.test.models.TestProxySanitizerType; import com.azure.core.test.utils.MockTokenCredential; +import com.azure.core.util.CoreUtils; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; @@ -55,12 +56,9 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -//import java.util.regex.Matcher; -//import java.util.regex.Pattern; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Stream; -import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; @@ -103,7 +101,7 @@ class ServiceBusAdministrationAsyncClientIntegrationTest extends TestProxyTestBa TEST_PROXY_REQUEST_MATCHERS = Collections.singletonList(customMatcher); } - private final AtomicReference pipelineCredential = new AtomicReference<>(); + private final AtomicReference credentialCached = new AtomicReference<>(); public static Stream createHttpClients() { return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); @@ -1219,22 +1217,32 @@ void updateRuleResponse(HttpClient httpClient) { private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)); + configure(builder, httpClient, interceptorManager, credentialCached); + return builder.buildAsyncClient(); + } - if (USE_CREDENTIALS) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - builder.credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)); - } else { - final String connectionString = interceptorManager.isPlaybackMode() - ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" - : TestUtils.getConnectionString(false); - builder.connectionString(connectionString); - } - + static void configure(ServiceBusAdministrationClientBuilder builder, + HttpClient httpClient, InterceptorManager interceptorManager, AtomicReference credentialCached) { if (interceptorManager.isPlaybackMode()) { + builder.credential(new MockTokenCredential()); builder.httpClient(interceptorManager.getPlaybackClient()); } else if (interceptorManager.isLiveMode()) { - builder.httpClient(httpClient); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final TokenCredential credential = TestUtils.getPipelineCredential(credentialCached); + builder.credential(fullyQualifiedDomainName, credential); + if (httpClient != null) { + builder.httpClient(httpClient); + } } else { + // Record Mode. + final String connectionString = TestUtils.getConnectionString(false); + if (CoreUtils.isNullOrEmpty(connectionString)) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); + builder.credential(fullyQualifiedDomainName, credential); + } else { + builder.connectionString(connectionString); + } builder.httpClient(httpClient).addPolicy(interceptorManager.getRecordPolicy()); } @@ -1242,23 +1250,5 @@ private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) interceptorManager.addSanitizers(TEST_PROXY_SANITIZERS); interceptorManager.addMatchers(TEST_PROXY_REQUEST_MATCHERS); } - - return builder.buildAsyncClient(); - } - - /** - * Retrieve the appropriate TokenCredential based on the test mode. - * - * @param interceptorManager the interceptor manager - * @return The appropriate token credential - */ - private TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { - if (interceptorManager.isLiveMode()) { - return TestUtils.getPipelineCredential(pipelineCredential); - } else if (interceptorManager.isRecordMode()) { - return new DefaultAzureCredentialBuilder().build(); - } else { - return new MockTokenCredential(); - } } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 5ac22f176473..942321c7b672 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -9,17 +9,12 @@ import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.ResourceExistsException; import com.azure.core.exception.ResourceNotFoundException; -import com.azure.core.http.policy.FixedDelayOptions; import com.azure.core.http.policy.HttpLogDetailLevel; import com.azure.core.http.policy.HttpLogOptions; -import com.azure.core.http.policy.RetryOptions; import com.azure.core.http.rest.PagedIterable; import com.azure.core.http.rest.Response; -import com.azure.core.test.InterceptorManager; import com.azure.core.test.TestProxyTestBase; -import com.azure.core.test.utils.MockTokenCredential; import com.azure.core.util.Context; -import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; @@ -58,7 +53,6 @@ //import java.util.regex.Matcher; //import java.util.regex.Pattern; -import static com.azure.messaging.servicebus.IntegrationTestBase.USE_CREDENTIALS; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; //import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; @@ -66,6 +60,7 @@ import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; import static com.azure.messaging.servicebus.TestUtils.getTopicBaseName; +import static com.azure.messaging.servicebus.administration.ServiceBusAdministrationAsyncClientIntegrationTest.configure; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -81,7 +76,7 @@ @Execution(ExecutionMode.SAME_THREAD) public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTestBase { private static final Duration TIMEOUT = Duration.ofSeconds(20); - private final AtomicReference pipelineCredential = new AtomicReference<>(); + private final AtomicReference credentialCached = new AtomicReference<>(); // /** // * Test to connect to the service bus with an azure identity TokenCredential. @@ -938,45 +933,7 @@ void listRules() { private ServiceBusAdministrationClient getClient() { final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)); - - if (USE_CREDENTIALS) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); - builder.credential(fullyQualifiedDomainName, getTestTokenCredential(interceptorManager)); - } else { - final String connectionString = interceptorManager.isPlaybackMode() - ? "Endpoint=sb://foo.servicebus.windows.net;SharedAccessKeyName=dummyKey;SharedAccessKey=dummyAccessKey" - : TestUtils.getConnectionString(false); - builder.connectionString(connectionString); - } - builder.retryOptions(new RetryOptions(new FixedDelayOptions(1, TIMEOUT))); - - if (interceptorManager.isPlaybackMode()) { - builder.httpClient(interceptorManager.getPlaybackClient()); - } else if (interceptorManager.isRecordMode()) { - builder.addPolicy(interceptorManager.getRecordPolicy()); - } - - if (!interceptorManager.isLiveMode()) { - interceptorManager.addSanitizers(ServiceBusAdministrationAsyncClientIntegrationTest.TEST_PROXY_SANITIZERS); - interceptorManager.addMatchers(ServiceBusAdministrationAsyncClientIntegrationTest.TEST_PROXY_REQUEST_MATCHERS); - } - + configure(builder, null, interceptorManager, credentialCached); return builder.buildClient(); } - - /** - * Retrieve the appropriate TokenCredential based on the test mode. - * - * @param interceptorManager the interceptor manager - * @return The appropriate token credential - */ - private TokenCredential getTestTokenCredential(InterceptorManager interceptorManager) { - if (interceptorManager.isLiveMode()) { - return TestUtils.getPipelineCredential(pipelineCredential); - } else if (interceptorManager.isRecordMode()) { - return new DefaultAzureCredentialBuilder().build(); - } else { - return new MockTokenCredential(); - } - } } From 3027a4b4b384be5f4216664dd307aae746ef5ebd Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 7 Jul 2024 16:25:12 -0700 Subject: [PATCH 18/29] Remove duplicate identity test (reason: now all tests relies on identity) --- ...rviceBusSessionManagerIntegrationTest.java | 2 +- ...inistrationAsyncClientIntegrationTest.java | 125 ++++++------------ ...usAdministrationClientIntegrationTest.java | 100 ++++---------- 3 files changed, 65 insertions(+), 162 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index 5167e05bde58..cee1f85fc3d1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -194,7 +194,7 @@ private void setSender(MessagingEntityType entityType, int entityIndex) { } private void setReceiver(MessagingEntityType entityType, int entityIndex, - Function onBuild) { + Function onBuild) { ServiceBusSessionReceiverClientBuilder sessionBuilder = getSessionReceiverBuilder(entityType, entityIndex, false, DEFAULT_RETRY_OPTIONS).disableAutoComplete(); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 11be81e836d5..4c2324454fcc 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -3,8 +3,7 @@ package com.azure.messaging.servicebus.administration; -//import com.azure.core.credential.AccessToken; -//import com.azure.core.credential.AzureSasCredential; +import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.ResourceExistsException; @@ -31,7 +30,7 @@ import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; -//import com.azure.messaging.servicebus.administration.models.NamespaceProperties; +import com.azure.messaging.servicebus.administration.models.NamespaceProperties; import com.azure.messaging.servicebus.administration.models.NamespaceType; import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; import com.azure.messaging.servicebus.administration.models.RuleProperties; @@ -42,8 +41,9 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; -//import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -57,9 +57,12 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Stream; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; +import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; @@ -68,7 +71,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Tests {@link ServiceBusAdministrationAsyncClient}. @@ -107,87 +110,6 @@ public static Stream createHttpClients() { return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); } -// /** -// * Test to connect to the service bus with an azure identity TokenCredential. -// * com.azure.identity.ClientSecretCredential is used in this test. -// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below -// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. -// */ -// @ParameterizedTest -// @MethodSource("createHttpClients") -// void azureIdentityCredentials(HttpClient httpClient) { -// -// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); -// final TokenCredential tokenCredential; -// if (interceptorManager.isPlaybackMode()) { -// tokenCredential = request -> Mono.fromCallable(() -> -// new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); -// } else { -// tokenCredential = new DefaultAzureCredentialBuilder().build(); -// } -// -// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); -// -// if (interceptorManager.isPlaybackMode()) { -// builder.httpClient(interceptorManager.getPlaybackClient()); -// } else if (interceptorManager.isLiveMode()) { -// builder.httpClient(httpClient); -// } else { -// builder.httpClient(httpClient) -// .addPolicy(interceptorManager.getRecordPolicy()); -// } -// -// final ServiceBusAdministrationAsyncClient client = builder -// .credential(fullyQualifiedDomainName, tokenCredential) -// .buildAsyncClient(); -// -// StepVerifier.create(client.getNamespaceProperties()) -// .assertNext(properties -> { -// assertNotNull(properties); -// -// if (!interceptorManager.isPlaybackMode()) { -// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); -// assertEquals(split[0], properties.getName()); -// } -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } -// -// /** -// * Test to connect to the service bus with an azure sas credential. -// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below -// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. -// */ -// @Test -// void azureSasCredentialsTest() { -// // Arrange -// assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); -// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); -// -// assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), -// "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); -// -// String connectionString = getConnectionString(true); -// Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); -// Matcher matcher = sasPattern.matcher(connectionString); -// assertTrue(matcher.find(), "Couldn't find SAS from connection string"); -// -// ServiceBusAdministrationAsyncClient client = new ServiceBusAdministrationClientBuilder() -// .endpoint("https://" + fullyQualifiedDomainName) -// .credential(new AzureSasCredential(matcher.group(1))) -// .buildAsyncClient(); -// -// // Act & Assert -// StepVerifier.create(client.getNamespacePropertiesWithResponse()) -// .assertNext(response -> { -// final NamespaceProperties np = response.getValue(); -// assertNotNull(np.getName()); -// }) -// .expectComplete() -// .verify(DEFAULT_TIMEOUT); -// } - //region Create tests @ParameterizedTest @@ -1214,6 +1136,35 @@ void updateRuleResponse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } + @Test + @Disabled("Decide if this test can be removed since live tests are no longer connection string based.") + void azureSasCredentialsTest() { + // Arrange + assumeTrue(interceptorManager.isLiveMode(), "skipping azure Sas Credentials test"); + assumeTrue(!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false)), "Connection string is not configured."); + + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + + String connectionString = getConnectionString(true); + Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); + Matcher matcher = sasPattern.matcher(connectionString); + assertTrue(matcher.find(), "Couldn't find SAS from connection string"); + + ServiceBusAdministrationAsyncClient client = new ServiceBusAdministrationClientBuilder() + .endpoint("https://" + fullyQualifiedDomainName) + .credential(new AzureSasCredential(matcher.group(1))) + .buildAsyncClient(); + + // Act & Assert + StepVerifier.create(client.getNamespacePropertiesWithResponse()) + .assertNext(response -> { + final NamespaceProperties np = response.getValue(); + assertNotNull(np.getName()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)); @@ -1224,7 +1175,7 @@ private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) static void configure(ServiceBusAdministrationClientBuilder builder, HttpClient httpClient, InterceptorManager interceptorManager, AtomicReference credentialCached) { if (interceptorManager.isPlaybackMode()) { - builder.credential(new MockTokenCredential()); + builder.credential(TestUtils.getFullyQualifiedDomainName(), new MockTokenCredential()); builder.httpClient(interceptorManager.getPlaybackClient()); } else if (interceptorManager.isLiveMode()) { final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index 942321c7b672..b23a1e5461d1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -3,8 +3,7 @@ package com.azure.messaging.servicebus.administration; -//import com.azure.core.credential.AccessToken; -//import com.azure.core.credential.AzureSasCredential; +import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.ResourceExistsException; @@ -15,6 +14,7 @@ import com.azure.core.http.rest.Response; import com.azure.core.test.TestProxyTestBase; import com.azure.core.util.Context; +import com.azure.core.util.CoreUtils; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; @@ -37,11 +37,11 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -//import reactor.core.publisher.Mono; import java.time.Clock; import java.time.Duration; @@ -50,11 +50,10 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; -//import java.util.regex.Matcher; -//import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; -//import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getQueueBaseName; import static com.azure.messaging.servicebus.TestUtils.getRuleBaseName; @@ -67,7 +66,7 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -//import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Tests {@link ServiceBusAdministrationClient}. @@ -78,73 +77,6 @@ public class ServiceBusAdministrationClientIntegrationTest extends TestProxyTest private static final Duration TIMEOUT = Duration.ofSeconds(20); private final AtomicReference credentialCached = new AtomicReference<>(); -// /** -// * Test to connect to the service bus with an azure identity TokenCredential. -// * com.azure.identity.ClientSecretCredential is used in this test. -// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below -// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. -// */ -// @Test -// void azureIdentityCredentials() { -// // Arrange -// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); -// final TokenCredential tokenCredential; -// if (interceptorManager.isPlaybackMode()) { -// tokenCredential = request -> Mono.fromCallable(() -> -// new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); -// } else { -// tokenCredential = new DefaultAzureCredentialBuilder().build(); -// } -// -// final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); -// -// if (interceptorManager.isPlaybackMode()) { -// builder.httpClient(interceptorManager.getPlaybackClient()); -// } else if (interceptorManager.isRecordMode()) { -// builder.addPolicy(interceptorManager.getRecordPolicy()); -// } -// -// final ServiceBusAdministrationClient client = builder -// .credential(fullyQualifiedDomainName, tokenCredential) -// .buildClient(); -// -// // Act -// NamespaceProperties properties = client.getNamespaceProperties(); -// -// // Assert -// assertNotNull(properties); -// -// if (!interceptorManager.isPlaybackMode()) { -// final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); -// assertEquals(split[0], properties.getName()); -// } -// } - -// /** -// * Test to connect to the service bus with an azure sas credential. -// * ServiceBusSharedKeyCredential doesn't need a specific test method because other tests below -// * use connection string, which is converted to a ServiceBusSharedKeyCredential internally. -// */ -// @Test -// void azureSasCredentialsTest() { -// assumeTrue(interceptorManager.isLiveMode(), "Azure Identity test is for live test only"); -// final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); -// -// assumeTrue(fullyQualifiedDomainName != null && !fullyQualifiedDomainName.isEmpty(), -// "AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set when using credentials."); -// -// String connectionString = getConnectionString(true); -// Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); -// Matcher matcher = sasPattern.matcher(connectionString); -// assertTrue(matcher.find(), "Couldn't find SAS from connection string"); -// ServiceBusAdministrationClient client = new ServiceBusAdministrationClientBuilder() -// .endpoint("https://" + fullyQualifiedDomainName) -// .credential(new AzureSasCredential(matcher.group(1))) -// .buildClient(); -// NamespaceProperties np = client.getNamespaceProperties(); -// assertNotNull(np.getName()); -// } - //region Create tests @Test @@ -928,6 +860,26 @@ void listRules() { assertTrue(rule.getAction() instanceof EmptyRuleAction); } + @Test + @Disabled("Decide if this test can be removed since live tests are no longer connection string based.") + void azureSasCredentialsTest() { + assumeTrue(interceptorManager.isLiveMode(), "skipping azure Sas Credentials test"); + assumeTrue(!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false)), "Connection string is not configured."); + + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + String connectionString = TestUtils.getConnectionString(true); + Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); + Matcher matcher = sasPattern.matcher(connectionString); + assertTrue(matcher.find(), "Couldn't find SAS from connection string"); + + ServiceBusAdministrationClient client = new ServiceBusAdministrationClientBuilder() + .endpoint("https://" + fullyQualifiedDomainName) + .credential(new AzureSasCredential(matcher.group(1))) + .buildClient(); + NamespaceProperties np = client.getNamespaceProperties(); + assertNotNull(np.getName()); + } + //endregion private ServiceBusAdministrationClient getClient() { From de3468d90c1d25893cc8461c05c8528aba20a2ad Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 7 Jul 2024 16:35:06 -0700 Subject: [PATCH 19/29] nits: spaces, newlines.. --- .../ServiceBusReceiverAsyncClientIntegrationTest.java | 2 +- .../servicebus/ServiceBusReceiverClientIntegrationTest.java | 1 - .../servicebus/ServiceBusSenderAsyncClientIntegrationTest.java | 1 - .../servicebus/ServiceBusSenderClientIntegrationTest.java | 1 - .../servicebus/ServiceBusSessionManagerIntegrationTest.java | 1 - 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index 1e54aba7183f..f142c7d7f147 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -1518,7 +1518,7 @@ private Mono sendMessage(ServiceBusMessage message) { logMessage(message, sender.getEntityPath(), "sent"); }); } -// + /** * Class represents various options while creating receiver/sender client. */ diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java index 6d9ed2c3d089..3cee975edcae 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus; - import com.azure.core.amqp.models.AmqpMessageBody; import com.azure.core.util.IterableStream; import com.azure.core.util.logging.ClientLogger; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java index b835ec486fb6..1170b459b85d 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderAsyncClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus; - import com.azure.core.util.logging.ClientLogger; import com.azure.core.util.logging.LogLevel; import com.azure.messaging.servicebus.implementation.MessagingEntityType; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java index 6ca8c647a87b..640681837bb9 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSenderClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus; - import com.azure.core.util.logging.ClientLogger; import com.azure.messaging.servicebus.implementation.MessagingEntityType; import com.azure.messaging.servicebus.models.CreateMessageBatchOptions; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java index cee1f85fc3d1..a62a2cfa41c8 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusSessionManagerIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus; - import com.azure.core.amqp.AmqpRetryOptions; import com.azure.core.util.CoreUtils; import com.azure.core.util.logging.ClientLogger; From 92b9b82d6df3d3523883d360e959adc57adf51c9 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Sun, 7 Jul 2024 19:25:15 -0700 Subject: [PATCH 20/29] isolate non-fed tests --- .../servicebus/IntegrationTestBase.java | 54 ++++--- .../ServiceBusClientBuilderTest.java | 56 -------- ...ServiceBusNonFederatedIntegrationTest.java | 133 ++++++++++++++++++ .../azure/messaging/servicebus/TestUtils.java | 13 +- ...inistrationAsyncClientIntegrationTest.java | 42 +----- ...usAdministrationClientIntegrationTest.java | 26 ---- 6 files changed, 177 insertions(+), 147 deletions(-) create mode 100644 sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 3d1e6dfcab16..ec59701a8bb4 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -92,7 +92,7 @@ public void setupTest(TestContextManager testContextManager) { logger.info("========= SET-UP [{}] =========", testName); - assumeTrue(getTestMode() == TestMode.RECORD); + assertRunnable(); toClose = new ArrayList<>(); optionsWithTracing = new ClientOptions().setTracingOptions(new LoggingTracerProvider.LoggingTracingOptions()); @@ -110,21 +110,6 @@ public void teardownTest() { dispose(); } - /** - * Gets the test mode for this API test. If AZURE_TEST_MODE equals {@link TestMode#RECORD} and Event Hubs connection - * string is set, then we return {@link TestMode#RECORD}. Otherwise, {@link TestMode#PLAYBACK} is returned. - */ - @Override - public TestMode getTestMode() { - if (super.getTestMode() == TestMode.PLAYBACK) { - return TestMode.PLAYBACK; - } - - return TestMode.RECORD; - // TODO (anu): alternative for this approach? - // return CoreUtils.isNullOrEmpty(getConnectionString()) ? TestMode.PLAYBACK : TestMode.RECORD; - } - /** * Gets the name of the queue. * @@ -198,13 +183,15 @@ protected ServiceBusClientBuilder getAuthenticatedBuilder() { final TestMode mode = super.getTestMode(); final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); if (mode == TestMode.LIVE) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = TestUtils.getPipelineCredential(credentialCached); return builder.credential(fullyQualifiedDomainName, credential); } else if (mode == TestMode.RECORD) { final String connectionString = TestUtils.getConnectionString(false); if (CoreUtils.isNullOrEmpty(connectionString)) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); return builder.credential(fullyQualifiedDomainName, credential); } else { @@ -474,4 +461,35 @@ protected final Configuration v1OrV2(boolean isV2) { return new ConfigurationBuilder(configSource) .build(); } + + /** + * Asserts that if the integration tests can be run. This method is expected to be called at the beginning of each + * test run. + * + * @throws TestAbortedException if the integration tests cannot be run. + */ + protected void assertRunnable() { + final TestMode mode = super.getTestMode(); + if (mode == TestMode.PLAYBACK) { + throw new TestAbortedException("Skipping integration tests in playback mode."); + } + + if (mode == TestMode.RECORD) { + if (!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false))) { + // integration tests are runnable using the connection string. + return; + } + if (!CoreUtils.isNullOrEmpty(TestUtils.getFullyQualifiedDomainName())) { + // best effort check: + // integration tests are potentially runnable using DefaultAzureCredential. Here we're assuming that + // in RECORD mode with FullyQualifiedDomainName set, the dev environment is also set up for one of the + // token credential type in DefaultAzureCredential (all token credentials requires FullyQualifiedDomainName). + return; + } + throw new TestAbortedException("Not running integration in record mode (missing authentication set up)."); + } + assert mode == TestMode.LIVE; + // tests are runnable in pipeline with federated identity. + return; + } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java index 813a493f28a1..f470a7155f84 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusClientBuilderTest.java @@ -6,7 +6,6 @@ import com.azure.core.amqp.AmqpTransportType; import com.azure.core.amqp.ProxyAuthenticationType; import com.azure.core.amqp.ProxyOptions; -import com.azure.core.amqp.implementation.ConnectionStringProperties; import com.azure.core.credential.AzureNamedKeyCredential; import com.azure.core.credential.AzureSasCredential; import com.azure.core.util.Configuration; @@ -17,12 +16,10 @@ import com.azure.messaging.servicebus.models.ServiceBusReceiveMode; import com.azure.messaging.servicebus.models.SubQueue; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import reactor.test.StepVerifier; import java.net.InetSocketAddress; import java.net.Proxy; @@ -35,8 +32,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static java.nio.charset.StandardCharsets.UTF_8; - class ServiceBusClientBuilderTest extends IntegrationTestBase { private static final String NAMESPACE_NAME = "dummyNamespaceName"; private static final String DEFAULT_DOMAIN_NAME = TestUtils.getEndpoint().substring(1) + "/"; @@ -267,57 +262,6 @@ public void testConnectionStringWithSas() { .connectionString("Endpoint=sb://sb-name" + TestUtils.getEndpoint() + "/;EntityPath=sb-name")); } - @Test - @Disabled("Convert to use AzurePowerShellCredentials?") - public void testBatchSendEventByAzureNameKeyCredential() { - ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(false)); - String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); - String sharedAccessKeyName = properties.getSharedAccessKeyName(); - String sharedAccessKey = properties.getSharedAccessKey(); - String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); - - final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); - - ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey)) - .sender() - .queueName(queueName) - .buildAsyncClient()); - StepVerifier.create( - senderAsyncClient.createMessageBatch().flatMap(batch -> { - assertTrue(batch.tryAddMessage(testData)); - return senderAsyncClient.sendMessages(batch); - })) - .expectComplete() - .verify(TIMEOUT); - } - - @Test - @Disabled("Convert to use AzurePowerShellCredentials?") - public void testBatchSendEventByAzureSasCredential() { - ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(true)); - String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); - String sharedAccessSignature = properties.getSharedAccessSignature(); - String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); - - final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); - - ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() - .credential(fullyQualifiedNamespace, - new AzureSasCredential(sharedAccessSignature)) - .sender() - .queueName(queueName) - .buildAsyncClient()); - - StepVerifier.create( - senderAsyncClient.createMessageBatch().flatMap(batch -> { - assertTrue(batch.tryAddMessage(testData)); - return senderAsyncClient.sendMessages(batch); - })) - .expectComplete() - .verify(TIMEOUT); - } - @Test public void testConnectionWithAzureNameKeyCredential() { String fullyQualifiedNamespace = "sb-name" + TestUtils.getEndpoint(); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java new file mode 100644 index 000000000000..20726f14b493 --- /dev/null +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +package com.azure.messaging.servicebus; + +import com.azure.core.amqp.implementation.ConnectionStringProperties; +import com.azure.core.credential.AzureNamedKeyCredential; +import com.azure.core.credential.AzureSasCredential; +import com.azure.core.test.TestMode; +import com.azure.core.util.CoreUtils; +import com.azure.core.util.logging.ClientLogger; +import com.azure.messaging.servicebus.administration.ServiceBusAdministrationAsyncClient; +import com.azure.messaging.servicebus.administration.ServiceBusAdministrationClientBuilder; +import com.azure.messaging.servicebus.administration.models.NamespaceProperties; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.opentest4j.TestAbortedException; +import reactor.test.StepVerifier; + +import java.time.Duration; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.azure.messaging.servicebus.TestUtils.getConnectionString; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +/** + * Live tests with non-federated authentication. + */ +@Tag("integration") +@Execution(ExecutionMode.SAME_THREAD) +public class ServiceBusNonFederatedIntegrationTest extends IntegrationTestBase { + private static final ClientLogger LOGGER = new ClientLogger(ServiceBusNonFederatedIntegrationTest.class); + private static final Duration TIMEOUT = Duration.ofSeconds(20); + private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); + private static final String TEST_MESSAGE = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \nUt sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \nAenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \nAenean fringilla quam elit, id mattis purus vestibulum nec. Praesent porta eros in dapibus molestie. Vestibulum orci libero, tincidunt et turpis eget, condimentum lobortis enim. Fusce suscipit ante et mauris consequat cursus nec laoreet lorem. Maecenas in sollicitudin diam, non tincidunt purus. Nunc mauris purus, laoreet eget interdum vitae, placerat a sapien. In mi risus, blandit eu facilisis nec, molestie suscipit leo. Pellentesque molestie urna vitae dui faucibus bibendum. \nDonec quis ipsum ultricies, imperdiet ex vel, scelerisque eros. Ut at urna arcu. Vestibulum rutrum odio dolor, vitae cursus nunc pulvinar vel. Donec accumsan sapien in malesuada tempor. Maecenas in condimentum eros. Sed vestibulum facilisis massa a iaculis. Etiam et nibh felis. Donec maximus, sem quis vestibulum gravida, turpis risus congue dolor, pharetra tincidunt lectus nisi at velit."; + + public ServiceBusNonFederatedIntegrationTest() { + super(LOGGER); + } + + @Test + public void testBatchSendEventByAzureNameKeyCredential() { + ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(false)); + String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); + String sharedAccessKeyName = properties.getSharedAccessKeyName(); + String sharedAccessKey = properties.getSharedAccessKey(); + String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); + + final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); + + ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, new AzureNamedKeyCredential(sharedAccessKeyName, sharedAccessKey)) + .sender() + .queueName(queueName) + .buildAsyncClient()); + StepVerifier.create( + senderAsyncClient.createMessageBatch().flatMap(batch -> { + assertTrue(batch.tryAddMessage(testData)); + return senderAsyncClient.sendMessages(batch); + })) + .expectComplete() + .verify(TIMEOUT); + } + + @Test + public void testBatchSendEventByAzureSasCredential() { + ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(true)); + String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); + String sharedAccessSignature = properties.getSharedAccessSignature(); + String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); + + final ServiceBusMessage testData = new ServiceBusMessage(TEST_MESSAGE.getBytes(UTF_8)); + + ServiceBusSenderAsyncClient senderAsyncClient = toClose(new ServiceBusClientBuilder() + .credential(fullyQualifiedNamespace, + new AzureSasCredential(sharedAccessSignature)) + .sender() + .queueName(queueName) + .buildAsyncClient()); + + StepVerifier.create( + senderAsyncClient.createMessageBatch().flatMap(batch -> { + assertTrue(batch.tryAddMessage(testData)); + return senderAsyncClient.sendMessages(batch); + })) + .expectComplete() + .verify(TIMEOUT); + } + + @Test + void azureSasCredentialsTest() { + final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); + String connectionString = getConnectionString(true); + Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); + Matcher matcher = sasPattern.matcher(connectionString); + assertTrue(matcher.find(), "Couldn't find SAS from connection string"); + + ServiceBusAdministrationAsyncClient client = new ServiceBusAdministrationClientBuilder() + .endpoint("https://" + fullyQualifiedDomainName) + .credential(new AzureSasCredential(matcher.group(1))) + .buildAsyncClient(); + + StepVerifier.create(client.getNamespacePropertiesWithResponse()) + .assertNext(response -> { + final NamespaceProperties np = response.getValue(); + assertNotNull(np.getName()); + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + + @Override + protected void assertRunnable() { + final TestMode mode = super.getTestMode(); + if (mode == TestMode.PLAYBACK) { + throw new TestAbortedException("Skipping integration tests in playback mode."); + } + + if (mode == TestMode.RECORD || mode == TestMode.LIVE) { + if (!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false))) { + // non-federated integration tests are runnable using the connection string. + return; + } + } + throw new TestAbortedException("Not running integration in record mode (missing authentication set up)."); + } +} diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java index e4f0ae34eb51..ade740763967 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java @@ -165,7 +165,7 @@ public static String getConnectionString(boolean withSas) { /** * Gets the fully qualified domain name for the service bus resource. * - * @return The fully qualified domain name for the service bus resource. + * @return The fully qualified domain name for the service bus resource if set else a redacted dummy name. */ public static String getFullyQualifiedDomainName() { return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME", "REDACTED.servicebus.windows.net"); @@ -174,15 +174,10 @@ public static String getFullyQualifiedDomainName() { /** * Gets the fully qualified domain name for the service bus resource. * - * @return the fully qualified domain name for the service bus resource. - * @throws org.opentest4j.TestAbortedException if the environment variable is not set. + * @return the fully qualified domain name for the service bus resource if set, {@code null} otherwise. */ - public static String getFullyQualifiedDomainNameWithAssertion() { - final String fullyQualifiedDomainName = getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME"); - if (CoreUtils.isNullOrEmpty(fullyQualifiedDomainName)) { - throw new TestAbortedException("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME variable needs to be set."); - } - return fullyQualifiedDomainName; + public static String getLiveFullyQualifiedDomainName() { + return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME"); } public static String getEndpoint() { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 4c2324454fcc..5bfe69a52976 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus.administration; -import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.ResourceExistsException; @@ -30,7 +29,6 @@ import com.azure.messaging.servicebus.administration.models.CreateTopicOptions; import com.azure.messaging.servicebus.administration.models.EmptyRuleAction; import com.azure.messaging.servicebus.administration.models.FalseRuleFilter; -import com.azure.messaging.servicebus.administration.models.NamespaceProperties; import com.azure.messaging.servicebus.administration.models.NamespaceType; import com.azure.messaging.servicebus.administration.models.QueueRuntimeProperties; import com.azure.messaging.servicebus.administration.models.RuleProperties; @@ -41,9 +39,7 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -57,12 +53,9 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Stream; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; -import static com.azure.messaging.servicebus.TestUtils.getConnectionString; import static com.azure.messaging.servicebus.TestUtils.getEntityName; import static com.azure.messaging.servicebus.TestUtils.getSessionSubscriptionBaseName; import static com.azure.messaging.servicebus.TestUtils.getSubscriptionBaseName; @@ -1136,35 +1129,6 @@ void updateRuleResponse(HttpClient httpClient) { .verify(DEFAULT_TIMEOUT); } - @Test - @Disabled("Decide if this test can be removed since live tests are no longer connection string based.") - void azureSasCredentialsTest() { - // Arrange - assumeTrue(interceptorManager.isLiveMode(), "skipping azure Sas Credentials test"); - assumeTrue(!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false)), "Connection string is not configured."); - - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); - - String connectionString = getConnectionString(true); - Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); - Matcher matcher = sasPattern.matcher(connectionString); - assertTrue(matcher.find(), "Couldn't find SAS from connection string"); - - ServiceBusAdministrationAsyncClient client = new ServiceBusAdministrationClientBuilder() - .endpoint("https://" + fullyQualifiedDomainName) - .credential(new AzureSasCredential(matcher.group(1))) - .buildAsyncClient(); - - // Act & Assert - StepVerifier.create(client.getNamespacePropertiesWithResponse()) - .assertNext(response -> { - final NamespaceProperties np = response.getValue(); - assertNotNull(np.getName()); - }) - .expectComplete() - .verify(DEFAULT_TIMEOUT); - } - private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) { final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder() .httpLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BODY_AND_HEADERS)); @@ -1178,7 +1142,8 @@ static void configure(ServiceBusAdministrationClientBuilder builder, builder.credential(TestUtils.getFullyQualifiedDomainName(), new MockTokenCredential()); builder.httpClient(interceptorManager.getPlaybackClient()); } else if (interceptorManager.isLiveMode()) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = TestUtils.getPipelineCredential(credentialCached); builder.credential(fullyQualifiedDomainName, credential); if (httpClient != null) { @@ -1188,7 +1153,8 @@ static void configure(ServiceBusAdministrationClientBuilder builder, // Record Mode. final String connectionString = TestUtils.getConnectionString(false); if (CoreUtils.isNullOrEmpty(connectionString)) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); + final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); builder.credential(fullyQualifiedDomainName, credential); } else { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index b23a1e5461d1..e56965461458 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -3,7 +3,6 @@ package com.azure.messaging.servicebus.administration; -import com.azure.core.credential.AzureSasCredential; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.ResourceExistsException; @@ -14,7 +13,6 @@ import com.azure.core.http.rest.Response; import com.azure.core.test.TestProxyTestBase; import com.azure.core.util.Context; -import com.azure.core.util.CoreUtils; import com.azure.messaging.servicebus.TestUtils; import com.azure.messaging.servicebus.administration.models.AccessRights; import com.azure.messaging.servicebus.administration.models.CreateQueueOptions; @@ -37,7 +35,6 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; @@ -50,8 +47,6 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import static com.azure.messaging.servicebus.TestUtils.assertAuthorizationRules; import static com.azure.messaging.servicebus.TestUtils.getEntityName; @@ -66,7 +61,6 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * Tests {@link ServiceBusAdministrationClient}. @@ -860,26 +854,6 @@ void listRules() { assertTrue(rule.getAction() instanceof EmptyRuleAction); } - @Test - @Disabled("Decide if this test can be removed since live tests are no longer connection string based.") - void azureSasCredentialsTest() { - assumeTrue(interceptorManager.isLiveMode(), "skipping azure Sas Credentials test"); - assumeTrue(!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false)), "Connection string is not configured."); - - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainNameWithAssertion(); - String connectionString = TestUtils.getConnectionString(true); - Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); - Matcher matcher = sasPattern.matcher(connectionString); - assertTrue(matcher.find(), "Couldn't find SAS from connection string"); - - ServiceBusAdministrationClient client = new ServiceBusAdministrationClientBuilder() - .endpoint("https://" + fullyQualifiedDomainName) - .credential(new AzureSasCredential(matcher.group(1))) - .buildClient(); - NamespaceProperties np = client.getNamespaceProperties(); - assertNotNull(np.getName()); - } - //endregion private ServiceBusAdministrationClient getClient() { From 9f75af71bf96a8b854d17549daaf9ed1fd2b1c19 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 09:45:14 -0700 Subject: [PATCH 21/29] doc, enable peek test --- .../com/azure/messaging/servicebus/IntegrationTestBase.java | 5 +++-- .../ServiceBusReceiverAsyncClientIntegrationTest.java | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index ec59701a8bb4..c1baef77e8a6 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -471,10 +471,12 @@ protected final Configuration v1OrV2(boolean isV2) { protected void assertRunnable() { final TestMode mode = super.getTestMode(); if (mode == TestMode.PLAYBACK) { + // AMQP traffic never gets recorded so there is no PLAYBACK supported. throw new TestAbortedException("Skipping integration tests in playback mode."); } if (mode == TestMode.RECORD) { + // RECORD mode used in SDK-dev setup not on CI pipeline. if (!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false))) { // integration tests are runnable using the connection string. return; @@ -488,8 +490,7 @@ protected void assertRunnable() { } throw new TestAbortedException("Not running integration in record mode (missing authentication set up)."); } + // The CI pipeline is expected to have federated identity configured, so tests are runnable. assert mode == TestMode.LIVE; - // tests are runnable in pipeline with federated identity. - return; } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java index f142c7d7f147..4f91b2cf234f 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusReceiverAsyncClientIntegrationTest.java @@ -364,7 +364,6 @@ void receiveMessageAutoComplete(MessagingEntityType entityType, boolean isSessio */ @MethodSource("com.azure.messaging.servicebus.IntegrationTestBase#messagingEntityWithSessions") @ParameterizedTest - @Disabled("Investigate: Could not emit tick 0 due to lack of requests (interval doesn't support small downstream requests that replenish slower than the ticks)))") void peekMessage(MessagingEntityType entityType, boolean isSessionEnabled) { // Arrange setSender(entityType, USE_CASE_PEEK_MESSAGE, isSessionEnabled); From 377e667d3655efac2dcbf23e73afbab991d0f280 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 10:45:05 -0700 Subject: [PATCH 22/29] doc update, remove connection string output from arm test-resource.json --- .../servicebus/ServiceBusNonFederatedIntegrationTest.java | 2 ++ sdk/servicebus/test-resources.json | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java index 20726f14b493..52fcac2133d0 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java @@ -119,10 +119,12 @@ void azureSasCredentialsTest() { protected void assertRunnable() { final TestMode mode = super.getTestMode(); if (mode == TestMode.PLAYBACK) { + // AMQP traffic never gets recorded so there is no PLAYBACK supported. throw new TestAbortedException("Skipping integration tests in playback mode."); } if (mode == TestMode.RECORD || mode == TestMode.LIVE) { + // RECORD mode used in SDK-dev setup and LIVE mode on CI pipeline. if (!CoreUtils.isNullOrEmpty(TestUtils.getConnectionString(false))) { // non-federated integration tests are runnable using the connection string. return; diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index 717792dfa590..f1c431092f44 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -201,10 +201,6 @@ "type": "string", "value": "[concat(variables('namespaceName'), parameters('serviceBusEndpointSuffix'))]" }, - "AZURE_SERVICEBUS_NAMESPACE_CONNECTION_STRING": { - "type": "string", - "value": "[listkeys(variables('authRuleResourceId'), '2021-01-01-preview').primaryConnectionString]" - }, "AZURE_SERVICEBUS_QUEUE_NAME": { "type": "string", "value": "[variables('queueName')]" From 26a2288eb36eeeb5607e5de01a854f373687551b Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 12:18:49 -0700 Subject: [PATCH 23/29] output connection string so ServiceBusNonFederatedIntegrationTest can run for now --- sdk/servicebus/test-resources.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index f1c431092f44..717792dfa590 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -201,6 +201,10 @@ "type": "string", "value": "[concat(variables('namespaceName'), parameters('serviceBusEndpointSuffix'))]" }, + "AZURE_SERVICEBUS_NAMESPACE_CONNECTION_STRING": { + "type": "string", + "value": "[listkeys(variables('authRuleResourceId'), '2021-01-01-preview').primaryConnectionString]" + }, "AZURE_SERVICEBUS_QUEUE_NAME": { "type": "string", "value": "[variables('queueName')]" From 3dd4402ac8eaf52478fda0c55dbd2e76d112cfe7 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 12:22:20 -0700 Subject: [PATCH 24/29] keep the client cred special test --- ...inistrationAsyncClientIntegrationTest.java | 43 +++++++++++++++++++ sdk/servicebus/tests.yml | 4 ++ 2 files changed, 47 insertions(+) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 5bfe69a52976..6ac3f0d1d600 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -3,6 +3,7 @@ package com.azure.messaging.servicebus.administration; +import com.azure.core.credential.AccessToken; import com.azure.core.credential.TokenCredential; import com.azure.core.exception.ClientAuthenticationException; import com.azure.core.exception.ResourceExistsException; @@ -103,6 +104,48 @@ public static Stream createHttpClients() { return Stream.of(Arguments.of(new NettyAsyncHttpClientBuilder().build())); } + /** + * Test to connect to the service bus using com.azure.identity.ClientSecretCredential. + */ + @ParameterizedTest + @MethodSource("createHttpClients") + void azureClientSecretCredential(HttpClient httpClient) { + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + final TokenCredential tokenCredential; + if (interceptorManager.isPlaybackMode()) { + tokenCredential = request -> Mono.fromCallable(() -> + new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); + } else { + // Uses ClientSecretCredential specific EnvVars exported in ..\..\..\..\..\..\test.yml + tokenCredential = new DefaultAzureCredentialBuilder().build(); + } + + final ServiceBusAdministrationClientBuilder builder = new ServiceBusAdministrationClientBuilder(); + + if (interceptorManager.isPlaybackMode()) { + builder.httpClient(interceptorManager.getPlaybackClient()); + } else if (interceptorManager.isLiveMode()) { + builder.httpClient(httpClient); + } else { + builder.httpClient(httpClient).addPolicy(interceptorManager.getRecordPolicy()); + } + + final ServiceBusAdministrationAsyncClient client = builder + .credential(fullyQualifiedDomainName, tokenCredential) + .buildAsyncClient(); + + StepVerifier.create(client.getNamespaceProperties()) + .assertNext(properties -> { + assertNotNull(properties); + if (!interceptorManager.isPlaybackMode()) { + final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); + assertEquals(split[0], properties.getName()); + } + }) + .expectComplete() + .verify(DEFAULT_TIMEOUT); + } + //region Create tests @ParameterizedTest diff --git a/sdk/servicebus/tests.yml b/sdk/servicebus/tests.yml index 9be1da120763..74e5e7b206e7 100644 --- a/sdk/servicebus/tests.yml +++ b/sdk/servicebus/tests.yml @@ -16,6 +16,10 @@ extends: SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources) EnvVars: AZURE_LOG_LEVEL: 1 + AZURE_CLIENT_ID: $(SERVICEBUS_CLIENT_ID) + AZURE_TENANT_ID: $(SERVICEBUS_TENANT_ID) + AZURE_CLIENT_SECRET: $(SERVICEBUS_CLIENT_SECRET) + AZURE_SUBSCRIPTION_ID: $(SERVICEBUS_SUBSCRIPTION_ID) AdditionalMatrixConfigs: - Name: version_overrides_tests Path: sdk/servicebus/version-overrides-matrix.json From c43eaed8c7a6eb7b2c58ce6cb5d6a3e6f71e2932 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 13:25:47 -0700 Subject: [PATCH 25/29] MI co-exists with old key cred? --- ...iceBusAdministrationAsyncClientIntegrationTest.java | 3 ++- sdk/servicebus/test-resources.json | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 6ac3f0d1d600..df7766239125 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -40,6 +40,7 @@ import com.azure.messaging.servicebus.administration.models.TopicProperties; import com.azure.messaging.servicebus.administration.models.TopicRuntimeProperties; import com.azure.messaging.servicebus.administration.models.TrueRuleFilter; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -109,6 +110,7 @@ public static Stream createHttpClients() { */ @ParameterizedTest @MethodSource("createHttpClients") + // @Disabled("With pipeline enabled for federated managed identity, the test needing secret won't work anymore - com.microsoft.aad.msal4j.MsalServiceException: AADSTS7000215: Invalid client secret provided") void azureClientSecretCredential(HttpClient httpClient) { final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); final TokenCredential tokenCredential; @@ -116,7 +118,6 @@ void azureClientSecretCredential(HttpClient httpClient) { tokenCredential = request -> Mono.fromCallable(() -> new AccessToken("foo-bar", OffsetDateTime.now().plus(Duration.ofMinutes(5)))); } else { - // Uses ClientSecretCredential specific EnvVars exported in ..\..\..\..\..\..\test.yml tokenCredential = new DefaultAzureCredentialBuilder().build(); } diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index 717792dfa590..c7bce0c652d7 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -35,6 +35,12 @@ "description": "The application client id used to run tests." } }, + "testApplicationSecret": { + "type": "string", + "metadata": { + "description": "The application client secret used to run tests." + } + }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", @@ -201,6 +207,10 @@ "type": "string", "value": "[concat(variables('namespaceName'), parameters('serviceBusEndpointSuffix'))]" }, + "AZURE_CLIENT_SECRET": { + "type": "string", + "value": "[parameters('testApplicationSecret')]" + }, "AZURE_SERVICEBUS_NAMESPACE_CONNECTION_STRING": { "type": "string", "value": "[listkeys(variables('authRuleResourceId'), '2021-01-01-preview').primaryConnectionString]" From 9b7bf1c0bf588e303ce8df8813c17edae6001f49 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 13:47:49 -0700 Subject: [PATCH 26/29] exlcude the test requiring aux tenant --- ...iceBusAdministrationAsyncClientIntegrationTest.java | 9 ++++++++- sdk/servicebus/test-resources.json | 10 ---------- sdk/servicebus/tests.yml | 4 ---- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index df7766239125..06c4be8ef9c9 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -107,10 +107,17 @@ public static Stream createHttpClients() { /** * Test to connect to the service bus using com.azure.identity.ClientSecretCredential. + *

+ * This is a potential test eligible to run in auxiliary tenant with secret auth. The CI Pipeline cannot be enabled + * for both Federated Managed Identity auth and Secret auth, the ARM deployment will fail if an attempt is made to + * enable two auth types - Exception calling "Invoke" with "0" argument(s): "Cannot process command because of one or + * more missing mandatory parameters: testApplicationSecret.". Hence, this test is disabled until auxiliary tenant is + * available. + *

*/ @ParameterizedTest @MethodSource("createHttpClients") - // @Disabled("With pipeline enabled for federated managed identity, the test needing secret won't work anymore - com.microsoft.aad.msal4j.MsalServiceException: AADSTS7000215: Invalid client secret provided") + @Disabled("The CI Pipeline cannot be enabled for both Federated Managed Identity auth and Secret auth") void azureClientSecretCredential(HttpClient httpClient) { final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); final TokenCredential tokenCredential; diff --git a/sdk/servicebus/test-resources.json b/sdk/servicebus/test-resources.json index c7bce0c652d7..717792dfa590 100644 --- a/sdk/servicebus/test-resources.json +++ b/sdk/servicebus/test-resources.json @@ -35,12 +35,6 @@ "description": "The application client id used to run tests." } }, - "testApplicationSecret": { - "type": "string", - "metadata": { - "description": "The application client secret used to run tests." - } - }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", @@ -207,10 +201,6 @@ "type": "string", "value": "[concat(variables('namespaceName'), parameters('serviceBusEndpointSuffix'))]" }, - "AZURE_CLIENT_SECRET": { - "type": "string", - "value": "[parameters('testApplicationSecret')]" - }, "AZURE_SERVICEBUS_NAMESPACE_CONNECTION_STRING": { "type": "string", "value": "[listkeys(variables('authRuleResourceId'), '2021-01-01-preview').primaryConnectionString]" diff --git a/sdk/servicebus/tests.yml b/sdk/servicebus/tests.yml index 74e5e7b206e7..9be1da120763 100644 --- a/sdk/servicebus/tests.yml +++ b/sdk/servicebus/tests.yml @@ -16,10 +16,6 @@ extends: SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources) EnvVars: AZURE_LOG_LEVEL: 1 - AZURE_CLIENT_ID: $(SERVICEBUS_CLIENT_ID) - AZURE_TENANT_ID: $(SERVICEBUS_TENANT_ID) - AZURE_CLIENT_SECRET: $(SERVICEBUS_CLIENT_SECRET) - AZURE_SUBSCRIPTION_ID: $(SERVICEBUS_SUBSCRIPTION_ID) AdditionalMatrixConfigs: - Name: version_overrides_tests Path: sdk/servicebus/version-overrides-matrix.json From c31d299a3040ab305d95a589ada999f8cf4403d4 Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 15:32:37 -0700 Subject: [PATCH 27/29] add useFallbackValue flag to TestUtils::getFullyQualifiedDomainName method --- .../servicebus/IntegrationTestBase.java | 6 +++--- ...ServiceBusNonFederatedIntegrationTest.java | 6 +++--- .../azure/messaging/servicebus/TestUtils.java | 19 ++++++++----------- .../servicebus/TracingIntegrationTests.java | 6 +++--- ...inistrationAsyncClientIntegrationTest.java | 12 ++++++------ ...usAdministrationClientIntegrationTest.java | 2 +- 6 files changed, 24 insertions(+), 27 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index c1baef77e8a6..208e9d231554 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -183,14 +183,14 @@ protected ServiceBusClientBuilder getAuthenticatedBuilder() { final TestMode mode = super.getTestMode(); final ServiceBusClientBuilder builder = new ServiceBusClientBuilder(); if (mode == TestMode.LIVE) { - final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(false); assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = TestUtils.getPipelineCredential(credentialCached); return builder.credential(fullyQualifiedDomainName, credential); } else if (mode == TestMode.RECORD) { final String connectionString = TestUtils.getConnectionString(false); if (CoreUtils.isNullOrEmpty(connectionString)) { - final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(false); assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); return builder.credential(fullyQualifiedDomainName, credential); @@ -481,7 +481,7 @@ protected void assertRunnable() { // integration tests are runnable using the connection string. return; } - if (!CoreUtils.isNullOrEmpty(TestUtils.getFullyQualifiedDomainName())) { + if (!CoreUtils.isNullOrEmpty(TestUtils.getFullyQualifiedDomainName(false))) { // best effort check: // integration tests are potentially runnable using DefaultAzureCredential. Here we're assuming that // in RECORD mode with FullyQualifiedDomainName set, the dev environment is also set up for one of the diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java index 52fcac2133d0..ebf6607c05a2 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java @@ -46,7 +46,7 @@ public ServiceBusNonFederatedIntegrationTest() { @Test public void testBatchSendEventByAzureNameKeyCredential() { ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(false)); - String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); + String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(true); String sharedAccessKeyName = properties.getSharedAccessKeyName(); String sharedAccessKey = properties.getSharedAccessKey(); String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); @@ -70,7 +70,7 @@ public void testBatchSendEventByAzureNameKeyCredential() { @Test public void testBatchSendEventByAzureSasCredential() { ConnectionStringProperties properties = new ConnectionStringProperties(TestUtils.getConnectionString(true)); - String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(); + String fullyQualifiedNamespace = TestUtils.getFullyQualifiedDomainName(true); String sharedAccessSignature = properties.getSharedAccessSignature(); String queueName = getQueueName(TestUtils.USE_CASE_DEFAULT); @@ -94,7 +94,7 @@ public void testBatchSendEventByAzureSasCredential() { @Test void azureSasCredentialsTest() { - final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(false); assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); String connectionString = getConnectionString(true); Pattern sasPattern = Pattern.compile("SharedAccessSignature=(.*);?", Pattern.CASE_INSENSITIVE); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java index ade740763967..3a4dd896cf7c 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java @@ -165,19 +165,16 @@ public static String getConnectionString(boolean withSas) { /** * Gets the fully qualified domain name for the service bus resource. * - * @return The fully qualified domain name for the service bus resource if set else a redacted dummy name. - */ - public static String getFullyQualifiedDomainName() { - return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME", "REDACTED.servicebus.windows.net"); - } - - /** - * Gets the fully qualified domain name for the service bus resource. + * @param useFallbackValue If {@code true}, a redacted dummy name is returned if the fully qualified domain name environment variable is not set. * - * @return the fully qualified domain name for the service bus resource if set, {@code null} otherwise. + * @return The fully qualified domain name for the service bus resource. */ - public static String getLiveFullyQualifiedDomainName() { - return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME"); + public static String getFullyQualifiedDomainName(boolean useFallbackValue) { + if (useFallbackValue) { + return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME", "REDACTED.servicebus.windows.net"); + } else { + return getPropertyValue("AZURE_SERVICEBUS_FULLY_QUALIFIED_DOMAIN_NAME"); + } } public static String getEndpoint() { diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java index 1c122d17a729..254d15ff68db 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TracingIntegrationTests.java @@ -68,7 +68,7 @@ public TracingIntegrationTests() { @Override protected void beforeTest() { - spanProcessor = new TestSpanProcessor(TestUtils.getFullyQualifiedDomainName(), getQueueName(0)); + spanProcessor = new TestSpanProcessor(TestUtils.getFullyQualifiedDomainName(true), getQueueName(0)); OpenTelemetryTracingOptions tracingOptions = new OpenTelemetryTracingOptions() .setOpenTelemetry(OpenTelemetrySdk.builder() .setTracerProvider( @@ -189,7 +189,7 @@ public void receiveAndRenewSessionLockWithDuration() throws InterruptedException ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES) .setSessionId(sessionId); - OpenTelemetry otel = configureOTel(TestUtils.getFullyQualifiedDomainName(), getSessionQueueName(0)); + OpenTelemetry otel = configureOTel(TestUtils.getFullyQualifiedDomainName(true), getSessionQueueName(0)); final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(); sender = toClose(senderBuilder .clientOptions(new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel))) @@ -598,7 +598,7 @@ public void sendAndProcessSessionNoAutoComplete() throws InterruptedException { String sessionId = UUID.randomUUID().toString(); ServiceBusMessage message = new ServiceBusMessage(CONTENTS_BYTES).setSessionId(sessionId); - OpenTelemetry otel = configureOTel(TestUtils.getFullyQualifiedDomainName(), sessionQueueName); + OpenTelemetry otel = configureOTel(TestUtils.getFullyQualifiedDomainName(true), sessionQueueName); clientOptions = new ClientOptions().setTracingOptions(new OpenTelemetryTracingOptions().setOpenTelemetry(otel)); final ServiceBusClientBuilder senderBuilder = getAuthenticatedBuilder(); sender = toClose(senderBuilder diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java index 06c4be8ef9c9..9a5b6be7a886 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationAsyncClientIntegrationTest.java @@ -119,7 +119,7 @@ public static Stream createHttpClients() { @MethodSource("createHttpClients") @Disabled("The CI Pipeline cannot be enabled for both Federated Managed Identity auth and Secret auth") void azureClientSecretCredential(HttpClient httpClient) { - final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(true); final TokenCredential tokenCredential; if (interceptorManager.isPlaybackMode()) { tokenCredential = request -> Mono.fromCallable(() -> @@ -146,7 +146,7 @@ void azureClientSecretCredential(HttpClient httpClient) { .assertNext(properties -> { assertNotNull(properties); if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); + final String[] split = TestUtils.getFullyQualifiedDomainName(true).split("\\.", 2); assertEquals(split[0], properties.getName()); } }) @@ -703,7 +703,7 @@ void getNamespace(HttpClient httpClient) { .assertNext(properties -> { assertEquals(NamespaceType.MESSAGING, properties.getNamespaceType()); if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); + final String[] split = TestUtils.getFullyQualifiedDomainName(true).split("\\.", 2); assertEquals(split[0], properties.getName()); } }) @@ -1190,10 +1190,10 @@ private ServiceBusAdministrationAsyncClient createClient(HttpClient httpClient) static void configure(ServiceBusAdministrationClientBuilder builder, HttpClient httpClient, InterceptorManager interceptorManager, AtomicReference credentialCached) { if (interceptorManager.isPlaybackMode()) { - builder.credential(TestUtils.getFullyQualifiedDomainName(), new MockTokenCredential()); + builder.credential(TestUtils.getFullyQualifiedDomainName(true), new MockTokenCredential()); builder.httpClient(interceptorManager.getPlaybackClient()); } else if (interceptorManager.isLiveMode()) { - final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(false); assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = TestUtils.getPipelineCredential(credentialCached); builder.credential(fullyQualifiedDomainName, credential); @@ -1204,7 +1204,7 @@ static void configure(ServiceBusAdministrationClientBuilder builder, // Record Mode. final String connectionString = TestUtils.getConnectionString(false); if (CoreUtils.isNullOrEmpty(connectionString)) { - final String fullyQualifiedDomainName = TestUtils.getLiveFullyQualifiedDomainName(); + final String fullyQualifiedDomainName = TestUtils.getFullyQualifiedDomainName(false); assumeTrue(!CoreUtils.isNullOrEmpty(fullyQualifiedDomainName), "FullyQualifiedDomainName is not set."); final TokenCredential credential = new DefaultAzureCredentialBuilder().build(); builder.credential(fullyQualifiedDomainName, credential); diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java index e56965461458..6355814842a8 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/administration/ServiceBusAdministrationClientIntegrationTest.java @@ -430,7 +430,7 @@ void getNamespace() { final NamespaceProperties namespaceProperties = client.getNamespaceProperties(); assertEquals(NamespaceType.MESSAGING, namespaceProperties.getNamespaceType()); if (!interceptorManager.isPlaybackMode()) { - final String[] split = TestUtils.getFullyQualifiedDomainName().split("\\.", 2); + final String[] split = TestUtils.getFullyQualifiedDomainName(true).split("\\.", 2); assertEquals(split[0], namespaceProperties.getName()); } } From 1f4d44ac33d7e7ad52dbd2b0c31730a54565a98e Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 15:53:17 -0700 Subject: [PATCH 28/29] Use assumeTrue to throw TestAbortedException --- .../messaging/servicebus/IntegrationTestBase.java | 13 ++++++++----- .../ServiceBusNonFederatedIntegrationTest.java | 6 +++--- .../com/azure/messaging/servicebus/TestUtils.java | 8 +++++--- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java index 208e9d231554..1d4b3edd0bbb 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/IntegrationTestBase.java @@ -30,7 +30,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.provider.Arguments; -import org.opentest4j.TestAbortedException; import reactor.core.Disposable; import reactor.core.publisher.Mono; import reactor.core.scheduler.Scheduler; @@ -198,7 +197,9 @@ protected ServiceBusClientBuilder getAuthenticatedBuilder() { return builder.connectionString(connectionString); } } else { - throw new TestAbortedException("Integration tests are not enabled in playback mode."); + // Throws org.opentest4j.TestAbortedException exception. + assumeTrue(false, "Integration tests are not enabled in playback mode."); + return null; } } @@ -466,13 +467,14 @@ protected final Configuration v1OrV2(boolean isV2) { * Asserts that if the integration tests can be run. This method is expected to be called at the beginning of each * test run. * - * @throws TestAbortedException if the integration tests cannot be run. + * @throws org.opentest4j.TestAbortedException if the integration tests cannot be run. */ protected void assertRunnable() { final TestMode mode = super.getTestMode(); if (mode == TestMode.PLAYBACK) { // AMQP traffic never gets recorded so there is no PLAYBACK supported. - throw new TestAbortedException("Skipping integration tests in playback mode."); + assumeTrue(false, "Skipping integration tests in playback mode."); + return; } if (mode == TestMode.RECORD) { @@ -488,7 +490,8 @@ protected void assertRunnable() { // token credential type in DefaultAzureCredential (all token credentials requires FullyQualifiedDomainName). return; } - throw new TestAbortedException("Not running integration in record mode (missing authentication set up)."); + assumeTrue(false, "Not running integration in record mode (missing authentication set up)."); + return; } // The CI pipeline is expected to have federated identity configured, so tests are runnable. assert mode == TestMode.LIVE; diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java index ebf6607c05a2..b003cff07bc1 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java @@ -15,7 +15,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.Execution; import org.junit.jupiter.api.parallel.ExecutionMode; -import org.opentest4j.TestAbortedException; import reactor.test.StepVerifier; import java.time.Duration; @@ -120,7 +119,8 @@ protected void assertRunnable() { final TestMode mode = super.getTestMode(); if (mode == TestMode.PLAYBACK) { // AMQP traffic never gets recorded so there is no PLAYBACK supported. - throw new TestAbortedException("Skipping integration tests in playback mode."); + assertTrue(false, "Skipping integration tests in playback mode."); + return; } if (mode == TestMode.RECORD || mode == TestMode.LIVE) { @@ -130,6 +130,6 @@ protected void assertRunnable() { return; } } - throw new TestAbortedException("Not running integration in record mode (missing authentication set up)."); + assertTrue(false, "Not running integration in record mode (missing authentication set up)."); } } diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java index 3a4dd896cf7c..85efebf168c5 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/TestUtils.java @@ -22,7 +22,6 @@ import org.apache.qpid.proton.amqp.messaging.Data; import org.apache.qpid.proton.amqp.messaging.MessageAnnotations; import org.apache.qpid.proton.message.Message; -import org.opentest4j.TestAbortedException; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; @@ -53,6 +52,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public class TestUtils { private static final ClientLogger LOGGER = new ClientLogger(TestUtils.class); @@ -261,7 +261,7 @@ public static AzurePipelinesCredentialBuilder getPipelineCredentialBuilder() { * Obtain the Azure Pipelines credential if running in Azure Pipelines configured with service connections federated identity. * * @return the Azure Pipelines credential. - * @throws TestAbortedException if the test is not running in Azure Pipelines configured with service connections federated identity. + * @throws org.opentest4j.TestAbortedException if the test is not running in Azure Pipelines configured with service connections federated identity. */ public static TokenCredential getPipelineCredential(AtomicReference credentialCached) { return credentialCached.updateAndGet(cached -> { @@ -270,7 +270,9 @@ public static TokenCredential getPipelineCredential(AtomicReference Mono.defer(() -> pipelinesCredential.getToken(request)) From 6de2456c5c34cd77ba0419553cb9f8cd694fe79b Mon Sep 17 00:00:00 2001 From: anuchandy Date: Mon, 8 Jul 2024 16:30:22 -0700 Subject: [PATCH 29/29] use assumeTrue not assertTrue --- .../ServiceBusNonFederatedIntegrationTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java index b003cff07bc1..37c89b67b80d 100644 --- a/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java +++ b/sdk/servicebus/azure-messaging-servicebus/src/test/java/com/azure/messaging/servicebus/ServiceBusNonFederatedIntegrationTest.java @@ -33,13 +33,12 @@ @Tag("integration") @Execution(ExecutionMode.SAME_THREAD) public class ServiceBusNonFederatedIntegrationTest extends IntegrationTestBase { - private static final ClientLogger LOGGER = new ClientLogger(ServiceBusNonFederatedIntegrationTest.class); private static final Duration TIMEOUT = Duration.ofSeconds(20); private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(10); private static final String TEST_MESSAGE = "SSLorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vehicula posuere lobortis. Aliquam finibus volutpat dolor, faucibus pellentesque ipsum bibendum vitae. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut sit amet urna hendrerit, dapibus justo a, sodales justo. Mauris finibus augue id pulvinar congue. Nam maximus luctus ipsum, at commodo ligula euismod ac. Phasellus vitae lacus sit amet diam porta placerat. \nUt sodales efficitur sapien ut posuere. Morbi sed tellus est. Proin eu erat purus. Proin massa nunc, condimentum id iaculis dignissim, consectetur et odio. Cras suscipit sem eu libero aliquam tincidunt. Nullam ut arcu suscipit, eleifend velit in, cursus libero. Ut eleifend facilisis odio sit amet feugiat. Phasellus at nunc sit amet elit sagittis commodo ac in nisi. Fusce vitae aliquam quam. Integer vel nibh euismod, tempus elit vitae, pharetra est. Duis vulputate enim a elementum dignissim. Morbi dictum enim id elit scelerisque, in elementum nulla pharetra. \nAenean aliquet aliquet condimentum. Proin dapibus dui id libero tempus feugiat. Sed commodo ligula a lectus mattis, vitae tincidunt velit auctor. Fusce quis semper dui. Phasellus eu efficitur sem. Ut non sem sit amet enim condimentum venenatis id dictum massa. Nullam sagittis lacus a neque sodales, et ultrices arcu mattis. Aliquam erat volutpat. \nAenean fringilla quam elit, id mattis purus vestibulum nec. Praesent porta eros in dapibus molestie. Vestibulum orci libero, tincidunt et turpis eget, condimentum lobortis enim. Fusce suscipit ante et mauris consequat cursus nec laoreet lorem. Maecenas in sollicitudin diam, non tincidunt purus. Nunc mauris purus, laoreet eget interdum vitae, placerat a sapien. In mi risus, blandit eu facilisis nec, molestie suscipit leo. Pellentesque molestie urna vitae dui faucibus bibendum. \nDonec quis ipsum ultricies, imperdiet ex vel, scelerisque eros. Ut at urna arcu. Vestibulum rutrum odio dolor, vitae cursus nunc pulvinar vel. Donec accumsan sapien in malesuada tempor. Maecenas in condimentum eros. Sed vestibulum facilisis massa a iaculis. Etiam et nibh felis. Donec maximus, sem quis vestibulum gravida, turpis risus congue dolor, pharetra tincidunt lectus nisi at velit."; - public ServiceBusNonFederatedIntegrationTest() { - super(LOGGER); + ServiceBusNonFederatedIntegrationTest() { + super(new ClientLogger(ServiceBusNonFederatedIntegrationTest.class)); } @Test @@ -119,7 +118,7 @@ protected void assertRunnable() { final TestMode mode = super.getTestMode(); if (mode == TestMode.PLAYBACK) { // AMQP traffic never gets recorded so there is no PLAYBACK supported. - assertTrue(false, "Skipping integration tests in playback mode."); + assumeTrue(false, "Skipping integration tests in playback mode."); return; } @@ -130,6 +129,6 @@ protected void assertRunnable() { return; } } - assertTrue(false, "Not running integration in record mode (missing authentication set up)."); + assumeTrue(false, "Not running integration in record mode (missing authentication set up)."); } }