public async Task BasicRulesCrudTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); try { await client.CreateTopicAsync(topicName); await client.CreateSubscriptionAsync( new SubscriptionDescription(topicName, subscriptionName), new RuleDescription("rule0", new FalseFilter())); var sqlFilter = new SqlFilter("stringValue = @stringParam AND intValue = @intParam AND longValue = @longParam AND dateValue = @dateParam AND timeSpanValue = @timeSpanParam"); sqlFilter.Parameters.Add("@stringParam", "string"); sqlFilter.Parameters.Add("@intParam", (int)1); sqlFilter.Parameters.Add("@longParam", (long)12); sqlFilter.Parameters.Add("@dateParam", DateTime.UtcNow); sqlFilter.Parameters.Add("@timeSpanParam", TimeSpan.FromDays(1)); var rule1 = new RuleDescription { Name = "rule1", Filter = sqlFilter, Action = new SqlRuleAction("SET a='b'") }; await client.CreateRuleAsync(topicName, subscriptionName, rule1); var correlationFilter = new CorrelationFilter() { ContentType = "contentType", CorrelationId = "correlationId", Label = "label", MessageId = "messageId", ReplyTo = "replyTo", ReplyToSessionId = "replyToSessionId", SessionId = "sessionId", To = "to" }; correlationFilter.Properties.Add("customKey", "customValue"); var rule2 = new RuleDescription() { Name = "rule2", Filter = correlationFilter, Action = null }; await client.CreateRuleAsync(topicName, subscriptionName, rule2); var rules = await client.GetRulesAsync(topicName, subscriptionName); Assert.True(rules.Count == 3); Assert.Equal("rule0", rules[0].Name); Assert.Equal(rule1, rules[1]); Assert.Equal(rule2, rules[2]); ((CorrelationFilter)rule2.Filter).CorrelationId = "correlationIdModified"; var updatedRule2 = await client.UpdateRuleAsync(topicName, subscriptionName, rule2); Assert.Equal(rule2, updatedRule2); var defaultRule = await client.GetRuleAsync(topicName, subscriptionName, "rule0"); Assert.NotNull(defaultRule); await client.DeleteRuleAsync(topicName, subscriptionName, "rule0"); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetRuleAsync(topicName, subscriptionName, "rule0"); }); await client.DeleteTopicAsync(topicName); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await client.CloseAsync(); } }
public async Task BasicTopicCrudTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); try { var td = new TopicDescription(topicName) { AutoDeleteOnIdle = TimeSpan.FromHours(1), DefaultMessageTimeToLive = TimeSpan.FromDays(2), DuplicateDetectionHistoryTimeWindow = TimeSpan.FromMinutes(1), EnableBatchedOperations = true, EnablePartitioning = false, MaxSizeInMB = 2048, RequiresDuplicateDetection = true, UserMetadata = nameof(BasicTopicCrudTest) }; td.AuthorizationRules.Add(new SharedAccessAuthorizationRule( "allClaims", new[] { AccessRights.Manage, AccessRights.Send, AccessRights.Listen })); var createdT = await client.CreateTopicAsync(td); Assert.Equal(td, createdT); var getT = await client.GetTopicAsync(td.Path); Assert.Equal(td, getT); getT.EnableBatchedOperations = false; getT.DefaultMessageTimeToLive = TimeSpan.FromDays(3); var updatedT = await client.UpdateTopicAsync(getT); Assert.Equal(getT, updatedT); var exists = await client.TopicExistsAsync(topicName); Assert.True(exists); var topics = await client.GetTopicsAsync(); Assert.True(topics.Count >= 1); Assert.Contains(topics, e => e.Path.Equals(topicName, StringComparison.OrdinalIgnoreCase)); await client.DeleteTopicAsync(updatedT.Path); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetTopicAsync(td.Path); }); exists = await client.TopicExistsAsync(topicName); Assert.False(exists); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await client.CloseAsync(); } }
public async Task BasicSubscriptionCrudTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); try { await client.CreateTopicAsync(topicName); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); var sd = new SubscriptionDescription(topicName, subscriptionName) { AutoDeleteOnIdle = TimeSpan.FromHours(1), DefaultMessageTimeToLive = TimeSpan.FromDays(2), EnableDeadLetteringOnMessageExpiration = true, EnableBatchedOperations = false, ForwardDeadLetteredMessagesTo = null, ForwardTo = null, LockDuration = TimeSpan.FromSeconds(45), MaxDeliveryCount = 8, RequiresSession = true, UserMetadata = nameof(BasicSubscriptionCrudTest) }; var createdS = await client.CreateSubscriptionAsync(sd); Assert.Equal(sd, createdS); var getS = await client.GetSubscriptionAsync(sd.TopicPath, sd.SubscriptionName); Assert.Equal(sd, getS); getS.DefaultMessageTimeToLive = TimeSpan.FromDays(3); getS.MaxDeliveryCount = 9; var updatedS = await client.UpdateSubscriptionAsync(getS); Assert.Equal(getS, updatedS); var exists = await client.SubscriptionExistsAsync(topicName, subscriptionName); Assert.True(exists); var subs = await client.GetSubscriptionsAsync(topicName); Assert.Equal(1, subs.Count); await client.DeleteSubscriptionAsync(sd.TopicPath, sd.SubscriptionName); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetSubscriptionAsync(sd.TopicPath, sd.SubscriptionName); }); await client.DeleteTopicAsync(sd.TopicPath); exists = await client.SubscriptionExistsAsync(topicName, subscriptionName); Assert.False(exists); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await client.CloseAsync(); } }
public override async Task RunAsync() { _logger.LogInformation("Enter name:"); var userName = Console.ReadLine(); // Create a management client to manage artifacts var manager = new ManagementClient(_configurations.ConnectionString); // Create a topic if it does not exist if (!await manager.TopicExistsAsync(_configurations.ChatTopicPath)) { await manager.CreateTopicAsync(_configurations.ChatTopicPath); } // Create a subscription for the user var description = new SubscriptionDescription(_configurations.ChatTopicPath, userName) { AutoDeleteOnIdle = TimeSpan.FromMinutes(5) }; manager.CreateSubscriptionAsync(description).Wait(); // Create clients _topicClient = new TopicClient(_configurations.ConnectionString, _configurations.ChatTopicPath); _subscriptionClient = new SubscriptionClient(_configurations.ConnectionString, _configurations.ChatTopicPath, userName); // Create a message pump for receiving messages _subscriptionClient.RegisterMessageHandler(ProcessMessagesAsync, ExceptionReceivedHandler); // Send a message to say you are here var helloMessage = new Message(Encoding.UTF8.GetBytes("Has entered the room...")) { Label = userName }; _topicClient.SendAsync(helloMessage).Wait(); while (true) { string text = Console.ReadLine(); if (text.Equals("exit")) { break; } // Send a chat message var chatMessage = new Message(Encoding.UTF8.GetBytes(text)) { Label = userName }; await _topicClient.SendAsync(chatMessage); } // Send a message to say you are leaving var goodbyeMessage = new Message(Encoding.UTF8.GetBytes("Has left the building...")) { Label = userName }; _topicClient.SendAsync(goodbyeMessage).Wait(); }
public async Task StartAsync(CancellationToken cancellationToken) { _cancellationToken = cancellationToken; _client = await _clientFactory.GetSubscriptionClient <TTopic, IEventSubscription <TTopic> >(_subscription).ConfigureAwait(false); if (!await _managementClient.TopicExistsAsync(_client.TopicPath, cancellationToken).ConfigureAwait(false)) { try { var serviceBusCreationOptions = GetServiceBusCreationOptions(); await _managementClient.CreateTopicAsync(new TopicDescription(_client.TopicPath) { EnableBatchedOperations = serviceBusCreationOptions.EnableBatchedOperations, EnablePartitioning = serviceBusCreationOptions.EnablePartitioning, SupportOrdering = serviceBusCreationOptions.SupportOrdering }, cancellationToken).ConfigureAwait(false); } catch (ServiceBusException e) { _log.Error(e, "Failed to create topic {TopicName}", _client.TopicPath); throw; } } if (!await _managementClient.SubscriptionExistsAsync(_client.TopicPath, _client.SubscriptionName, cancellationToken).ConfigureAwait(false)) { try { var serviceBusCreationOptions = GetServiceBusCreationOptions(); await _managementClient.CreateSubscriptionAsync(new SubscriptionDescription(_client.TopicPath, _client.SubscriptionName) { EnableBatchedOperations = serviceBusCreationOptions.EnableBatchedOperations, }, cancellationToken).ConfigureAwait(false); } catch (ServiceBusException e) { _log.Error(e, "Failed to create subscription {TopicName} {SubscriptionName}", _client.TopicPath, _client.SubscriptionName); throw; } } _deadLetterLimit = Settings.DeadLetterDeliveryLimit; _client.PrefetchCount = Settings.PrefetchCount; _messageReceiver = new StoppableMessageReceiver(_client.ServiceBusConnection, EntityNameHelper.FormatSubscriptionPath(_client.TopicPath, _client.SubscriptionName), ReceiveMode.PeekLock, RetryPolicy.Default, Settings.PrefetchCount); var options = new StoppableMessageReceiver.MessageHandlerOptions(OnExceptionReceivedAsync) { AutoComplete = false, MaxAutoRenewDuration = Settings.MessageLockTimeout, MaxConcurrentCalls = Settings.MaxConcurrentCalls }; _messageReceiver.RegisterStoppableMessageHandler(options, OnMessageAsync); #pragma warning disable 4014 // ReSharper disable once MethodSupportsCancellation Task.Run(() => { _cancellationToken.WaitHandle.WaitOne(); //Cancellation requested try { _log.Information($"Closing ServiceBus channel receiver for {typeof(TTopic).Name}"); _messageReceiver.StopPump(); } catch (Exception) { //Swallow } }); #pragma warning restore 4014 }
public async Task GetTopicRuntimeInfoTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); var sender = new MessageSender(TestUtility.NamespaceConnectionString, topicName); try { var td = await client.CreateTopicAsync(topicName); // Changing Last Updated Time td.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); await client.UpdateTopicAsync(td); await client.CreateSubscriptionAsync(topicName, subscriptionName); // Populating 1 active message and 1 scheduled message // Changing Last Accessed Time await sender.SendAsync(new Message() { MessageId = "1" }); await sender.SendAsync(new Message() { MessageId = "2" }); await sender.SendAsync(new Message() { MessageId = "3", ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddDays(1) }); var topicsRI = await client.GetTopicsRuntimeInfoAsync(); var topicRI = topicsRI.FirstOrDefault(t => topicName.Equals(t.Path, StringComparison.OrdinalIgnoreCase)); Assert.Equal(topicName, topicRI.Path); Assert.True(topicRI.CreatedAt < topicRI.UpdatedAt); Assert.True(topicRI.UpdatedAt < topicRI.AccessedAt); Assert.Equal(0, topicRI.MessageCountDetails.ActiveMessageCount); Assert.Equal(0, topicRI.MessageCountDetails.DeadLetterMessageCount); Assert.Equal(1, topicRI.MessageCountDetails.ScheduledMessageCount); Assert.Equal(1, topicRI.SubscriptionCount); Assert.True(topicRI.SizeInBytes > 0); var singleTopicRI = await client.GetTopicRuntimeInfoAsync(topicRI.Path); Assert.Equal(topicRI.AccessedAt, singleTopicRI.AccessedAt); Assert.Equal(topicRI.CreatedAt, singleTopicRI.CreatedAt); Assert.Equal(topicRI.UpdatedAt, singleTopicRI.UpdatedAt); Assert.Equal(topicRI.MessageCountDetails.ActiveMessageCount, singleTopicRI.MessageCountDetails.ActiveMessageCount); Assert.Equal(topicRI.MessageCountDetails.DeadLetterMessageCount, singleTopicRI.MessageCountDetails.DeadLetterMessageCount); Assert.Equal(topicRI.MessageCountDetails.ScheduledMessageCount, singleTopicRI.MessageCountDetails.ScheduledMessageCount); Assert.Equal(topicRI.SizeInBytes, singleTopicRI.SizeInBytes); Assert.Equal(topicRI.SubscriptionCount, singleTopicRI.SubscriptionCount); await client.DeleteSubscriptionAsync(topicName, subscriptionName); await client.DeleteTopicAsync(topicName); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await sender.CloseAsync(); await client.CloseAsync(); } }
public async Task MessagingEntityNotFoundExceptionTest() { var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); try { await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetQueueAsync("NonExistingPath"); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetSubscriptionAsync("NonExistingTopic", "NonExistingPath"); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.UpdateQueueAsync(new QueueDescription("NonExistingPath")); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.UpdateTopicAsync(new TopicDescription("NonExistingPath")); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.UpdateSubscriptionAsync(new SubscriptionDescription("NonExistingTopic", "NonExistingPath")); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.DeleteQueueAsync("NonExistingPath"); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.DeleteTopicAsync("NonExistingPath"); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.DeleteSubscriptionAsync("NonExistingTopic", "NonExistingPath"); }); var queueName = Guid.NewGuid().ToString("D").Substring(0, 8); var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); try { await client.CreateQueueAsync(queueName); await client.CreateTopicAsync(topicName); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetQueueAsync(topicName); }); await Assert.ThrowsAsync <MessagingEntityNotFoundException>( async() => { await client.GetTopicAsync(queueName); }); // Cleanup await client.DeleteQueueAsync(queueName); await client.DeleteTopicAsync(topicName); } catch { await Task.WhenAll(SafeDeleteQueue(client, queueName), SafeDeleteTopic(client, topicName)); throw; } } finally { await client.CloseAsync(); } }
public async Task GetSubscriptionRuntimeInfoTest() { var topicName = Guid.NewGuid().ToString("D").Substring(0, 8); var subscriptionName = Guid.NewGuid().ToString("D").Substring(0, 8); var client = new ManagementClient(new ServiceBusConnectionStringBuilder(TestUtility.NamespaceConnectionString)); var sender = new MessageSender(TestUtility.NamespaceConnectionString, topicName); var receiver = new MessageReceiver(TestUtility.NamespaceConnectionString, EntityNameHelper.FormatSubscriptionPath(topicName, subscriptionName)); try { var td = await client.CreateTopicAsync(topicName); // Changing Last Updated Time td.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); await client.UpdateTopicAsync(td); var sd = await client.CreateSubscriptionAsync(topicName, subscriptionName); // Changing Last Updated Time for subscription sd.AutoDeleteOnIdle = TimeSpan.FromMinutes(100); await client.UpdateSubscriptionAsync(sd); // Populating 1 active message, 1 dead letter message and 1 scheduled message // Changing Last Accessed Time await sender.SendAsync(new Message() { MessageId = "1" }); await sender.SendAsync(new Message() { MessageId = "2" }); await sender.SendAsync(new Message() { MessageId = "3", ScheduledEnqueueTimeUtc = DateTime.UtcNow.AddDays(1) }); var msg = await receiver.ReceiveAsync(); await receiver.DeadLetterAsync(msg.SystemProperties.LockToken); var subscriptionsRI = await client.GetSubscriptionsRuntimeInfoAsync(topicName); var subscriptionRI = subscriptionsRI.FirstOrDefault(s => subscriptionName.Equals(s.SubscriptionName, StringComparison.OrdinalIgnoreCase)); Assert.Equal(topicName, subscriptionRI.TopicPath); Assert.Equal(subscriptionName, subscriptionRI.SubscriptionName); Assert.True(subscriptionRI.CreatedAt < subscriptionRI.UpdatedAt); Assert.True(subscriptionRI.UpdatedAt < subscriptionRI.AccessedAt); Assert.Equal(1, subscriptionRI.MessageCountDetails.ActiveMessageCount); Assert.Equal(1, subscriptionRI.MessageCountDetails.DeadLetterMessageCount); Assert.Equal(0, subscriptionRI.MessageCountDetails.ScheduledMessageCount); Assert.Equal(2, subscriptionRI.MessageCount); var singleSubscriptionRI = await client.GetSubscriptionRuntimeInfoAsync(topicName, subscriptionName); Assert.Equal(subscriptionRI.CreatedAt, singleSubscriptionRI.CreatedAt); Assert.Equal(subscriptionRI.AccessedAt, singleSubscriptionRI.AccessedAt); Assert.Equal(subscriptionRI.UpdatedAt, singleSubscriptionRI.UpdatedAt); Assert.Equal(subscriptionRI.SubscriptionName, singleSubscriptionRI.SubscriptionName); Assert.Equal(subscriptionRI.MessageCount, singleSubscriptionRI.MessageCount); Assert.Equal(subscriptionRI.MessageCountDetails.ActiveMessageCount, singleSubscriptionRI.MessageCountDetails.ActiveMessageCount); Assert.Equal(subscriptionRI.MessageCountDetails.DeadLetterMessageCount, singleSubscriptionRI.MessageCountDetails.DeadLetterMessageCount); Assert.Equal(subscriptionRI.MessageCountDetails.ScheduledMessageCount, singleSubscriptionRI.MessageCountDetails.ScheduledMessageCount); Assert.Equal(subscriptionRI.TopicPath, singleSubscriptionRI.TopicPath); await client.DeleteSubscriptionAsync(topicName, subscriptionName); await client.DeleteTopicAsync(topicName); } catch { await SafeDeleteTopic(client, topicName); throw; } finally { await sender.CloseAsync(); await receiver.CloseAsync(); await client.CloseAsync(); } }
public async Task CreateQueueIfNecessary(QueueBindings queueBindings, string identity) { var result = await namespacePermissions.CanManage().ConfigureAwait(false); if (!result.Succeeded) { throw new Exception(result.ErrorMessage); } var client = new ManagementClient(connectionStringBuilder, tokenProvider); try { var topic = new TopicDescription(topicName) { EnableBatchedOperations = true, EnablePartitioning = enablePartitioning, MaxSizeInMB = maxSizeInMB }; try { await client.CreateTopicAsync(topic).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { } // TODO: refactor when https://github.com/Azure/azure-service-bus-dotnet/issues/525 is fixed catch (ServiceBusException sbe) when(sbe.Message.Contains("SubCode=40901.")) // An operation is in progress. { } foreach (var address in queueBindings.ReceivingAddresses.Concat(queueBindings.SendingAddresses)) { var queue = new QueueDescription(address) { EnableBatchedOperations = true, LockDuration = TimeSpan.FromMinutes(5), MaxDeliveryCount = int.MaxValue, MaxSizeInMB = maxSizeInMB, EnablePartitioning = enablePartitioning }; try { await client.CreateQueueAsync(queue).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { } // TODO: refactor when https://github.com/Azure/azure-service-bus-dotnet/issues/525 is fixed catch (ServiceBusException sbe) when(sbe.Message.Contains("SubCode=40901.")) // An operation is in progress. { } } var subscriptionName = subscriptionFactory(mainInputQueueName); var subscription = new SubscriptionDescription(topicName, subscriptionName) { LockDuration = TimeSpan.FromMinutes(5), ForwardTo = mainInputQueueName, EnableDeadLetteringOnFilterEvaluationExceptions = false, MaxDeliveryCount = int.MaxValue, EnableBatchedOperations = true, UserMetadata = mainInputQueueName }; try { await client.CreateSubscriptionAsync(subscription, new RuleDescription("$default", new FalseFilter())).ConfigureAwait(false); } catch (MessagingEntityAlreadyExistsException) { } // TODO: refactor when https://github.com/Azure/azure-service-bus-dotnet/issues/525 is fixed catch (ServiceBusException sbe) when(sbe.Message.Contains("SubCode=40901.")) // An operation is in progress. { } } finally { await client.CloseAsync().ConfigureAwait(false); } }
internal async Task RunAsync() { try { // We use the Topic/Subscription pattern which is a pub/sub model where each Server will send // messages to this Topic, and every other server has a Subscription to receive those messages. // If the Message has a "To" field then the server ignores the message as it was not meant for them. // Otherwise the Message is considered a "broadcast" to all servers and each server will handle it. // The client also has a subcription on the same topic and is how it broadcasts requests and receives // the final response from the elected Leader. var managementClient = new ManagementClient(this.ConnectionString); if (!await managementClient.TopicExistsAsync(this.TopicName)) { await managementClient.CreateTopicAsync(this.TopicName); } // then we need a subscription, whether we are client or server and the subscription name will be // the same as our local actorid. string subscriptionName = (this.ServerId < 0) ? "Client" : $"Server-{this.ServerId}"; if (!await managementClient.SubscriptionExistsAsync(this.TopicName, subscriptionName)) { await managementClient.CreateSubscriptionAsync( new SubscriptionDescription(this.TopicName, subscriptionName)); } Console.WriteLine("Running " + subscriptionName); IActorRuntime runtime = RuntimeFactory.Create(Configuration.Create().WithVerbosityEnabled()); if (this.GraphIt) { var graphBuilder = new ActorRuntimeLogGraphBuilder(false); runtime.RegisterLog(graphBuilder); _ = Task.Run(() => { PeriodicSaves(graphBuilder, subscriptionName); }); } // We create a new Coyote actor runtime instance, and pass an optional configuration // that increases the verbosity level to see the Coyote runtime log. runtime.OnFailure += RuntimeOnFailure; var topicClient = new TopicClient(this.ConnectionString, this.TopicName); // cluster manager needs the topic client in order to be able to broadcast messages using Azure Service Bus var clusterManager = runtime.CreateActor(typeof(AzureClusterManager), new AzureClusterManager.RegisterMessageBusEvent() { TopicClient = topicClient }); if (this.ServerId < 0) { await this.RunClient(runtime, clusterManager, subscriptionName); } else { await this.RunServer(runtime, clusterManager, subscriptionName); } } catch (Exception ex) { Console.WriteLine($"{DateTime.Now} :: ex: {ex.ToString()}"); } }
Task <TopicDescription> CreateTopicAsync(TopicDescription topicDescription) { return(RunOperation(() => _managementClient.CreateTopicAsync(topicDescription))); }
public Task <TopicDescription> CreateTopicAsync(TopicDescription topicDescription) { return(_managementClient.CreateTopicAsync(topicDescription)); }