static void Register(StandardConfigurer<ISubscriptionStorage> configurer, string tableName, CloudStorageAccount storageAccount, bool isCentralized = false)
        {
            if (configurer == null) throw new ArgumentNullException(nameof(configurer));
            if (tableName == null) throw new ArgumentNullException(nameof(tableName));
            if (storageAccount == null) throw new ArgumentNullException(nameof(storageAccount));

            configurer.Register(c => new AzureStorageSubscriptionStorage(storageAccount, c.Get<IRebusLoggerFactory>(), isCentralized, tableName));
        }
Esempio n. 2
0
        /// <summary>
        /// Uses the given <see cref="StandardConfigurer{TService}"/> of <see cref="ITransport"/> to set the number of workers
        /// to zero (effectively disabling message processing) and installs a decorator of <see cref="IBus"/> that prevents
        /// further modification of the number of workers (thus preventing accidentally starting workers when there's no input queue).
        /// </summary>
        public static void ConfigureOneWayClient(StandardConfigurer<ITransport> configurer)
        {
            configurer.Options.NumberOfWorkers = 0;

            configurer.OtherService<IBus>().Decorate(c =>
            {
                configurer.Options.NumberOfWorkers = 0;
                var resolveRealBus = c.Get<IBus>();
                return new OneWayClientBusDecorator(resolveRealBus);
            }, description: OneWayDecoratorDescription);
        } 
        static void Configure(StandardConfigurer<IRouter> configurer)
        {
            var rebusRoutingConfigurationSection = GetRebusRoutingConfigurationSection();

            configurer.Register(c =>
            {
                var typeBasedRouter = new TypeBasedRouter();

                SetUpEndpointMappings(rebusRoutingConfigurationSection.MappingsCollection, (type, endpoint) => typeBasedRouter.Map(type, endpoint));

                return typeBasedRouter;
            });
        }
        static void Register(StandardConfigurer<ITransport> configurer, string inputQueueAddress, CloudStorageAccount storageAccount)
        {
            configurer.Register(c => new AzureStorageQueuesTransport(storageAccount, inputQueueAddress));

            configurer.OtherService<ITimeoutManager>().Register(c => new DisabledTimeoutManager(), description: AsqTimeoutManagerText);

            configurer.OtherService<IPipeline>().Decorate(c =>
            {
                var pipeline = c.Get<IPipeline>();
                
                return new PipelineStepRemover(pipeline)
                    .RemoveIncomingStep(s => s.GetType() == typeof(HandleDeferredMessagesStep));
            });
        }
    /// <summary>
    /// Configures Topos to stores its consumer positions in blobs. Individual blobs will be created for each relevant topic/partition.
    /// </summary>
    public static void StoreInAzureBlobs(this StandardConfigurer <IPositionManager> configurer, CloudStorageAccount storageAccount, string containerName)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }
        if (storageAccount == null)
        {
            throw new ArgumentNullException(nameof(storageAccount));
        }
        if (containerName == null)
        {
            throw new ArgumentNullException(nameof(containerName));
        }

        var registrar = StandardConfigurer.Open(configurer);

        registrar.Register(_ => new AzureBlobsPositionManager(storageAccount, containerName));
    }
        /// <summary>
        /// Configures Rebus' data bus to storage data in Azure blobs in the given storage account and container
        /// </summary>
        public static void StoreInBlobStorage(this StandardConfigurer <IDataBusStorage> configurer, string storageAccountConnectionString, string containerName)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }
            if (containerName == null)
            {
                throw new ArgumentNullException(nameof(containerName));
            }
            if (storageAccountConnectionString == null)
            {
                throw new ArgumentNullException(nameof(storageAccountConnectionString));
            }

            var cloudStorageAccount = CloudStorageAccount.Parse(storageAccountConnectionString);

            Configure(configurer, containerName, cloudStorageAccount);
        }
