public void Should_use_passed_in_queue_parameters_if_specified() { // Given var description = new QueueDescription(this.queueName); var listener = new ServiceBusClient( this.serialiser, this.bus); // When listener.Connect(this.connectionString, this.queueName, description); // Then this.bus.VerifyQueueDescription.ShouldBeSameAs(description); }
public void Should_verify_queue_on_connect() { // Given var listener = new ServiceBusClient( this.serialiser, this.bus); // When listener.Connect(this.connectionString, this.queueName); // Then this.bus.VerifyQueueConnectionString.ShouldEqual(this.connectionString); this.bus.VerifyQueueDescription.ShouldNotBeNull(); this.bus.VerifyQueueDescription.Path.ShouldEqual(this.queueName); }
public void Should_serialise_message() { // Given object passedPayload = null; var description = new QueueDescription(this.queueName); var listener = new ServiceBusClient( this.serialiser, this.bus); listener.Connect(this.connectionString, this.queueName, description); var payload = new Object(); A.CallTo(() => this.serialiser.Serialise(payload)) .Invokes(foc => passedPayload = foc.Arguments[0]) .Returns("FooBarBaz"); // When listener.Send("messageType", payload).Wait(); // Then passedPayload.ShouldBeSameAs(payload); }
public async Task TransactionalSendViaCommitTest() { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); await using var intermediateQueue = await ServiceBusScope.CreateWithQueue(enablePartitioning : true, enableSession : false); await using var destination1 = await ServiceBusScope.CreateWithTopic(enablePartitioning : true, enableSession : false); await using var destination2 = await ServiceBusScope.CreateWithQueue(enablePartitioning : true, enableSession : false); var intermediateSender = client.CreateSender(intermediateQueue.QueueName); var intermediateReceiver = client.CreateReceiver(intermediateQueue.QueueName); var destination1Sender = client.CreateSender(destination1.TopicName); var destination1ViaSender = client.CreateSender(destination1.TopicName, new ServiceBusSenderOptions { ViaQueueOrTopicName = intermediateQueue.QueueName }); var destination2ViaSender = client.CreateSender(destination2.QueueName, new ServiceBusSenderOptions { ViaQueueOrTopicName = intermediateQueue.QueueName }); var destination1Receiver = client.CreateReceiver(destination1.TopicName, destination1.SubscriptionNames.First()); var destination2Receiver = client.CreateReceiver(destination2.QueueName); var body = Encoding.Default.GetBytes(Guid.NewGuid().ToString("N")); var message1 = new ServiceBusMessage(body) { MessageId = "1", PartitionKey = "pk1" }; var message2 = new ServiceBusMessage(body) { MessageId = "2", PartitionKey = "pk2", ViaPartitionKey = "pk1" }; var message3 = new ServiceBusMessage(body) { MessageId = "3", PartitionKey = "pk3", ViaPartitionKey = "pk1" }; await intermediateSender.SendAsync(message1).ConfigureAwait(false); var receivedMessage = await intermediateReceiver.ReceiveAsync(); Assert.NotNull(receivedMessage); Assert.AreEqual("pk1", receivedMessage.PartitionKey); // If the transaction succeeds, then all the operations occurred on the same partition. using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await intermediateReceiver.CompleteAsync(receivedMessage); await destination1ViaSender.SendAsync(message2); await destination2ViaSender.SendAsync(message3); ts.Complete(); } // Assert that first message indeed completed. receivedMessage = await intermediateReceiver.ReceiveAsync(TimeSpan.FromSeconds(5)); Assert.Null(receivedMessage); // Assert that second message reached its destination. var receivedMessage1 = await destination1Receiver.ReceiveAsync(); Assert.NotNull(receivedMessage1); Assert.AreEqual("pk2", receivedMessage1.PartitionKey); // Assert destination1 message actually used partitionKey in the destination entity. var destination1Message = new ServiceBusMessage(body) { PartitionKey = "pk2" }; using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { await destination1Receiver.CompleteAsync(receivedMessage1); await destination1Sender.SendAsync(destination1Message); ts.Complete(); } // Assert that third message reached its destination. var receivedMessage2 = await destination2Receiver.ReceiveAsync(); Assert.NotNull(receivedMessage2); Assert.AreEqual("pk3", receivedMessage2.PartitionKey); await destination2Receiver.CompleteAsync(receivedMessage2); // Cleanup receivedMessage1 = await destination1Receiver.ReceiveAsync(); await destination1Receiver.CompleteAsync(receivedMessage1); }
public async Task GetSubscriptionRuntimeInfoTest() { var topicName = nameof(GetSubscriptionRuntimeInfoTest).ToLower() + Recording.Random.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Recording.Random.NewGuid().ToString("D").Substring(0, 8); var client = CreateClient(); await using var sbClient = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); await client.CreateTopicAsync(topicName); TopicProperties getTopic = await client.GetTopicAsync(topicName); // Changing Last Updated Time getTopic.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); await client.UpdateTopicAsync(getTopic); SubscriptionProperties subscriptionDescription = await client.CreateSubscriptionAsync(topicName, subscriptionName); // Changing Last Updated Time for subscription subscriptionDescription.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); await client.UpdateSubscriptionAsync(subscriptionDescription); // Populating 1 active message, 1 dead letter message and 1 scheduled message // Changing Last Accessed Time ServiceBusSender sender = sbClient.CreateSender(topicName); await sender.SendMessageAsync(new ServiceBusMessage() { MessageId = "1" }); await sender.SendMessageAsync(new ServiceBusMessage() { MessageId = "2" }); await sender.SendMessageAsync(new ServiceBusMessage() { MessageId = "3", ScheduledEnqueueTime = DateTime.UtcNow.AddDays(1) }); ServiceBusReceiver receiver = sbClient.CreateReceiver(topicName, subscriptionName); ServiceBusReceivedMessage msg = await receiver.ReceiveMessageAsync(); await receiver.DeadLetterMessageAsync(msg); List <SubscriptionRuntimeProperties> runtimeInfoList = new List <SubscriptionRuntimeProperties>(); await foreach (SubscriptionRuntimeProperties subscriptionRuntimeInfo in client.GetSubscriptionsRuntimePropertiesAsync(topicName)) { runtimeInfoList.Add(subscriptionRuntimeInfo); } runtimeInfoList = runtimeInfoList.Where(e => e.TopicName.StartsWith(nameof(GetSubscriptionRuntimeInfoTest).ToLower())).ToList(); Assert.True(runtimeInfoList.Count == 1, $"Expected 1 subscription but {runtimeInfoList.Count} subscriptions returned"); SubscriptionRuntimeProperties runtimeInfo = runtimeInfoList.First(); Assert.NotNull(runtimeInfo); Assert.AreEqual(topicName, runtimeInfo.TopicName); Assert.AreEqual(subscriptionName, runtimeInfo.SubscriptionName); Assert.True(runtimeInfo.CreatedAt < runtimeInfo.UpdatedAt); Assert.True(runtimeInfo.UpdatedAt < runtimeInfo.AccessedAt); Assert.AreEqual(1, runtimeInfo.ActiveMessageCount); Assert.AreEqual(1, runtimeInfo.DeadLetterMessageCount); Assert.AreEqual(2, runtimeInfo.TotalMessageCount); SubscriptionRuntimeProperties singleRuntimeInfo = await client.GetSubscriptionRuntimePropertiesAsync(topicName, subscriptionName); Assert.AreEqual(runtimeInfo.CreatedAt, singleRuntimeInfo.CreatedAt); Assert.AreEqual(runtimeInfo.AccessedAt, singleRuntimeInfo.AccessedAt); Assert.AreEqual(runtimeInfo.UpdatedAt, singleRuntimeInfo.UpdatedAt); Assert.AreEqual(runtimeInfo.SubscriptionName, singleRuntimeInfo.SubscriptionName); Assert.AreEqual(runtimeInfo.TotalMessageCount, singleRuntimeInfo.TotalMessageCount); Assert.AreEqual(runtimeInfo.ActiveMessageCount, singleRuntimeInfo.ActiveMessageCount); Assert.AreEqual(runtimeInfo.DeadLetterMessageCount, singleRuntimeInfo.DeadLetterMessageCount); Assert.AreEqual(runtimeInfo.TopicName, singleRuntimeInfo.TopicName); List <TopicRuntimeProperties> topicRuntimePropertiesList = new List <TopicRuntimeProperties>(); await foreach (TopicRuntimeProperties topicRuntime in client.GetTopicsRuntimePropertiesAsync()) { topicRuntimePropertiesList.Add(topicRuntime); } topicRuntimePropertiesList = topicRuntimePropertiesList.Where(e => e.Name.StartsWith(nameof(GetSubscriptionRuntimeInfoTest).ToLower())).ToList(); Assert.True(topicRuntimePropertiesList.Count == 1, $"Expected 1 subscription but {topicRuntimePropertiesList.Count} subscriptions returned"); TopicRuntimeProperties topicRuntimeProperties = topicRuntimePropertiesList.First(); Assert.NotNull(topicRuntimeProperties); Assert.AreEqual(topicName, topicRuntimeProperties.Name); Assert.True(topicRuntimeProperties.CreatedAt < topicRuntimeProperties.UpdatedAt); Assert.True(topicRuntimeProperties.UpdatedAt < topicRuntimeProperties.AccessedAt); Assert.AreEqual(1, topicRuntimeProperties.ScheduledMessageCount); TopicRuntimeProperties singleTopicRuntimeProperties = await client.GetTopicRuntimePropertiesAsync(topicName); Assert.AreEqual(topicRuntimeProperties.CreatedAt, singleTopicRuntimeProperties.CreatedAt); Assert.AreEqual(topicRuntimeProperties.AccessedAt, singleTopicRuntimeProperties.AccessedAt); Assert.AreEqual(topicRuntimeProperties.UpdatedAt, singleTopicRuntimeProperties.UpdatedAt); Assert.AreEqual(topicRuntimeProperties.ScheduledMessageCount, singleTopicRuntimeProperties.ScheduledMessageCount); Assert.AreEqual(topicRuntimeProperties.Name, singleTopicRuntimeProperties.Name); await client.DeleteTopicAsync(topicName); }
public SbQueueLoadGenerator(ServiceBusClient sBusClient, ILogger <SbQueueLoadGenerator> logger) { _sBusClient = sBusClient; _logger = logger; }
private async Task RunBatchReceiveLoopAsync(CancellationToken cancellationToken) { ServiceBusClient sessionClient = null; ServiceBusReceiver receiver = null; if (_isSessionsEnabled) { sessionClient = _client.Value; } else { receiver = _batchReceiver.Value; } // The batch receive loop below only executes functions at a concurrency level of 1, // so we don't need to do anything special when DynamicConcurrency is enabled. If in // the future we make this loop concurrent, we'll have to check with ConcurrencyManager. while (true) { try { if (cancellationToken.IsCancellationRequested) { _logger.LogInformation($"Message processing has been stopped or cancelled ({_details.Value})"); return; } if (_isSessionsEnabled && (receiver == null || receiver.IsClosed)) { try { receiver = await sessionClient.AcceptNextSessionAsync( _entityPath, new ServiceBusSessionReceiverOptions { PrefetchCount = _serviceBusOptions.PrefetchCount }, cancellationToken).ConfigureAwait(false); } catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.ServiceTimeout) { // it's expected if the entity is empty, try next time continue; } } IReadOnlyList <ServiceBusReceivedMessage> messages = await receiver.ReceiveMessagesAsync( _serviceBusOptions.MaxMessageBatchSize, cancellationToken : cancellationToken).AwaitWithCancellation(cancellationToken); if (messages.Count > 0) { var actions = _isSessionsEnabled ? new ServiceBusSessionMessageActions((ServiceBusSessionReceiver)receiver) : new ServiceBusMessageActions(receiver); ServiceBusReceivedMessage[] messagesArray = messages.ToArray(); ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateBatch( messagesArray, actions, _client.Value); FunctionResult result = await _triggerExecutor.TryExecuteAsync(input.GetTriggerFunctionData(), cancellationToken).ConfigureAwait(false); // Complete batch of messages only if the execution was successful if (_autoCompleteMessagesOptionEvaluatedValue) { if (result.Succeeded) { List <Task> completeTasks = new List <Task>(); foreach (ServiceBusReceivedMessage message in messagesArray) { // skip messages that were settled in the user's function if (input.MessageActions.SettledMessages.ContainsKey(message)) { continue; } // Pass CancellationToken.None to allow autocompletion to finish even when shutting down completeTasks.Add(receiver.CompleteMessageAsync(message, CancellationToken.None)); } await Task.WhenAll(completeTasks).ConfigureAwait(false); } else { List <Task> abandonTasks = new List <Task>(); foreach (ServiceBusReceivedMessage message in messagesArray) { // skip messages that were settled in the user's function if (input.MessageActions.SettledMessages.ContainsKey(message)) { continue; } // Pass CancellationToken.None to allow abandon to finish even when shutting down abandonTasks.Add(receiver.AbandonMessageAsync(message, cancellationToken: CancellationToken.None)); } await Task.WhenAll(abandonTasks).ConfigureAwait(false); } } if (_isSessionsEnabled) { if (((ServiceBusSessionMessageActions)actions).ShouldReleaseSession) { // Use CancellationToken.None to attempt to close the receiver even when shutting down await receiver.CloseAsync(CancellationToken.None).ConfigureAwait(false); } } } else { // Close the session and release the session lock after draining all messages for the accepted session. if (_isSessionsEnabled) { // Use CancellationToken.None to attempt to close the receiver even when shutting down await receiver.CloseAsync(CancellationToken.None).ConfigureAwait(false); } } } catch (ObjectDisposedException) { // Ignore as we are stopping the host } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // Ignore as we are stopping the host _logger.LogInformation($"Message processing has been stopped or cancelled ({_details.Value})"); } catch (Exception ex) { // Log another exception _logger.LogError(ex, $"An unhandled exception occurred in the message batch receive loop ({_details.Value})"); if (_isSessionsEnabled && receiver != null) { // Attempt to close the session and release session lock to accept a new session on the next loop iteration try { // Use CancellationToken.None to attempt to close the receiver even when shutting down await receiver.CloseAsync(CancellationToken.None).ConfigureAwait(false); } catch { // Best effort receiver = null; } } } } }
public async Task ReceiverCanReconnectToSameSession(bool isSessionSpecified) { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true, lockDuration: TimeSpan.FromSeconds(5))) { await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); await sender.SendMessagesAsync(GetMessages(3, "sessionId1")); // send another session message before the one we are interested in to make sure that when isSessionSpecified=true, it is being respected await sender.SendMessagesAsync(GetMessages(3, "sessionId2")); ServiceBusSessionReceiver receiver = await client.CreateSessionReceiverAsync( scope.QueueName, new ServiceBusSessionReceiverOptions { SessionId = isSessionSpecified ? "sessionId1" : null }); if (isSessionSpecified) { Assert.AreEqual("sessionId1", receiver.SessionId); } var firstMessage = await receiver.ReceiveMessageAsync(); Assert.AreEqual(receiver.SessionId, firstMessage.SessionId); var sessionId = receiver.SessionId; await Task.Delay((receiver.SessionLockedUntil - DateTime.UtcNow) + TimeSpan.FromSeconds(5)); var secondMessage = await receiver.ReceiveMessageAsync(); Assert.AreEqual(sessionId, receiver.SessionId); Assert.AreEqual(receiver.SessionId, secondMessage.SessionId); // Even though the receiver has re-established the session link, since the first message was // received before we reconnected, the message won't be able to be settled. This is analogous // to the case of reconnecting a regular non-session link and getting a MessageLockLost error. Assert.That( async() => await receiver.CompleteMessageAsync(firstMessage), Throws.InstanceOf <ServiceBusException>().And.Property(nameof(ServiceBusException.Reason)).EqualTo(ServiceBusFailureReason.SessionLockLost)); await Task.Delay((receiver.SessionLockedUntil - DateTime.UtcNow) + TimeSpan.FromSeconds(5)); // If another receiver accepts the session after the lock is lost, we expect a SessionCannotBeLocked error, // when we try to receive again with our initial receiver. ServiceBusSessionReceiver secondReceiver = await client.CreateSessionReceiverAsync( scope.QueueName, new ServiceBusSessionReceiverOptions { SessionId = sessionId }); try { await receiver.ReceiveMessageAsync(); } catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.SessionCannotBeLocked) { return; } catch (Exception ex) { Assert.Fail($"Expected exception not thrown: {ex}"); } Assert.Fail("No exception thrown!"); } }
public async Task DeadLetterMessages(bool useSpecificSession) { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true)) { await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); var messageCount = 10; var sessionId = "sessionId1"; using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync(); IEnumerable <ServiceBusMessage> messages = AddMessages(batch, messageCount, sessionId).AsEnumerable <ServiceBusMessage>(); await sender.SendMessagesAsync(batch); var receiver = await client.CreateSessionReceiverAsync( scope.QueueName, new ServiceBusSessionReceiverOptions { SessionId = useSpecificSession ? sessionId : null }); var remainingMessages = messageCount; var messageEnum = messages.GetEnumerator(); while (remainingMessages > 0) { foreach (var item in await receiver.ReceiveMessagesAsync(remainingMessages)) { remainingMessages--; messageEnum.MoveNext(); Assert.AreEqual(messageEnum.Current.MessageId, item.MessageId); Assert.AreEqual(messageEnum.Current.SessionId, item.SessionId); await receiver.DeadLetterMessageAsync(item.LockToken, "testReason", "testDescription"); } } Assert.AreEqual(0, remainingMessages); var peekedMessage = receiver.PeekMessageAsync(); Assert.IsNull(peekedMessage.Result); messageEnum.Reset(); remainingMessages = messageCount; var deadLetterReceiver = client.CreateReceiver(scope.QueueName, new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter }); while (remainingMessages > 0) { foreach (var msg in await deadLetterReceiver.ReceiveMessagesAsync(remainingMessages)) { remainingMessages--; messageEnum.MoveNext(); Assert.AreEqual(messageEnum.Current.MessageId, msg.MessageId); Assert.AreEqual(messageEnum.Current.SessionId, msg.SessionId); Assert.AreEqual("testReason", msg.DeadLetterReason); Assert.AreEqual("testDescription", msg.DeadLetterErrorDescription); await deadLetterReceiver.CompleteMessageAsync(msg.LockToken); } } Assert.AreEqual(0, remainingMessages); var deadLetterMessage = await deadLetterReceiver.PeekMessageAsync(); Assert.IsNull(deadLetterMessage); } }
private ServiceBusProcessor BuildServiceBusProcessor(ServiceBusClient serviceBusClient, string topic, string subscription, ServiceBusProcessorOptions?serviceBusProcessorOptions) => serviceBusProcessorOptions is null ? serviceBusClient.CreateProcessor(topic, subscription) : serviceBusClient.CreateProcessor(topic, subscription, serviceBusProcessorOptions);
public override void ExecuteCmdlet() { try { PSSharedAccessAuthorizationRuleAttributes sasRule = new PSSharedAccessAuthorizationRuleAttributes(); if (InputObject != null) { sasRule = InputObject; } else { sasRule.Rights = new List <AccessRights?>(); if (Rights != null && Rights.Length > 0) { if (Array.Exists(Rights, element => element == "Manage") && !Array.Exists(Rights, element => element == "Listen") || !Array.Exists(Rights, element => element == "Send")) { Exception exManage = new Exception("Assigning 'Manage' to rights requires ‘Listen and ‘Send' to be included with. e.g. @(\"Manage\",\"Listen\",\"Send\")"); throw exManage; } foreach (string test in Rights) { sasRule.Rights.Add(ParseAccessRights(test)); } } } if (ParameterSetName.Equals(AuthoRuleInputObjectParameterSet)) { if (Topic != null) { if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateTopicAuthorizationrule, Name, Topic))) { WriteObject(Client.CreateOrUpdateServiceBusTopicAuthorizationRules(ResourceGroupName, Namespace, Topic, Name, sasRule)); } } else if (Queue != null) { if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateQueueAuthorizationrule, Name, Queue))) { WriteObject(Client.CreateOrUpdateServiceBusQueueAuthorizationRules(ResourceGroupName, Namespace, Queue, Name, sasRule)); } } else if (Namespace != null) { if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateNamespaceAuthorizationrule, Name, Namespace))) { WriteObject(Client.CreateOrUpdateNamespaceAuthorizationRules(ResourceGroupName, Namespace, Name, sasRule)); } } } // update Namespace Authorization Rule if (ParameterSetName.Equals(NamespaceAuthoRuleParameterSet)) { if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateNamespaceAuthorizationrule, Name, Namespace))) { WriteObject(Client.CreateOrUpdateNamespaceAuthorizationRules(ResourceGroupName, Namespace, Name, sasRule)); } } // Update Topic authorizationRule if (ParameterSetName.Equals(QueueAuthoRuleParameterSet)) { if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateQueueAuthorizationrule, Name, Queue))) { WriteObject(Client.CreateOrUpdateServiceBusQueueAuthorizationRules(ResourceGroupName, Namespace, Queue, Name, sasRule)); } } // Update Topic authorizationRule if (ParameterSetName.Equals(TopicAuthoRuleParameterSet)) { if (ShouldProcess(target: sasRule.Name, action: string.Format(Resources.UpdateTopicAuthorizationrule, Name, Topic))) { WriteObject(Client.CreateOrUpdateServiceBusTopicAuthorizationRules(ResourceGroupName, Namespace, Topic, Name, sasRule)); } } } catch (ErrorResponseException ex) { WriteError(ServiceBusClient.WriteErrorforBadrequest(ex)); } catch (Exception ex) { WriteError(new ErrorRecord(ex, ex.Message, ErrorCategory.OpenError, ex)); } }
/// <inheritdoc /> public override Task DeadLetter(Message message, IDictionary <string, object> propertiesToModify = null) { return(ServiceBusClient.DeadLetterAsync(message.SystemProperties.LockToken, propertiesToModify)); }
public async Task TransactionThrowsWhenOperationsOfDifferentPartitionsAreInSameTransaction() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: true, enableSession: false)) { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); ServiceBusReceiver receiver = client.CreateReceiver(scope.QueueName); string body = Guid.NewGuid().ToString("N"); ServiceBusMessage message1 = GetMessage(partitionKey: "1"); ServiceBusMessage message2 = GetMessage(partitionKey: "2"); // Two send operations to different partitions. var transaction = new CommittableTransaction(); using (TransactionScope ts = new TransactionScope(transaction, TransactionScopeAsyncFlowOption.Enabled)) { await sender.SendAsync(message1); Assert.ThrowsAsync <InvalidOperationException>( async() => await sender.SendAsync(message2)); ts.Complete(); } transaction.Rollback(); // Adding delay since transaction Commit/Rollback is an asynchronous operation. // Operating on the same message should not be done. await Task.Delay(TimeSpan.FromSeconds(2)); // Two complete operations to different partitions. await sender.SendAsync(message1); await sender.SendAsync(message2); ServiceBusReceivedMessage receivedMessage1 = await receiver.ReceiveAsync(); Assert.NotNull(receivedMessage1); ServiceBusReceivedMessage receivedMessage2 = await receiver.ReceiveAsync(); Assert.NotNull(receivedMessage2); transaction = new CommittableTransaction(); using (TransactionScope ts = new TransactionScope(transaction, TransactionScopeAsyncFlowOption.Enabled)) { await receiver.CompleteAsync(receivedMessage1); Assert.ThrowsAsync <InvalidOperationException>( async() => await receiver.CompleteAsync(receivedMessage2)); ts.Complete(); } transaction.Rollback(); // Adding delay since transaction Commit/Rollback is an asynchronous operation. // Operating on the same message should not be done. await Task.Delay(TimeSpan.FromSeconds(2)); await receiver.CompleteAsync(receivedMessage1); // the service seems to abandon the message that // triggered the InvalidOperationException // in the transaction Assert.That( async() => await receiver.CompleteAsync(receivedMessage2), Throws.InstanceOf <ServiceBusException>() .And.Property(nameof(ServiceBusException.Reason)) .EqualTo(ServiceBusException.FailureReason.MessageLockLost)); } }
public async Task UserSettlingWithAutoCompleteDoesNotThrow(int numThreads) { await using (var scope = await ServiceBusScope.CreateWithQueue( enablePartitioning: false, enableSession: false)) { await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); // use double the number of threads so we can make sure we test that we don't // retrieve more messages than expected when there are more messages available using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync(); var messageSendCt = numThreads * 2; ServiceBusMessageBatch messageBatch = AddMessages(batch, messageSendCt); await sender.SendMessagesAsync(messageBatch); var options = new ServiceBusProcessorOptions { MaxConcurrentCalls = numThreads, AutoComplete = true, MaxReceiveWaitTime = TimeSpan.FromSeconds(30) }; var processor = client.CreateProcessor(scope.QueueName, options); int messageCt = 0; TaskCompletionSource <bool>[] completionSources = Enumerable .Range(0, numThreads) .Select(index => new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously)) .ToArray(); var completionSourceIndex = -1; processor.ProcessMessageAsync += ProcessMessage; processor.ProcessErrorAsync += ExceptionHandler; await processor.StartProcessingAsync(); async Task ProcessMessage(ProcessMessageEventArgs args) { try { var message = args.Message; switch (numThreads) { case 1: await args.CompleteMessageAsync(message, args.CancellationToken); break; case 5: await args.AbandonMessageAsync(message); break; case 10: await args.DeadLetterMessageAsync(message); break; case 20: await args.DeferMessageAsync(message); break; } Interlocked.Increment(ref messageCt); } finally { var setIndex = Interlocked.Increment(ref completionSourceIndex); if (setIndex < numThreads) { completionSources[setIndex].SetResult(true); } } } await Task.WhenAll(completionSources.Select(source => source.Task)); await processor.StopProcessingAsync(); // we complete each task after one message being processed, so the total number of messages // processed should equal the number of threads, but it's possible that we may process a few more per thread. Assert.IsTrue(messageCt >= numThreads); Assert.IsTrue(messageCt <= messageSendCt, messageCt.ToString()); } }
public async Task SenderReceiverActivities(bool useSessions) { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: useSessions)) { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); string sessionId = null; if (useSessions) { sessionId = "sessionId"; } int numMessages = 5; var msgs = ServiceBusTestUtilities.GetMessages(numMessages, sessionId); await sender.SendMessagesAsync(msgs); Activity[] sendActivities = AssertSendActivities(useSessions, sender, msgs); ServiceBusReceiver receiver = null; if (useSessions) { receiver = await client.AcceptNextSessionAsync(scope.QueueName); } else { receiver = client.CreateReceiver(scope.QueueName); } var remaining = numMessages; List <ServiceBusReceivedMessage> receivedMsgs = new List <ServiceBusReceivedMessage>(); while (remaining > 0) { // loop in case we don't receive all messages in one attempt var received = await receiver.ReceiveMessagesAsync(remaining); receivedMsgs.AddRange(received); var receiveScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveActivityName); AssertCommonTags(receiveScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var receiveLinkedActivities = receiveScope.LinkedActivities; for (int i = 0; i < receiveLinkedActivities.Count; i++) { Assert.AreEqual(sendActivities[i].ParentId, receiveLinkedActivities[i].ParentId); } remaining -= received.Count; } var msgIndex = 0; var completed = receivedMsgs[msgIndex]; await receiver.CompleteMessageAsync(completed); var completeScope = _listener.AssertAndRemoveScope(DiagnosticProperty.CompleteActivityName); AssertCommonTags(completeScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var deferred = receivedMsgs[++msgIndex]; await receiver.DeferMessageAsync(deferred); var deferredScope = _listener.AssertAndRemoveScope(DiagnosticProperty.DeferActivityName); AssertCommonTags(deferredScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var deadLettered = receivedMsgs[++msgIndex]; await receiver.DeadLetterMessageAsync(deadLettered); var deadLetterScope = _listener.AssertAndRemoveScope(DiagnosticProperty.DeadLetterActivityName); AssertCommonTags(deadLetterScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var abandoned = receivedMsgs[++msgIndex]; await receiver.AbandonMessageAsync(abandoned); var abandonScope = _listener.AssertAndRemoveScope(DiagnosticProperty.AbandonActivityName); AssertCommonTags(abandonScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); var receiveDeferMsg = await receiver.ReceiveDeferredMessageAsync(deferred.SequenceNumber); var receiveDeferScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveDeferredActivityName); AssertCommonTags(receiveDeferScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); // renew lock if (useSessions) { var sessionReceiver = (ServiceBusSessionReceiver)receiver; await sessionReceiver.RenewSessionLockAsync(); var renewSessionScope = _listener.AssertAndRemoveScope(DiagnosticProperty.RenewSessionLockActivityName); AssertCommonTags(renewSessionScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); // set state var state = new BinaryData("state"); await sessionReceiver.SetSessionStateAsync(state); var setStateScope = _listener.AssertAndRemoveScope(DiagnosticProperty.SetSessionStateActivityName); AssertCommonTags(setStateScope.Activity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace); // get state var getState = await sessionReceiver.GetSessionStateAsync(); Assert.AreEqual(state.ToArray(), getState.ToArray()); var getStateScope = _listener.AssertAndRemoveScope(DiagnosticProperty.GetSessionStateActivityName); AssertCommonTags(getStateScope.Activity, sessionReceiver.EntityPath, sessionReceiver.FullyQualifiedNamespace); } else { await receiver.RenewMessageLockAsync(receivedMsgs[4]); var renewMessageScope = _listener.AssertAndRemoveScope(DiagnosticProperty.RenewMessageLockActivityName); AssertCommonTags(renewMessageScope.Activity, receiver.EntityPath, receiver.FullyQualifiedNamespace); } // schedule msgs = ServiceBusTestUtilities.GetMessages(numMessages, sessionId); foreach (var msg in msgs) { var seq = await sender.ScheduleMessageAsync(msg, DateTimeOffset.UtcNow.AddMinutes(1)); Assert.IsNotNull(msg.ApplicationProperties[DiagnosticProperty.DiagnosticIdAttribute]); var messageScope = _listener.AssertAndRemoveScope(DiagnosticProperty.MessageActivityName); AssertCommonTags(messageScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace); var scheduleScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ScheduleActivityName); AssertCommonTags(scheduleScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace); var linkedActivities = scheduleScope.LinkedActivities; Assert.AreEqual(1, linkedActivities.Count); Assert.AreEqual(messageScope.Activity.Id, linkedActivities[0].ParentId); await sender.CancelScheduledMessageAsync(seq); var cancelScope = _listener.AssertAndRemoveScope(DiagnosticProperty.CancelActivityName); AssertCommonTags(cancelScope.Activity, sender.EntityPath, sender.FullyQualifiedNamespace); } // send a batch var batch = await sender.CreateMessageBatchAsync(); for (int i = 0; i < numMessages; i++) { batch.TryAddMessage(ServiceBusTestUtilities.GetMessage(sessionId)); } await sender.SendMessagesAsync(batch); AssertSendActivities(useSessions, sender, batch.AsReadOnly <ServiceBusMessage>()); }; }
public async Task SessionProcessorActivities() { ClientDiagnosticListener.ProducedLink[] messageActivities = null; int messageProcessedCt = 0; bool callbackExecuted = false; _listener = new ClientDiagnosticListener( EntityScopeFactory.DiagnosticNamespace, scopeStartCallback: scope => { if (scope.Name == DiagnosticProperty.ProcessSessionMessageActivityName) { Assert.IsNotNull(messageActivities); Assert.AreEqual( messageActivities[messageProcessedCt], scope.Links.Single()); callbackExecuted = true; } }); await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: false, enableSession: true)) { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.QueueName); var messageCt = 2; var msgs = ServiceBusTestUtilities.GetMessages(messageCt, "sessionId"); await sender.SendMessagesAsync(msgs); Activity[] sendActivities = AssertSendActivities(false, sender, msgs); messageActivities = sendActivities.Select(a => new ClientDiagnosticListener.ProducedLink(a.ParentId, a.TraceStateString)).ToArray(); ServiceBusSessionProcessor processor = client.CreateSessionProcessor(scope.QueueName, new ServiceBusSessionProcessorOptions { AutoCompleteMessages = false, SessionIdleTimeout = TimeSpan.FromSeconds(10), MaxConcurrentSessions = 1 }); TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(); processor.ProcessMessageAsync += args => { if (++messageProcessedCt == messageCt) { tcs.SetResult(true); } return(Task.CompletedTask); }; processor.ProcessErrorAsync += ServiceBusTestUtilities.ExceptionHandler; await processor.StartProcessingAsync(); await tcs.Task; await processor.StopProcessingAsync(); for (int i = 0; i < messageCt; i++) { _listener.AssertAndRemoveScope(DiagnosticProperty.ReceiveActivityName); var processScope = _listener.AssertAndRemoveScope(DiagnosticProperty.ProcessSessionMessageActivityName); AssertCommonTags(processScope.Activity, processor.EntityPath, processor.FullyQualifiedNamespace); } Assert.IsTrue(callbackExecuted); } }
public async Task CreateFromReceivedMessageCopiesProperties() { await using (var scope = await ServiceBusScope.CreateWithQueue(enablePartitioning: true, enableSession: true)) { var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); var sender = client.CreateSender(scope.QueueName); var msg = new ServiceBusMessage(new BinaryData(GetRandomBuffer(100))); msg.ContentType = "contenttype"; msg.CorrelationId = "correlationid"; msg.Subject = "label"; msg.MessageId = "messageId"; msg.PartitionKey = "key"; msg.ApplicationProperties.Add("testProp", "my prop"); msg.ReplyTo = "replyto"; msg.ReplyToSessionId = "replytosession"; msg.ScheduledEnqueueTime = DateTimeOffset.Now; msg.SessionId = "key"; msg.TimeToLive = TimeSpan.FromSeconds(60); msg.To = "to"; await sender.SendMessageAsync(msg); ServiceBusSessionReceiver receiver = await client.AcceptNextSessionAsync(scope.QueueName); ServiceBusReceivedMessage received = await receiver.ReceiveMessageAsync(); AmqpAnnotatedMessage rawReceived = received.GetRawAmqpMessage(); Assert.IsNotNull(rawReceived.Header.DeliveryCount); Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.LockedUntilName)); Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.SequenceNumberName)); Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueueSequenceNumberName)); Assert.IsTrue(rawReceived.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueuedTimeUtcName)); AssertMessagesEqual(msg, received); var toSend = new ServiceBusMessage(received); AmqpAnnotatedMessage rawSend = toSend.GetRawAmqpMessage(); // verify that all system set properties have been cleared out Assert.IsNull(rawSend.Header.DeliveryCount); Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.LockedUntilName)); Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.SequenceNumberName)); Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.DeadLetterSourceName)); Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueueSequenceNumberName)); Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.EnqueuedTimeUtcName)); Assert.IsFalse(rawSend.MessageAnnotations.ContainsKey(AmqpMessageConstants.DeadLetterSourceName)); Assert.IsFalse(toSend.ApplicationProperties.ContainsKey(AmqpMessageConstants.DeadLetterReasonHeader)); Assert.IsFalse(toSend.ApplicationProperties.ContainsKey(AmqpMessageConstants.DeadLetterErrorDescriptionHeader)); AssertMessagesEqual(toSend, received); void AssertMessagesEqual(ServiceBusMessage sentMessage, ServiceBusReceivedMessage received) { Assert.IsTrue(received.Body.ToArray().SequenceEqual(sentMessage.Body.ToArray())); Assert.AreEqual(received.ContentType, sentMessage.ContentType); Assert.AreEqual(received.CorrelationId, sentMessage.CorrelationId); Assert.AreEqual(received.Subject, sentMessage.Subject); Assert.AreEqual(received.ContentType, sentMessage.ContentType); Assert.AreEqual(received.CorrelationId, sentMessage.CorrelationId); Assert.AreEqual(received.MessageId, sentMessage.MessageId); Assert.AreEqual(received.PartitionKey, sentMessage.PartitionKey); Assert.AreEqual((string)received.ApplicationProperties["testProp"], (string)sentMessage.ApplicationProperties["testProp"]); Assert.AreEqual(received.ReplyTo, sentMessage.ReplyTo); Assert.AreEqual(received.ReplyToSessionId, sentMessage.ReplyToSessionId); Assert.AreEqual(received.ScheduledEnqueueTime.UtcDateTime.Second, sentMessage.ScheduledEnqueueTime.UtcDateTime.Second); Assert.AreEqual(received.SessionId, sentMessage.SessionId); Assert.AreEqual(received.TimeToLive, sentMessage.TimeToLive); Assert.AreEqual(received.To, sentMessage.To); Assert.AreEqual(received.TransactionPartitionKey, sentMessage.TransactionPartitionKey); } } }
public void Should_set_message_type() { // Given var description = new QueueDescription(this.queueName); var listener = new ServiceBusClient( this.serialiser, this.bus); listener.Connect(this.connectionString, this.queueName, description); var payload = new Object(); A.CallTo(() => this.serialiser.Serialise(payload)) .Returns("FooBarBaz"); // When listener.Send("messageType", payload).Wait(); // Then this.bus.SentMessageType.ShouldEqual("messageType"); }
private static async Task Main(string[] args) { await using var stage = await Prepare.Stage(connectionString, destination); await using var serviceBusClient = new ServiceBusClient(connectionString); await using var sender = serviceBusClient.CreateSender(destination); var messages = new List <ServiceBusMessage>(); for (var i = 0; i < 10; i++) { var message = new ServiceBusMessage("Deep Dive{i}"); messages.Add(message); } WriteLine($"Sending {messages.Count} messages in a batch."); await sender.SendMessagesAsync(messages); messages.Clear(); WriteLine(); for (var i = 0; i < 6500; i++) { var message = new ServiceBusMessage($"Deep Dive{i}"); messages.Add(message); } try { WriteLine($"Sending {messages.Count} messages in a batch."); await sender.SendMessagesAsync(messages); } catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.MessageSizeExceeded) { await Error.WriteLineAsync(ex.Message); } messages.Clear(); WriteLine(); for (var i = 0; i < 101; i++) { var message = new ServiceBusMessage($"Deep Dive{i}"); messages.Add(message); } try { using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { WriteLine($"Sending {messages.Count} messages in a batch with in transaction '{Transaction.Current.TransactionInformation.LocalIdentifier}'."); await sender.SendMessagesAsync(messages); scope.Complete(); } } catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.QuotaExceeded) { await Error.WriteLineAsync(ex.Message); } var messagesToSend = new Queue <ServiceBusMessage>(); for (var i = 0; i < 4500; i++) { var message = new ServiceBusMessage($"Deep Dive{i}. Deep Dive{i}. Deep Dive{i}."); messagesToSend.Enqueue(message); } var messageCount = messagesToSend.Count; int batchCount = 1; while (messagesToSend.Count > 0) { using ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync(); if (messageBatch.TryAddMessage(messagesToSend.Peek())) { messagesToSend.Dequeue(); } else { throw new Exception($"Message {messageCount - messagesToSend.Count} is too large and cannot be sent."); } while (messagesToSend.Count > 0 && messageBatch.TryAddMessage(messagesToSend.Peek())) { messagesToSend.Dequeue(); } WriteLine($"Sending {messageBatch.Count} messages in a batch {batchCount++}."); await sender.SendMessagesAsync(messageBatch); } }
public ServiceBus(AppSettings settings) { _client = new ServiceBusClient(settings.ServiceBusSettings.ConnectionString); }
public async Task GetSessionStateAsyncValidatesClientIsNotDisposed() { await using var client = new ServiceBusClient("not.real.com", Mock.Of <TokenCredential>()); await using var receiver = new ServiceBusSessionReceiver(client.Connection, "fake", default, CancellationToken.None);
public async Task SendToServiceBusQueueAsync(Models.Customer customer, string reqUrl) { await ServiceBusClient.SendPostMessageAsync(customer, reqUrl); }
public override void ExecuteCmdlet() { try { // Delete Namespace authorizationRule if (ParameterSetName.Equals(NamespaceAuthoRuleParameterSet)) { ConfirmAction( Force.IsPresent, string.Format(Resources.RemovingNamespaceAuthorizationRule, Name, Namespace), string.Format(Resources.RemoveNamespaceAuthorizationRule, Name, Namespace), Name, () => { Client.DeleteNamespaceAuthorizationRules(ResourceGroupName, Namespace, Name); if (PassThru) { WriteObject(true); } }); } // Delete Queue authorizationRule if (ParameterSetName.Equals(QueueAuthoRuleParameterSet)) { ConfirmAction( Force.IsPresent, string.Format(Resources.RemovingQueueAuthorizationRule, Namespace, Queue, Name), string.Format(Resources.RemoveQueueAuthorizationRule, Namespace, Queue, Name), Name, () => { Client.DeleteServiceBusQueueAuthorizationRules(ResourceGroupName, Namespace, Queue, Name); if (PassThru) { WriteObject(true); } }); } // Delete Topic authorizationRule if (ParameterSetName.Equals(TopicAuthoRuleParameterSet)) { ConfirmAction( Force.IsPresent, string.Format(Resources.RemovingTopicAuthorizationRule, Namespace, Topic, Name), string.Format(Resources.RemoveTopicAuthorizationRule, Namespace, Topic, Name), Name, () => { Client.DeleteServiceBusTopicAuthorizationRule(ResourceGroupName, Namespace, Topic, Name); if (PassThru) { WriteObject(true); } }); } } catch (Management.ServiceBus.Models.ErrorResponseException ex) { WriteError(ServiceBusClient.WriteErrorforBadrequest(ex)); } }
public DefaultServiceBusPersisterConnection(string serviceBusConnectionString) { _serviceBusConnectionString = serviceBusConnectionString; _subscriptionClient = new ServiceBusAdministrationClient(_serviceBusConnectionString); _topicClient = new ServiceBusClient(_serviceBusConnectionString); }
public async Task DeadLetterMessagesSubscription(bool useSpecificSession) { await using (var scope = await ServiceBusScope.CreateWithTopic(enablePartitioning: false, enableSession: true)) { await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusSender sender = client.CreateSender(scope.TopicName); var messageCount = 10; var sessionId = "sessionId1"; using ServiceBusMessageBatch batch = await sender.CreateMessageBatchAsync(); IEnumerable <ServiceBusMessage> messages = AddMessages(batch, messageCount, sessionId).AsEnumerable <ServiceBusMessage>(); await sender.SendMessagesAsync(batch); var topicName = scope.TopicName; var subscriptionName = scope.SubscriptionNames.First(); var receiver = await client.CreateSessionReceiverAsync( topicName : topicName, subscriptionName : subscriptionName, new ServiceBusSessionReceiverOptions { SessionId = useSpecificSession ? sessionId : null }); var remainingMessages = messageCount; var messageEnum = messages.GetEnumerator(); while (remainingMessages > 0) { foreach (var item in await receiver.ReceiveMessagesAsync(remainingMessages)) { remainingMessages--; messageEnum.MoveNext(); Assert.AreEqual(messageEnum.Current.MessageId, item.MessageId); Assert.AreEqual(messageEnum.Current.SessionId, item.SessionId); var props = new Dictionary <string, object>(); // these should be ignored by DeadLetter property getters as they are not strings props[ServiceBusReceivedMessage.DeadLetterReasonHeader] = DateTime.UtcNow; props[ServiceBusReceivedMessage.DeadLetterErrorDescriptionHeader] = DateTime.UtcNow; await receiver.DeadLetterMessageAsync(item.LockToken, props); } } Assert.AreEqual(0, remainingMessages); var peekedMessage = receiver.PeekMessageAsync(); Assert.IsNull(peekedMessage.Result); messageEnum.Reset(); remainingMessages = messageCount; var deadLetterReceiver = client.CreateReceiver(topicName, subscriptionName, new ServiceBusReceiverOptions { SubQueue = SubQueue.DeadLetter }); while (remainingMessages > 0) { foreach (var msg in await deadLetterReceiver.ReceiveMessagesAsync(remainingMessages)) { remainingMessages--; messageEnum.MoveNext(); Assert.AreEqual(messageEnum.Current.MessageId, msg.MessageId); Assert.AreEqual(messageEnum.Current.SessionId, msg.SessionId); Assert.IsNull(msg.DeadLetterErrorDescription); Assert.IsNull(msg.DeadLetterReason); Assert.IsNotNull(msg.ApplicationProperties[ServiceBusReceivedMessage.DeadLetterReasonHeader]); Assert.IsNotNull(msg.ApplicationProperties[ServiceBusReceivedMessage.DeadLetterErrorDescriptionHeader]); await deadLetterReceiver.CompleteMessageAsync(msg.LockToken); } } Assert.AreEqual(0, remainingMessages); var deadLetterMessage = await deadLetterReceiver.PeekMessageAsync(); Assert.IsNull(deadLetterMessage); } }
public HomeController(IOptions <ServiceBusConfiguration> serviceBusConfig) { Config = serviceBusConfig.Value; client = new ServiceBusClient(Config.Namespace, new DefaultAzureCredential()); _startProcessingTask = ReceivedMessageStore.InitializeAsync(Config, client); }
public static int Main(string[] args) { var app = new CommandLineApplication(); app.HelpOption("-h|--help"); var connectionStringOption = app.Option("-c|--connection-string <string>", "The Azure Service Bus connection string", CommandOptionType.SingleValue).IsRequired(); var queueOption = app.Option("-q|--queue <string>", "The Azure Service Bus queue name", CommandOptionType.SingleValue).IsRequired(); var jobDefinitionsPathOption = app.Option("-j|--jobs <path>", "The path for the job definitions file", CommandOptionType.SingleValue).IsRequired(); app.OnExecuteAsync(async cancellationToken => { if (!File.Exists(jobDefinitionsPathOption.Value())) { Console.WriteLine($"The file '{0}' could not be found", jobDefinitionsPathOption.Value()); return; } var jobDefinitions = JsonSerializer.Deserialize <JobDefinitions>(File.ReadAllText(jobDefinitionsPathOption.Value()), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); ConnectionString = connectionStringOption.Value(); // Substitute with ENV value if it exists if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable(ConnectionString))) { ConnectionString = Environment.GetEnvironmentVariable(ConnectionString); } Queue = queueOption.Value(); // Substitute with ENV value if it exists if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable(Queue))) { Queue = Environment.GetEnvironmentVariable(Queue); } foreach (var job in jobDefinitions.Jobs) { if (!File.Exists(job.Value.Executable)) { Console.WriteLine($"The executable for the job '{job.Key}' could not be found at '{job.Value.Executable}'"); return; } } var client = new ServiceBusClient(ConnectionString); var processor = client.CreateProcessor(Queue, new ServiceBusProcessorOptions { AutoComplete = false, MaxConcurrentCalls = 1, // Process one message at a time }); // Whenever a message is available on the queue processor.ProcessMessageAsync += async args => { Console.WriteLine("Processing message '{0}'", args.Message.ToString()); var message = args.Message; JobPayload jobPayload; DevopsMessage devopsMessage = null; Job driverJob = null; try { // The DevopsMessage does the communications with AzDo devopsMessage = new DevopsMessage(message); // The Body contains the parameters for the application to run jobPayload = JobPayload.Deserialize(message.Body.ToArray()); if (!jobDefinitions.Jobs.TryGetValue(jobPayload.Name, out var job)) { throw new Exception("Invalid job name: " + jobPayload.Name); } await devopsMessage.SendTaskStartedEventAsync(); // The arguments are built from the Task payload and the ones // set on the command line var allArguments = jobPayload.Args.Union(job.Arguments).ToArray(); // Convert any arguments with the custom bindings foreach (var binding in job.Bindings.Keys) { if (job.Bindings[binding].StartsWith("env:")) { job.Bindings[binding] = Environment.GetEnvironmentVariable(binding.Substring(4)); } } // Create protected arguments string by hiding binding values for (var i = 0; i < allArguments.Length; i++) { var argument = allArguments[i]; if (job.Bindings.ContainsKey(argument)) { allArguments[i] = "****"; } } var sanitizedArguments = String.Join(' ', allArguments); for (var i = 0; i < allArguments.Length; i++) { var argument = allArguments[i]; if (job.Bindings.ContainsKey(argument)) { allArguments[i] = job.Bindings[argument]; } } var arguments = String.Join(' ', allArguments); Console.WriteLine("Invoking application with arguments: " + sanitizedArguments); // The DriverJob manages the application's lifetime and standard output driverJob = new Job(job.Executable, arguments); driverJob.OnStandardOutput = log => Console.WriteLine(log); Console.WriteLine("Processing..."); driverJob.Start(); // Pump application standard output while it's running while (driverJob.IsRunning) { if ((DateTime.UtcNow - driverJob.StartTimeUtc) > jobPayload.Timeout) { throw new Exception("Job timed out"); } var logs = driverJob.FlushStandardOutput().ToArray(); // Send any page of logs to the AzDo task log feed if (logs.Any()) { await devopsMessage.SendTaskLogFeedsAsync(String.Join("\r\n", logs)); } await Task.Delay(TaskLogFeedDelay); } // Mark the task as completed await devopsMessage.SendTaskCompletedEventAsync(succeeded: driverJob.WasSuccessful); // Create a task log entry var taskLogObjectString = await devopsMessage?.CreateTaskLogAsync(); var taskLogObject = JsonSerializer.Deserialize <Dictionary <string, object> >(taskLogObjectString); var taskLogId = taskLogObject["id"].ToString(); await devopsMessage?.AppendToTaskLogAsync(taskLogId, driverJob.OutputBuilder.ToString()); // Attach task log to the timeline record await devopsMessage?.UpdateTaskTimelineRecordAsync(taskLogObjectString); // Mark the message as completed await args.CompleteAsync(message); driverJob.Stop(); Console.WriteLine("Job completed"); } catch (Exception e) { Console.WriteLine("Job failed: " + e.Message); try { await devopsMessage?.SendTaskCompletedEventAsync(succeeded: false); await args.AbandonAsync(message); } catch (Exception f) { Console.WriteLine("Failed to abandon task: " + f.Message); } } finally { driverJob?.Dispose(); } }; processor.ProcessErrorAsync += args => { Console.WriteLine("Process error: " + args.Exception.ToString()); return(Task.CompletedTask); }; await processor.StartProcessingAsync(); Console.WriteLine("Press ENTER to exit..."); Console.ReadLine(); }); return(app.Execute(args)); }
public async Task AddGetAndRemoveRules() { await using (var scope = await ServiceBusScope.CreateWithTopic(enablePartitioning: false, enableSession: false)) { await using var client = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); ServiceBusRuleManager ruleManager = client.CreateRuleManager(scope.TopicName, scope.SubscriptionNames.First()); var sqlRuleName = "sqlRule"; var correlationRuleName = "correlationRule"; var rules = (await ruleManager.GetRulesAsync()).ToList(); Assert.AreEqual(1, rules.Count()); var firstRule = rules[0]; Assert.AreEqual(RuleDescription.DefaultRuleName, firstRule.Name); Assert.Null(firstRule.Action); await ruleManager.AddRuleAsync(sqlRuleName, new SqlRuleFilter("price > 10")); var ruleDescription = new RuleDescription(correlationRuleName) { Filter = new CorrelationRuleFilter { CorrelationId = "correlationId", Label = "label", MessageId = "messageId", Properties = { { "key1", "value1" } }, ReplyTo = "replyTo", ReplyToSessionId = "replyToSessionId", SessionId = "sessionId", To = "to" }, Action = new SqlRuleAction("Set CorrelationId = 'newValue'") }; await ruleManager.AddRuleAsync(ruleDescription); rules = (await ruleManager.GetRulesAsync()).ToList(); Assert.AreEqual(3, rules.Count); var sqlRule = rules.FirstOrDefault(rule => rule.Name.Equals(sqlRuleName)); Assert.NotNull(sqlRule); Assert.Null(sqlRule.Action); Assert.IsInstanceOf <SqlRuleFilter>(sqlRule.Filter); Assert.AreEqual("price > 10", ((SqlRuleFilter)sqlRule.Filter).SqlExpression); var correlationRule = rules.FirstOrDefault(rule => rule.Name.Equals(correlationRuleName)); Assert.NotNull(correlationRule); Assert.IsInstanceOf <SqlRuleAction>(correlationRule.Action); var sqlRuleAction = correlationRule.Action as SqlRuleAction; Assert.NotNull(sqlRuleAction); Assert.AreEqual("Set CorrelationId = 'newValue'", sqlRuleAction.SqlExpression); Assert.IsInstanceOf <CorrelationRuleFilter>(correlationRule.Filter); var correlationRuleFilter = correlationRule.Filter as CorrelationRuleFilter; Assert.NotNull(correlationRuleFilter); Assert.AreEqual("correlationId", correlationRuleFilter.CorrelationId); Assert.AreEqual("label", correlationRuleFilter.Label); Assert.AreEqual("messageId", correlationRuleFilter.MessageId); Assert.AreEqual("replyTo", correlationRuleFilter.ReplyTo); Assert.AreEqual("replyToSessionId", correlationRuleFilter.ReplyToSessionId); Assert.AreEqual("sessionId", correlationRuleFilter.SessionId); Assert.AreEqual("to", correlationRuleFilter.To); Assert.NotNull(correlationRuleFilter.Properties); Assert.AreEqual("value1", correlationRuleFilter.Properties["key1"]); await ruleManager.RemoveRuleAsync(RuleDescription.DefaultRuleName); await ruleManager.RemoveRuleAsync(sqlRuleName); await ruleManager.RemoveRuleAsync(correlationRuleName); rules = (await ruleManager.GetRulesAsync()).ToList(); Assert.AreEqual(0, rules.Count()); } }
internal void StartMessageBatchReceiver(CancellationToken cancellationToken) { ServiceBusClient sessionClient = null; ServiceBusReceiver receiver = null; if (_isSessionsEnabled) { sessionClient = _sessionClient.Value; } else { receiver = BatchReceiver; } Task.Run(async() => { while (true) { try { if (!_started || cancellationToken.IsCancellationRequested) { _logger.LogInformation("Message processing has been stopped or cancelled"); return; } if (_isSessionsEnabled && (receiver == null || receiver.IsClosed)) { try { receiver = await sessionClient.AcceptNextSessionAsync(_entityPath, new ServiceBusSessionReceiverOptions { PrefetchCount = _serviceBusOptions.PrefetchCount }).ConfigureAwait(false); } catch (ServiceBusException ex) when(ex.Reason == ServiceBusFailureReason.ServiceTimeout) { // it's expected if the entity is empty, try next time continue; } } IReadOnlyList <ServiceBusReceivedMessage> messages = await receiver.ReceiveMessagesAsync(_serviceBusOptions.MaxMessages).ConfigureAwait(false); if (messages != null) { ServiceBusReceivedMessage[] messagesArray = messages.ToArray(); ServiceBusTriggerInput input = ServiceBusTriggerInput.CreateBatch(messagesArray); if (_isSessionsEnabled) { input.MessageActions = new ServiceBusSessionMessageActions((ServiceBusSessionReceiver)receiver); } else { input.MessageActions = new ServiceBusMessageActions(receiver); } FunctionResult result = await _triggerExecutor.TryExecuteAsync(input.GetTriggerFunctionData(), cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return; } // Complete batch of messages only if the execution was successful if (_serviceBusOptions.AutoCompleteMessages && _started) { if (result.Succeeded) { List <Task> completeTasks = new List <Task>(); foreach (ServiceBusReceivedMessage message in messagesArray) { completeTasks.Add(receiver.CompleteMessageAsync(message)); } await Task.WhenAll(completeTasks).ConfigureAwait(false); } else { List <Task> abandonTasks = new List <Task>(); foreach (ServiceBusReceivedMessage message in messagesArray) { abandonTasks.Add(receiver.AbandonMessageAsync(message)); } await Task.WhenAll(abandonTasks).ConfigureAwait(false); } } } else { // Close the session and release the session lock after draining all messages for the accepted session. if (_isSessionsEnabled) { await receiver.CloseAsync().ConfigureAwait(false); } } } catch (ObjectDisposedException) { // Ignore as we are stopping the host } catch (Exception ex) { // Log another exception _logger.LogError(ex, $"An unhandled exception occurred in the message batch receive loop"); if (_isSessionsEnabled && receiver != null) { // Attempt to close the session and release session lock to accept a new session on the next loop iteration try { await receiver.CloseAsync().ConfigureAwait(false); } catch { // Best effort receiver = null; } } } } }, cancellationToken); }
public async Task SendToServiceBusQueueAsync(Models.Goal Goals, Guid customerId, string reqUrl) { await ServiceBusClient.SendPatchMessageAsync(Goals, customerId, reqUrl); }
public ServiceBusEventBus(ServiceBusClient serviceBusClient) { this.serviceBusClient = serviceBusClient; serviceBusSender = serviceBusClient.CreateSender(queueName); }
/// <summary> /// This method causes the communication listener to close. Close is a terminal state and /// this method allows the communication listener to transition to this state in a /// graceful manner. /// </summary> /// <param name="cancellationToken">Cancellation token</param> /// <returns> /// A <see cref="T:System.Threading.Tasks.Task">Task</see> that represents outstanding operation. /// </returns> protected override async Task CloseImplAsync(CancellationToken cancellationToken) { await ServiceBusClient.CloseAsync(); }
public async Task GetQueueRuntimeInfo() { var queueName = nameof(GetQueueRuntimeInfo).ToLower() + Recording.Random.NewGuid().ToString("D").Substring(0, 8); var mgmtClient = GetClient(); await using var sbClient = new ServiceBusClient(TestEnvironment.ServiceBusConnectionString); QueueProperties queue = await mgmtClient.CreateQueueAsync(queueName); queue = await mgmtClient.GetQueueAsync(queueName); // Changing Last Updated Time queue.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); QueueProperties updatedQueue = await mgmtClient.UpdateQueueAsync(queue); // Populating 1 active message, 1 dead letter message and 1 scheduled message // Changing Last Accessed Time ServiceBusSender sender = sbClient.CreateSender(queueName); await sender.SendMessageAsync(new ServiceBusMessage() { MessageId = "1" }); await sender.SendMessageAsync(new ServiceBusMessage() { MessageId = "2" }); await sender.SendMessageAsync(new ServiceBusMessage() { MessageId = "3", ScheduledEnqueueTime = DateTime.UtcNow.AddDays(1) }); ServiceBusReceiver receiver = sbClient.CreateReceiver(queueName); ServiceBusReceivedMessage msg = await receiver.ReceiveMessageAsync(); await receiver.DeadLetterMessageAsync(msg.LockToken); List <QueueRuntimeProperties> runtimeInfoList = new List <QueueRuntimeProperties>(); await foreach (QueueRuntimeProperties queueRuntimeInfo in mgmtClient.GetQueuesRuntimePropertiesAsync()) { runtimeInfoList.Add(queueRuntimeInfo); } runtimeInfoList = runtimeInfoList.Where(e => e.Name.StartsWith(nameof(GetQueueRuntimeInfo).ToLower())).ToList(); Assert.True(runtimeInfoList.Count == 1, $"Expected 1 queue but {runtimeInfoList.Count} queues returned"); QueueRuntimeProperties runtimeInfo = runtimeInfoList.First(); Assert.NotNull(runtimeInfo); Assert.AreEqual(queueName, runtimeInfo.Name); Assert.True(runtimeInfo.CreatedAt < runtimeInfo.UpdatedAt); Assert.True(runtimeInfo.UpdatedAt < runtimeInfo.AccessedAt); Assert.AreEqual(1, runtimeInfo.ActiveMessageCount); Assert.AreEqual(1, runtimeInfo.DeadLetterMessageCount); Assert.AreEqual(1, runtimeInfo.ScheduledMessageCount); Assert.AreEqual(3, runtimeInfo.TotalMessageCount); Assert.True(runtimeInfo.SizeInBytes > 0); QueueRuntimeProperties singleRuntimeInfo = await mgmtClient.GetQueueRuntimePropertiesAsync(runtimeInfo.Name); Assert.AreEqual(runtimeInfo.AccessedAt, singleRuntimeInfo.AccessedAt); Assert.AreEqual(runtimeInfo.CreatedAt, singleRuntimeInfo.CreatedAt); Assert.AreEqual(runtimeInfo.UpdatedAt, singleRuntimeInfo.UpdatedAt); Assert.AreEqual(runtimeInfo.TotalMessageCount, singleRuntimeInfo.TotalMessageCount); Assert.AreEqual(runtimeInfo.ActiveMessageCount, singleRuntimeInfo.ActiveMessageCount); Assert.AreEqual(runtimeInfo.DeadLetterMessageCount, singleRuntimeInfo.DeadLetterMessageCount); Assert.AreEqual(runtimeInfo.ScheduledMessageCount, singleRuntimeInfo.ScheduledMessageCount); Assert.AreEqual(runtimeInfo.SizeInBytes, singleRuntimeInfo.SizeInBytes); await mgmtClient.DeleteQueueAsync(queueName); }
/// <inheritdoc /> public override Task Complete(Message message) { return(ServiceBusClient.CompleteAsync(message.SystemProperties.LockToken)); }