public static IEventHandler UseServiceBusForDurability( this object handler, ServiceBusSettings settings, string handlerCatchupAlias = null, Configuration configuration = null) { if (handler == null) { throw new ArgumentNullException("handler"); } if (settings == null) { throw new ArgumentNullException("settings"); } configuration = configuration ?? Configuration.Global; var queues = new Dictionary <Type, QueueClient>(); var binders = EventHandler.GetBinders(handler); // create queues var subscriptions = binders.Select(binder => SubscribeToReceiveMessages(binder, handler, settings, configuration, queues)) .ToArray(); configuration.RegisterDisposable(new CompositeDisposable(subscriptions)); // intercept events for the consequenter and queue them on Service Bus var wrappedHandler = handler.WrapAll(SimulatedSend ?? SendMessage(queues)); return(wrappedHandler); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusCommandQueueReceiver"/> class. /// </summary> /// <param name="settings">The service bus settings.</param> /// <param name="clockTrigger">The command clockTrigger.</param> /// <exception cref="System.ArgumentNullException"> /// settings /// or /// clockTrigger /// </exception> public ServiceBusCommandQueueReceiver( ServiceBusSettings settings, ISchedulerClockTrigger clockTrigger, Func <CommandSchedulerDbContext> createCommandSchedulerDbContext) { if (settings == null) { throw new ArgumentNullException("settings"); } if (clockTrigger == null) { throw new ArgumentNullException("clockTrigger"); } if (createCommandSchedulerDbContext == null) { throw new ArgumentNullException("createCommandSchedulerDbContext"); } this.settings = settings; this.clockTrigger = clockTrigger; this.createCommandSchedulerDbContext = createCommandSchedulerDbContext; #if DEBUG exceptionSubject .Where(ex => !(ex is OperationCanceledException)) .Subscribe(ex => Debug.WriteLine("ServiceBusCommandQueueReceiver error: " + ex)); #endif }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusCommandQueueReceiver"/> class. /// </summary> /// <param name="settings">The service bus settings.</param> /// <param name="clockTrigger">The command clockTrigger.</param> /// <exception cref="System.ArgumentNullException"> /// settings /// or /// clockTrigger /// </exception> public ServiceBusCommandQueueReceiver( ServiceBusSettings settings, ISchedulerClockTrigger clockTrigger, Func<CommandSchedulerDbContext> createCommandSchedulerDbContext) { if (settings == null) { throw new ArgumentNullException("settings"); } if (clockTrigger == null) { throw new ArgumentNullException("clockTrigger"); } if (createCommandSchedulerDbContext == null) { throw new ArgumentNullException("createCommandSchedulerDbContext"); } this.settings = settings; this.clockTrigger = clockTrigger; this.createCommandSchedulerDbContext = createCommandSchedulerDbContext; #if DEBUG exceptionSubject .Where(ex => !(ex is OperationCanceledException)) .Subscribe(ex => Debug.WriteLine("ServiceBusCommandQueueReceiver error: " + ex)); #endif }
private static void CreateTopicIfDoesNotAlreadyExist( this ServiceBusSettings settings, TopicDescription topicDescription) { var namespaceManager = NamespaceManager.CreateFromConnectionString(settings.ConnectionString); if (!namespaceManager.TopicExists(topicDescription.Path)) { namespaceManager.CreateTopic(topicDescription); } }
private static void CreateSubscriptionIfDoesNotAlreadyExist( this ServiceBusSettings settings, SubscriptionDescription subscriptionDescription) { var namespaceManager = NamespaceManager.CreateFromConnectionString(settings.ConnectionString); if (!namespaceManager.SubscriptionExists(subscriptionDescription.TopicPath, subscriptionDescription.Name)) { namespaceManager.CreateSubscription(subscriptionDescription); } }
private static void CreateQueueIfDoesNotAlreadyExist( this ServiceBusSettings settings, QueueDescription queueDescription) { var namespaceManager = NamespaceManager.CreateFromConnectionString(settings.ConnectionString); if (!namespaceManager.QueueExists(queueDescription.Path)) { namespaceManager.CreateQueue(queueDescription); } }
private static IDisposable SubscribeToReceiveMessages <THandler>( IEventHandlerBinder binder, THandler handler, ServiceBusSettings settings, Configuration configuration, Dictionary <Type, QueueClient> queues) where THandler : class { Type eventType = ((dynamic)binder).EventType; var queueName = string.Format("{0}_on_{1}.{2}", EventHandler.Name(handler), eventType.AggregateTypeForEventType().Name, eventType.EventName()); var bus = new InProcessEventBus(errorSubject: (ISubject <EventHandlingError>)configuration.EventBus.Errors); var eventBusSubscription = binder.SubscribeToBus(handler, bus); var receive = SimulatedReceive; if (receive != null) { var receiveSubscription = receive.Subscribe(e => bus.PublishAsync(e).Subscribe(_ => { }, ex => bus.PublishErrorAsync(new EventHandlingError(ex, @event: e)))); return(new CompositeDisposable(eventBusSubscription, receiveSubscription)); } var queueClient = settings.CreateQueueClient( queueName, settings.ConfigureQueue); // starting listening on the queue for incoming events queueClient.OnMessage(msg => { var storedEvent = msg.GetBody <string>() .FromJsonTo <StoredEvent>(); var @event = Serializer.DeserializeEvent( aggregateName: storedEvent.AggregateName, eventName: storedEvent.EventName, body: storedEvent.Body, aggregateId: storedEvent.AggregateId, sequenceNumber: storedEvent.SequenceNumber, timestamp: storedEvent.Timestamp); bus.PublishAsync(@event).Subscribe( _ => msg.Complete(), ex => bus.PublishErrorAsync(new EventHandlingError(ex, @event: @event))); }); queues[((dynamic)binder).EventType] = queueClient; return(new CompositeDisposable(eventBusSubscription, Disposable.Create(queueClient.Close))); }
internal static QueueClient CreateQueueClient(ServiceBusSettings settings) { return(settings.CreateQueueClient( "ScheduledCommands", q => { q.SupportOrdering = true; q.RequiresSession = true; q.LockDuration = TimeSpan.FromMinutes(5); q.MaxDeliveryCount = (int)(TimeSpan.FromDays(45).Ticks / q.LockDuration.Ticks); q.EnableDeadLetteringOnMessageExpiration = false; })); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusCommandQueueSender"/> class. /// </summary> /// <exception cref="System.ArgumentNullException">queueClient</exception> public ServiceBusCommandQueueSender(ServiceBusSettings settings) { if (settings == null) { throw new ArgumentNullException("settings"); } this.settings = settings; MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromMinutes(2); #if DEBUG exceptionSubject.Subscribe(ex => Debug.WriteLine("ServiceBusCommandQueueSender error: " + ex)); #endif }
/// <summary> /// Creates a queue client, as well as the target queue if it does not already exist. /// </summary> public static QueueClient CreateQueueClient( this ServiceBusSettings settings, string queueName, Action <QueueDescription> configure = null) { queueName = queueName.PrefixedIfConfigured(settings); var queueDescription = new QueueDescription(queueName); if (configure != null) { configure(queueDescription); } settings.CreateQueueIfDoesNotAlreadyExist(queueDescription); return(QueueClient.CreateFromConnectionString(settings.ConnectionString, queueName)); }
/// <summary> /// Creates a topic client, as well as the target topic if it does not already exist. /// </summary> public static TopicClient CreateTopicClient( this ServiceBusSettings settings, string topicName, Action <TopicDescription> configure = null) { topicName = topicName.PrefixedIfConfigured(settings); var topicDescription = new TopicDescription(topicName); if (configure != null) { configure(topicDescription); } settings.CreateTopicIfDoesNotAlreadyExist(topicDescription); return(TopicClient.CreateFromConnectionString(settings.ConnectionString, topicName)); }
/// <summary> /// Creates a subscription client, as well as the target subscription if it does not already exist. /// </summary> public static SubscriptionClient CreateSubscriptionClient( this ServiceBusSettings settings, string topicPath, string subscriptionName, Action <SubscriptionDescription> configure = null) { topicPath = topicPath.PrefixedIfConfigured(settings); var subscriptionDescription = new SubscriptionDescription(topicPath, subscriptionName); if (configure != null) { configure(subscriptionDescription); } settings.CreateSubscriptionIfDoesNotAlreadyExist(subscriptionDescription); return(SubscriptionClient.CreateFromConnectionString(settings.ConnectionString, subscriptionDescription.TopicPath, subscriptionDescription.Name)); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBusCommandQueueReceiver"/> class. /// </summary> /// <param name="settings">The service bus settings.</param> /// <param name="scheduler">The command scheduler.</param> /// <exception cref="System.ArgumentNullException"> /// settings /// or /// scheduler /// </exception> public ServiceBusCommandQueueReceiver(ServiceBusSettings settings, SqlCommandScheduler scheduler) { if (settings == null) { throw new ArgumentNullException("settings"); } if (scheduler == null) { throw new ArgumentNullException("scheduler"); } this.settings = settings; this.scheduler = scheduler; #if DEBUG exceptionSubject .Where(ex => !(ex is OperationCanceledException)) .Subscribe(ex => Debug.WriteLine("ServiceBusCommandQueueReceiver error: " + ex)); #endif }
public override void SetUp() { base.SetUp(); schedulerActivity = new List<IScheduledCommand>(); using (VirtualClock.Start(DateTimeOffset.Now.AddMonths(1))) { disposables = new CompositeDisposable(); Settings.Sources = new ISettingsSource[] { new ConfigDirectorySettings(@"c:\dev\.config") }.Concat(Settings.Sources); serviceBusSettings = Settings.Get<ServiceBusSettings>(); serviceBusSettings.NamePrefix = "itscqrstests"; serviceBusSettings.ConfigureQueue = q => { q.AutoDeleteOnIdle = TimeSpan.FromMinutes(15); }; var clockName = Any.Paragraph(4); var configuration = new Configuration() .UseSqlEventStore() .UseDependency<GetClockName>(_ => @event => clockName) .UseSqlStorageForScheduledCommands() .AddToCommandSchedulerPipeline<Order>( schedule: async (cmd, next) => { await next(cmd); schedulerActivity.Add(cmd); }, deliver: async (cmd, next) => { await next(cmd); schedulerActivity.Add(cmd); }); queueSender = new ServiceBusCommandQueueSender(serviceBusSettings) { MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(30) }; disposables.Add(queueSender.Messages.Subscribe(s => Console.WriteLine("[ServiceBusCommandQueueSender] " + s.ToJson()))); disposables.Add(configuration); disposables.Add(ConfigurationContext.Establish(configuration)); } }
public override void SetUp() { base.SetUp(); using (VirtualClock.Start(DateTimeOffset.Now.AddMonths(1))) { disposables = new CompositeDisposable(); Settings.Sources = new ISettingsSource[] { new ConfigDirectorySettings(@"c:\dev\.config") }.Concat(Settings.Sources); serviceBusSettings = Settings.Get<ServiceBusSettings>(); serviceBusSettings.NamePrefix = "itscqrstests"; serviceBusSettings.ConfigureQueue = q => { q.AutoDeleteOnIdle = TimeSpan.FromMinutes(15); }; bus = new FakeEventBus(); orderRepository = new SqlEventSourcedRepository<Order>(bus); var configuration = new Configuration() .UseSqlEventStore(() => new EventStoreDbContext()) .UseEventBus(bus) .UseSqlCommandScheduling() .UseDependency<IEventSourcedRepository<Order>>(t => orderRepository); var clockName = Any.Paragraph(4); scheduler = new SqlCommandScheduler(configuration) { GetClockName = @event => clockName }; queueSender = new ServiceBusCommandQueueSender(serviceBusSettings) { MessageDeliveryOffsetFromCommandDueTime = TimeSpan.FromSeconds(30) }; disposables.Add(scheduler.Activity.Subscribe(s => Console.WriteLine("SqlCommandScheduler: " + s.ToJson()))); disposables.Add(queueSender.Messages.Subscribe(s => Console.WriteLine("ServiceBusCommandQueueSender: " + s.ToJson()))); disposables.Add(bus.Subscribe(scheduler)); disposables.Add(configuration); disposables.Add(ConfigurationContext.Establish(configuration)); } }
internal static QueueClient CreateQueueClient(ServiceBusSettings settings) { return settings.CreateQueueClient( "ScheduledCommands", q => { q.SupportOrdering = true; q.RequiresSession = true; q.LockDuration = TimeSpan.FromMinutes(5); q.MaxDeliveryCount = (int) (TimeSpan.FromDays(45).Ticks / q.LockDuration.Ticks); q.EnableDeadLetteringOnMessageExpiration = false; }); }
private static string PrefixedIfConfigured(this string name, ServiceBusSettings settings) { return (string.IsNullOrEmpty(settings.NamePrefix) ? "" : settings.NamePrefix + "_") + name; }
private static string PrefixedIfConfigured(this string name, ServiceBusSettings settings) { return((string.IsNullOrEmpty(settings.NamePrefix) ? "" : settings.NamePrefix + "_") + name); }