Esempio n. 7
0
        /// <summary>
        /// <para>
        /// Configures Rebus to automatically transfer message bodies as data bus attachments, if the size of the body exceeds <paramref name="bodySizeThresholdBytes"/> bytes.
        /// </para>
        /// <para>
        /// This can be used in situations when you know that the message size will sometimes be too big for the transport, like e.g. when using Azure Service Bus.
        /// With Azure Service Bus (at least at the time of writing), the maximum message size is 256 kB, including all headers and everything.
        /// </para>
        /// <para>
        /// Since it can be hard to predict how large the final Azure Service Bus transport message can get, if you know that your message payloads will approach the 256 kB limit,
        /// it is recommended to enable automatic compression of message payloads (by calling <see cref="ZipConfigurationExtensions.EnableCompression"/>).
        /// </para>
        /// <para>
        /// If you still fear that your message payloads will approach the limit, this feature is for you :) simply ensure that the data bus is properly configured
        /// (e.g. to use Azure Blob Storage to store attachments), and then call this method to enable automatic big message claim check.
        /// </para>
        /// </summary>
        public static void SendBigMessagesAsAttachments(this StandardConfigurer <IDataBusStorage> configurer, int bodySizeThresholdBytes)
        {
            configurer
            .OtherService <IPipeline>()
            .Decorate(c =>
            {
                var pipeline = c.Get <IPipeline>();
                var dataBus  = c.Get <IDataBus>();

                var dehydrateStep = new DehydrateOutgoingMessageStep(dataBus, bodySizeThresholdBytes);

                return(new PipelineStepInjector(pipeline)
                       .OnSend(
                           step: dehydrateStep,
                           position: PipelineRelativePosition.After,
                           anchorStep: typeof(SerializeOutgoingMessageStep)
                           ));
            });
        }
    /// <summary>
    /// Forces exclusive access using a lockhandler defined by <see cref="IExclusiveAccessLock"/>, materialized via a callback within the resolution context
    /// </summary>
    public static void EnforceExclusiveAccess(this StandardConfigurer <ISagaStorage> configurer, Func <IResolutionContext, IExclusiveAccessLock> getLocker, string lockPrefix = null, int maxLockBuckets = 1000)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }

        configurer
        .OtherService <IPipeline>()
        .Decorate(c =>
        {
            var pipeline          = c.Get <IPipeline>();
            var cancellationToken = c.Get <CancellationToken>();
            var step = new EnforceExclusiveSagaAccessIncomingStep(getLocker(c), maxLockBuckets, lockPrefix ?? "sagalock_", cancellationToken);

            return(new PipelineStepInjector(pipeline)
                   .OnReceive(step, PipelineRelativePosition.Before, typeof(LoadSagaDataStep)));
        });
    }
Esempio n. 9
0
    /// <summary>
    /// Configures Topos to stores its consumer positions in documents in MongoDB. Individual documents will be created for each relevant topic with fields for each partition.
    /// </summary>
    public static void StoreInMongoDb(this StandardConfigurer <IPositionManager> configurer, IMongoDatabase database, string collectionName)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }
        if (database == null)
        {
            throw new ArgumentNullException(nameof(database));
        }
        if (collectionName == null)
        {
            throw new ArgumentNullException(nameof(collectionName));
        }

        var registrar = StandardConfigurer.Open(configurer);

        registrar.Register(_ => new MongoDbPositionManager(database, collectionName));
    }
    /// <summary>
    /// Configures Rebus to use SQL Server to store sagas, using the tables specified to store data and indexed properties respectively.
    /// </summary>
    public static void StoreInSqlServer(this StandardConfigurer <ISagaStorage> configurer, SqlServerSagaStorageOptions options, string dataTableName, string indexTableName)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }
        if (dataTableName == null)
        {
            throw new ArgumentNullException(nameof(dataTableName));
        }
        if (indexTableName == null)
        {
            throw new ArgumentNullException(nameof(indexTableName));
        }

        configurer.Register(c =>
        {
            var rebusLoggerFactory     = c.Get <IRebusLoggerFactory>();
            var connectionProvider     = options.ConnectionProviderFactory(c);
            var sagaTypeNamingStrategy = GetSagaTypeNamingStrategy(c, rebusLoggerFactory);
            var serializer             = c.Has <ISagaSerializer>(false) ? c.Get <ISagaSerializer>() : new DefaultSagaSerializer();

            var sagaStorage = new SqlServerSagaStorage(
                connectionProvider: connectionProvider,
                dataTableName: dataTableName,
                indexTableName: indexTableName,
                rebusLoggerFactory: rebusLoggerFactory,
                sagaTypeNamingStrategy: sagaTypeNamingStrategy,
                sagaSerializer: serializer
                );

            if (options.EnsureTablesAreCreated)
            {
                sagaStorage.EnsureTablesAreCreated();
            }

            return(sagaStorage);
        });
    }
Esempio n. 11
0
        /// <summary>
        /// Configures the data bus to store data in the file system
        /// </summary>
        public static void StoreInFileSystem(this StandardConfigurer <IDataBusStorage> configurer, string directoryPath)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }
            if (directoryPath == null)
            {
                throw new ArgumentNullException(nameof(directoryPath));
            }

            configurer.Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var rebusTime          = c.Get <IRebusTime>();

                return(new FileSystemDataBusStorage(directoryPath, rebusLoggerFactory, rebusTime));
            });
        }
Esempio n. 12
0
        public static XmlSerializer UseXmlSerializing(
            this StandardConfigurer <ISerializer> configurer,
            ILogger logger,
            XmlSerializingOptions options = null
            )
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }

            var instance = new XmlSerializer(options ?? new XmlSerializingOptions());

            instance.WithLogging(logger);

            configurer.Register(r => instance);

            return(instance);
        }
        /// <summary>
        /// Forces exclusive using a lockhandler defined by <see cref="IExclusiveSagaAccessLock"/>
        /// </summary>
        public static void EnforceExclusiveAccess(this StandardConfigurer <ISagaStorage> configurer, IExclusiveSagaAccessLock locker)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }

            configurer
            .OtherService <IPipeline>()
            .Decorate(c =>
            {
                var pipeline          = c.Get <IPipeline>();
                var cancellationToken = c.Get <CancellationToken>();
                var step = new EnforceExclusiveSagaAccessIncomingStep(locker, cancellationToken);

                return(new PipelineStepInjector(pipeline)
                       .OnReceive(step, PipelineRelativePosition.Before, typeof(LoadSagaDataStep)));
            });
        }
        /// <summary>
        /// Enables saga auditing which will cause Rebus to save a snapshot of each saga state to the configured snapshot storage.
        /// Please remember to select a saga snapshot storage by calling an extension on the returned <see cref="StandardConfigurer{TService}"/>, e.g. like so:
        /// <code>
        /// Configure.With(..)
        ///     .(...)
        ///     .Options(o => o.EnableSagaAuditing().StoreInSqlServer(....))
        ///     .Start();
        /// </code>
        /// </summary>
        public static StandardConfigurer <ISagaSnapshotStorage> EnableSagaAuditing(this OptionsConfigurer configurer)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }

            configurer.Decorate <IPipeline>(c =>
            {
                var pipeline            = c.Get <IPipeline>();
                var sagaSnapshotStorage = GetSagaSnapshotStorage(c);
                var transport           = GetTransport(c);

                return(new PipelineStepInjector(pipeline)
                       .OnReceive(new SaveSagaDataSnapshotStep(sagaSnapshotStorage, transport), PipelineRelativePosition.Before, typeof(LoadSagaDataStep)));
            });

            return(StandardConfigurer <ISagaSnapshotStorage> .GetConfigurerFrom(configurer));
        }
        /// <summary>
        /// Configures Rebus to use RavenDb to store timeouts.
        /// </summary>
        public static void StoreInRavenDb(this StandardConfigurer <ITimeoutManager> configurer, IDocumentStore documentStore)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }
            if (documentStore == null)
            {
                throw new ArgumentNullException(nameof(documentStore));
            }

            documentStore.ExecuteIndex(new TimeoutIndex());

            configurer.Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var timeoutManager     = new RavenDbTimeoutManager(documentStore, rebusLoggerFactory);
                return(timeoutManager);
            });
        }
        static void Configure(StandardConfigurer<ITransport> configurer, string connectionString, string tableName, string inputQueueName)
        {
            configurer.Register(context =>
            {
                var connectionProvider = new DbConnectionProvider(connectionString);
                var transport = new SqlServerTransport(connectionProvider, tableName, inputQueueName);
                transport.EnsureTableIsCreated();
                return transport;
            });

            configurer.OtherService<ITimeoutManager>().Register(c => new DisabledTimeoutManager());

            configurer.OtherService<IPipeline>().Decorate(c =>
            {
                var pipeline = c.Get<IPipeline>();

                return new PipelineStepRemover(pipeline)
                    .RemoveIncomingStep(s => s.GetType() == typeof (HandleDeferredMessagesStep));
            });
        }
Esempio n. 17
0
        static void Configure(StandardConfigurer <ITransport> configurer, string connectionString, string tableName, string inputQueueName)
        {
            configurer.Register(context =>
            {
                var rebusLoggerFactory = context.Get <IRebusLoggerFactory>();
                var connectionProvider = new DbConnectionProvider(connectionString, rebusLoggerFactory);
                var transport          = new SqlServerTransport(connectionProvider, tableName, inputQueueName, rebusLoggerFactory);
                transport.EnsureTableIsCreated();
                return(transport);
            });

            configurer.OtherService <ITimeoutManager>().Register(c => new DisabledTimeoutManager());

            configurer.OtherService <IPipeline>().Decorate(c =>
            {
                var pipeline = c.Get <IPipeline>();

                return(new PipelineStepRemover(pipeline)
                       .RemoveIncomingStep(s => s.GetType() == typeof(HandleDeferredMessagesStep)));
            });
        }
Esempio n. 18
0
        /// <summary>
        /// Configures Rebus to use the file system to transport messages. The specified <paramref name="baseDirectory"/> will be used as the base directory
        /// within which subdirectories will be created for each logical queue.
        /// </summary>
        public static void UseFileSystem(this StandardConfigurer <ITransport> configurer, string baseDirectory, string inputQueueName)
        {
            if (baseDirectory == null)
            {
                throw new ArgumentNullException(nameof(baseDirectory));
            }
            if (inputQueueName == null)
            {
                throw new ArgumentNullException(nameof(inputQueueName));
            }

            configurer
            .OtherService <FileSystemTransport>()
            .Register(context => new FileSystemTransport(baseDirectory, inputQueueName));

            configurer
            .OtherService <ITransportInspector>()
            .Register(context => context.Get <FileSystemTransport>());

            configurer.Register(context => context.Get <FileSystemTransport>());
        }
Esempio n. 19
0
    public static void StoreInPostgreSql(
        this StandardConfigurer <IPositionManager> configurer,
        string connectionString,
        string consumerGroup)
    {
        if (configurer is null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }
        if (string.IsNullOrEmpty(connectionString))
        {
            throw new ArgumentException($"{nameof(connectionString)} cannot be null or empty.");
        }
        if (string.IsNullOrEmpty(consumerGroup))
        {
            throw new ArgumentException($"{nameof(consumerGroup)} cannot be null or empty.");
        }

        StandardConfigurer.Open(configurer)
        .Register(_ => new PostgreSqlPositionManager(connectionString, consumerGroup));
    }
Esempio n. 20
0
    /// <summary>
    /// Adds the given routing function - should return <see cref="ForwardAction.None"/> to do nothing, or another action
    /// available on <see cref="ForwardAction"/> in order to do something to the message
    /// </summary>
    public static void AddTransportMessageForwarder(this StandardConfigurer <IRouter> configurer,
                                                    Func <TransportMessage, Task <ForwardAction> > routingFunction,
                                                    ErrorBehavior errorBehavior)
    {
        configurer.OtherService <IPipeline>()
        .Decorate(c =>
        {
            var pipeline           = c.Get <IPipeline>();
            var transport          = c.Get <ITransport>();
            var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();

            var errorQueueName = c.Has <SimpleRetryStrategySettings>()
                    ? c.Get <SimpleRetryStrategySettings>().ErrorQueueAddress
                    : "error";

            var stepToAdd = new ForwardTransportMessageStep(routingFunction, transport, rebusLoggerFactory, errorQueueName, errorBehavior);

            return(new PipelineStepConcatenator(pipeline)
                   .OnReceive(stepToAdd, PipelineAbsolutePosition.Front));
        });
    }
        /// <summary>
        /// Configures Rebus to use MongoDB to store sagas, using the specified collection name resolver function. If the collection name resolver is omitted,
        /// collection names will be determined by using the <code>Name</code> property of the saga data's <see cref="Type"/>
        /// </summary>
        public static void StoreInMongoDb(this StandardConfigurer <ISagaStorage> configurer, MongoDatabase mongoDatabase, Func <Type, string> collectionNameResolver = null)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException("configurer");
            }
            if (mongoDatabase == null)
            {
                throw new ArgumentNullException("mongoDatabase");
            }

            collectionNameResolver = collectionNameResolver
                                     ?? (sagaDataType => sagaDataType.Name);

            configurer.Register(c =>
            {
                var sagaStorage = new MongoDbSagaStorage(mongoDatabase, collectionNameResolver);

                return(sagaStorage);
            });
        }
        /// <summary>
        /// Configures Rebus to use Amazon Simple Queue Service as the message transport
        /// </summary>
        public static void UseAmazonSqs(this StandardConfigurer <ITransport> configurer, string accessKeyId, string secretAccessKey, AmazonSQSConfig config, string inputQueueAddress)
        {
            configurer.Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var asyncTaskFactory   = c.Get <IAsyncTaskFactory>();

                return(new AmazonSqsTransport(inputQueueAddress, accessKeyId, secretAccessKey, config, rebusLoggerFactory, asyncTaskFactory));
            });

            configurer
            .OtherService <IPipeline>()
            .Decorate(p =>
            {
                var pipeline = p.Get <IPipeline>();

                return(new PipelineStepRemover(pipeline)
                       .RemoveIncomingStep(s => s.GetType() == typeof(HandleDeferredMessagesStep)));
            });

            configurer.OtherService <ITimeoutManager>().Register(c => new DisabledTimeoutManager(), description: SqsTimeoutManagerText);
        }
Esempio n. 23
0
        /// <summary>
        /// Configures the data bus to store data in a central SQL Server
        /// </summary>
        public static void StoreInSqlServer(this StandardConfigurer <IDataBusStorage> configurer, Func <Task <IDbConnection> > connectionFactory, string tableName, bool automaticallyCreateTables = true)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }
            if (connectionFactory == null)
            {
                throw new ArgumentNullException(nameof(connectionFactory));
            }
            if (tableName == null)
            {
                throw new ArgumentNullException(nameof(tableName));
            }

            configurer.Register(c =>
            {
                var loggerFactory      = c.Get <IRebusLoggerFactory>();
                var connectionProvider = new DbConnectionFactoryProvider(connectionFactory, loggerFactory);
                return(new SqlServerDataBusStorage(connectionProvider, tableName, automaticallyCreateTables, loggerFactory));
            });
        }
        /// <summary>
        /// Configures Rebus to use MongoDB to store subscriptions. Use <see cref="isCentralized"/> = true to indicate whether it's OK to short-circuit
        /// subscribing and unsubscribing by manipulating the subscription directly from the subscriber or just let it default to false to preserve the
        /// default behavior.
        /// </summary>
        public static void StoreInMongoDb(this StandardConfigurer <ISubscriptionStorage> configurer, MongoDatabase mongoDatabase, string collectionName, bool isCentralized = false)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException("configurer");
            }
            if (mongoDatabase == null)
            {
                throw new ArgumentNullException("mongoDatabase");
            }
            if (collectionName == null)
            {
                throw new ArgumentNullException("collectionName");
            }

            configurer.Register(c =>
            {
                var subscriptionStorage = new MongoDbSubscriptionStorage(mongoDatabase, collectionName, isCentralized);

                return(subscriptionStorage);
            });
        }
Esempio n. 25
0
        /// <summary>
        /// Configures Rebus to use RabbitMQ to move messages around
        /// </summary>
        public static RabbitMqOptionsBuilder UseRabbitMq(this StandardConfigurer <ITransport> configurer, string connectionString, string inputQueueName)
        {
            var options = new RabbitMqOptionsBuilder();

            configurer
            .OtherService <RabbitMqTransport>()
            .Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var transport          = new RabbitMqTransport(connectionString, inputQueueName, rebusLoggerFactory);
                options.Configure(transport);
                return(transport);
            });

            configurer
            .OtherService <ISubscriptionStorage>()
            .Register(c => c.Get <RabbitMqTransport>(), description: RabbitMqSubText);

            configurer.Register(c => c.Get <RabbitMqTransport>());

            return(options);
        }
    /// <summary>
    /// Configures SQL Server as the outbox storage
    /// </summary>
    public static void StoreInSqlServer(this StandardConfigurer<IOutboxStorage> configurer, string connectionString, TableName tableName)
    {
        if (configurer == null) throw new ArgumentNullException(nameof(configurer));
        if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
        if (tableName == null) throw new ArgumentNullException(nameof(tableName));

        IDbConnection ConnectionProvider(ITransactionContext context)
        {
            // if we find a connection in the context, use that (and accept that its lifestyle is managed somewhere else):
            if (context.Items.TryGetValue(CurrentOutboxConnectionKey, out var result) && result is OutboxConnection outboxConnection)
            {
                return new DbConnectionWrapper(outboxConnection.Connection, outboxConnection.Transaction, managedExternally: true);
            }

            var connection = new SqlConnection(connectionString);

            connection.Open();

            try
            {
                var transaction = connection.BeginTransaction();

                return new DbConnectionWrapper(connection, transaction, managedExternally: false);
            }
            catch
            {
                connection.Dispose();
                throw;
            }
        }

        configurer
            .OtherService<IOutboxStorage>()
            .Register(_ => new SqlServerOutboxStorage(ConnectionProvider, tableName));

        configurer.OtherService<IOutboxConnectionProvider>()
            .Register(_ => new OutboxConnectionProvider(connectionString));
    }
    /// <summary>
    /// Configures Rebus to use SQL Server to store sagas, using the tables specified to store data and indexed properties respectively.
    /// </summary>
    public static void StoreInSqlServer(this StandardConfigurer <ISagaStorage> configurer,
                                        Func <Task <IDbConnection> > connectionFactory, string dataTableName, string indexTableName,
                                        bool automaticallyCreateTables = true)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }
        if (connectionFactory == null)
        {
            throw new ArgumentNullException(nameof(connectionFactory));
        }
        if (dataTableName == null)
        {
            throw new ArgumentNullException(nameof(dataTableName));
        }
        if (indexTableName == null)
        {
            throw new ArgumentNullException(nameof(indexTableName));
        }

        configurer.Register(c =>
        {
            var rebusLoggerFactory     = c.Get <IRebusLoggerFactory>();
            var connectionProvider     = new DbConnectionFactoryProvider(connectionFactory);
            var sagaTypeNamingStrategy = GetSagaTypeNamingStrategy(c, rebusLoggerFactory);
            var serializer             = c.Has <ISagaSerializer>(false) ? c.Get <ISagaSerializer>() : new DefaultSagaSerializer();

            var sagaStorage = new SqlServerSagaStorage(connectionProvider, dataTableName, indexTableName, rebusLoggerFactory, sagaTypeNamingStrategy, serializer);

            if (automaticallyCreateTables)
            {
                sagaStorage.EnsureTablesAreCreated();
            }

            return(sagaStorage);
        });
    }
        /// <summary>
        /// Short-circuits the usual retry strategy by immediately forwarding the transport message to the specified queue when an
        /// exception of the type specified by <typeparamref name="TException"/> is caught. Please note that any outgoing message
        /// that have already been sent WILL BE SENT because the queue transaction is not rolled back.
        /// Use <paramref name="logLevel"/> to specify which log level to use when logging the forwarding action.
        /// </summary>
        public static StandardConfigurer <IRouter> ForwardOnException <TException>(this StandardConfigurer <IRouter> configurer, string destinationQueue, LogLevel logLevel, Func <TException, bool> shouldForward = null)
            where TException : Exception
        {
            configurer
            .OtherService <IPipeline>()
            .Decorate(c =>
            {
                var pipeline           = c.Get <IPipeline>();
                var transport          = c.Get <ITransport>();
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();

                var shouldForwardException = shouldForward != null
                        ? (Func <Exception, bool>)(exception => shouldForward((TException)exception))
                        : (exception => true);

                var step = new ForwardOnExceptionsStep(typeof(TException), destinationQueue, transport, rebusLoggerFactory, logLevel, shouldForwardException);

                return(new PipelineStepInjector(pipeline)
                       .OnReceive(step, PipelineRelativePosition.After, typeof(SimpleRetryStrategyStep)));
            });

            return(configurer);
        }
Esempio n. 29
0
    /// <summary>
    /// Uses the given <see cref="StandardConfigurer{TService}"/> of <see cref="ITransport"/> to set the number of workers
    /// to zero (effectively disabling message processing) and installs a decorator of <see cref="IBus"/> that prevents
    /// further modification of the number of workers (thus preventing accidentally starting workers when there's no input queue).
    /// </summary>
    public static void ConfigureOneWayClient(StandardConfigurer <ITransport> configurer)
    {
        configurer.Options.NumberOfWorkers = 0;

        configurer.OtherService <IBus>().Decorate(c =>
        {
            var transport = c.Get <ITransport>();

            if (transport.Address != null)
            {
                throw new InvalidOperationException($"Cannot configure this bus to be a one-way client, because the transport is configured with '{transport.Address}' as its input queue. One-way clients must have a NULL input queue, otherwise the transport could be fooled into believing it was supposed to receive messages");
            }

            var options             = c.Get <Options>();
            options.NumberOfWorkers = 0;

            var realBus            = c.Get <IBus>();
            var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
            var busDecorator       = new OneWayClientBusDecorator(realBus, rebusLoggerFactory);

            return(busDecorator);
        }, description: OneWayDecoratorDescription);
    }
Esempio n. 30
0
    /// <summary>
    /// Configures Rebus to use in-mem message queues, delivering/receiving from the specified <see cref="InMemNetwork"/>
    /// </summary>
    public static void UseInMemoryTransport(this StandardConfigurer <ITransport> configurer, InMemNetwork network, string inputQueueName)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }
        if (network == null)
        {
            throw new ArgumentNullException(nameof(network));
        }
        if (inputQueueName == null)
        {
            throw new ArgumentNullException(nameof(inputQueueName));
        }

        configurer.OtherService <InMemTransport>()
        .Register(context => new InMemTransport(network, inputQueueName));

        configurer.OtherService <ITransportInspector>()
        .Register(context => context.Get <InMemTransport>());

        configurer.Register(context => context.Get <InMemTransport>());
    }
Esempio n. 31
0
        /// <summary>
        /// Configures Rebus to use RabbitMQ to transport messages as a one-way client (i.e. will not be able to receive any messages)
        /// </summary>
        public static RabbitMqOptionsBuilder UseRabbitMqAsOneWayClient(this StandardConfigurer <ITransport> configurer, string connectionString)
        {
            var options = new RabbitMqOptionsBuilder();

            configurer
            .OtherService <RabbitMqTransport>()
            .Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var transport          = new RabbitMqTransport(connectionString, null, rebusLoggerFactory);
                options.Configure(transport);
                return(transport);
            });

            configurer
            .OtherService <ISubscriptionStorage>()
            .Register(c => c.Get <RabbitMqTransport>(), description: RabbitMqSubText);

            configurer.Register(c => c.Get <RabbitMqTransport>());

            OneWayClientBackdoor.ConfigureOneWayClient(configurer);

            return(options);
        }
    /// <summary>
    /// Configures Topos to use Microsoft's FASTER Log and the file system as the event store
    /// </summary>
    public static void UseFileSystem(this StandardConfigurer <IConsumerImplementation> configurer, string directoryPath)
    {
        if (configurer == null)
        {
            throw new ArgumentNullException(nameof(configurer));
        }

        CheckDirectoryPath(directoryPath);

        StandardConfigurer.Open(configurer)
        .Register(c => new FasterLogConsumerImplementation(
                      loggerFactory: c.Get <ILoggerFactory>(),
                      deviceManager: c.Get <IDeviceManager>(),
                      logEntrySerializer: c.Get <ILogEntrySerializer>(),
                      topics: c.Has <Topics>() ? c.Get <Topics>() : new Topics(),
                      consumerDispatcher: c.Get <IConsumerDispatcher>(),
                      positionManager: c.Get <IPositionManager>()
                      ))
        .Other <IDeviceManager>().Register(c => new DefaultDeviceManager(
                                               loggerFactory: c.Get <ILoggerFactory>(),
                                               directoryPath: directoryPath
                                               ))
        .Other <ILogEntrySerializer>().Register(_ => new ProtobufLogEntrySerializer());
    }
Esempio n. 33
0
        /// <summary>Configures Rebus to use Apache Kafka to transport messages as a one-way client (i.e. will not be able to receive any messages).
        /// Performs a simplified configuration of the parameters of the producer used in this transport.</summary>
        /// <param name="configurer"></param>
        /// <param name="brokerList">Initial list of brokers as a CSV list of broker host or host:port.</param>
        public static void UseKafkaAsOneWayClient(this StandardConfigurer <ITransport> configurer, string brokerList)
        {
            // Register implementation of the transport as ISubscriptionStorage as well
            configurer
            .OtherService <KafkaTransport>()
            .Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var asyncTaskFactory   = c.Get <IAsyncTaskFactory>();
                var cancellationToken  = c.Get <CancellationToken>();
                return(new KafkaTransport(rebusLoggerFactory, asyncTaskFactory
                                          , brokerList, null, null, cancellationToken));
            });

            // Register implementation of the Transport as ITransport
            configurer.Register(c => c.Get <KafkaTransport>());

            // Link the ISubscriberStorage to the transport
            configurer
            .OtherService <ISubscriptionStorage>()
            .Register(c => c.Get <KafkaTransport>(), description: AsbSubStorageText);

            OneWayClientBackdoor.ConfigureOneWayClient(configurer);
        }
Esempio n. 34
0
    static TTransportOptions Configure <TTransportOptions>(StandardConfigurer <ITransport> configurer, TransportFactoryDelegate transportFactory, TTransportOptions transportOptions) where TTransportOptions : SqlServerTransportOptions
    {
        configurer.Register(context =>
        {
            if (transportOptions.IsOneWayClient)
            {
                OneWayClientBackdoor.ConfigureOneWayClient(configurer);
            }

            var connectionProvider = transportOptions.ConnectionProviderFactory(context);
            var transport          = transportFactory(context, connectionProvider, transportOptions.InputQueueName);
            if ((transportOptions.InputQueueName != null) && (transportOptions.EnsureTablesAreCreated == true))
            {
                transport.EnsureTableIsCreated();
            }

            return(transport);
        }
                            );

        configurer.OtherService <Options>().Decorate(c =>
        {
            var options = c.Get <Options>();

            // if the transport is a one-way client and no external timeout manager has been configured, set the
            // external timeout manager's address to this magic string, which we'll detect later on
            if (transportOptions.IsOneWayClient && string.IsNullOrWhiteSpace(options.ExternalTimeoutManagerAddressOrNull))
            {
                options.ExternalTimeoutManagerAddressOrNull = SqlServerTransport.MagicExternalTimeoutManagerAddress;
            }

            return(options);
        });

        return(transportOptions);
    }
 /// <summary>
 /// Configures Rebus to use Amazon Simple Queue Service as the message transport
 /// </summary>
 public static void UseAmazonSqs(this StandardConfigurer <ITransport> configurer, string accessKeyId, string secretAccessKey, RegionEndpoint regionEndpoint, string inputQueueAddress)
 {
     configurer.Register(c => new AmazonSqsTransport(inputQueueAddress, accessKeyId, secretAccessKey, regionEndpoint));
 }
        static void Register(StandardConfigurer<ITransport> configurer, string inputQueueAddress, CloudStorageAccount storageAccount)
        {
            if (configurer == null) throw new ArgumentNullException(nameof(configurer));
            if (inputQueueAddress == null) throw new ArgumentNullException(nameof(inputQueueAddress));
            if (storageAccount == null) throw new ArgumentNullException(nameof(storageAccount));

            configurer.Register(c =>
            {
                var rebusLoggerFactory = c.Get<IRebusLoggerFactory>();
                return new AzureStorageQueuesTransport(storageAccount, inputQueueAddress, rebusLoggerFactory);
            });

            configurer.OtherService<ITimeoutManager>().Register(c => new DisabledTimeoutManager(), description: AsqTimeoutManagerText);

            configurer.OtherService<IPipeline>().Decorate(c =>
            {
                var pipeline = c.Get<IPipeline>();

                return new PipelineStepRemover(pipeline)
                    .RemoveIncomingStep(s => s.GetType() == typeof(HandleDeferredMessagesStep));
            });
        }
 static void Configure(StandardConfigurer<IDataBusStorage> configurer, string containerName, CloudStorageAccount cloudStorageAccount)
 {
     configurer.Register(c => new AzureBlobsDataBusStorage(cloudStorageAccount,containerName, c.Get<IRebusLoggerFactory>()));
 }
 static void Register(StandardConfigurer<ITransport> configurer, string inputQueueAddress, CloudStorageAccount storageAccount)
 {
     configurer.Register(c => new AzureStorageQueuesTransport(storageAccount, inputQueueAddress));
 }