/// <summary> /// Constructs the saga storage /// </summary> public PostgreSqlSagaStorage(PostgresConnectionHelper connectionHelper, string dataTableName, string indexTableName, IRebusLoggerFactory rebusLoggerFactory) { _connectionHelper = connectionHelper; _dataTableName = dataTableName; _indexTableName = indexTableName; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Creates the worker factory /// </summary> public ThreadPoolWorkerFactory(ITransport transport, IRebusLoggerFactory rebusLoggerFactory, IPipeline pipeline, IPipelineInvoker pipelineInvoker, Options options, Func<RebusBus> busGetter, BusLifetimeEvents busLifetimeEvents, ISyncBackoffStrategy backoffStrategy) { if (transport == null) throw new ArgumentNullException(nameof(transport)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); if (pipeline == null) throw new ArgumentNullException(nameof(pipeline)); if (pipelineInvoker == null) throw new ArgumentNullException(nameof(pipelineInvoker)); if (options == null) throw new ArgumentNullException(nameof(options)); if (busGetter == null) throw new ArgumentNullException(nameof(busGetter)); if (busLifetimeEvents == null) throw new ArgumentNullException(nameof(busLifetimeEvents)); if (backoffStrategy == null) throw new ArgumentNullException(nameof(backoffStrategy)); _transport = transport; _rebusLoggerFactory = rebusLoggerFactory; _pipeline = pipeline; _pipelineInvoker = pipelineInvoker; _options = options; _busGetter = busGetter; _backoffStrategy = backoffStrategy; _parallelOperationsManager = new ParallelOperationsManager(options.MaxParallelism); _log = _rebusLoggerFactory.GetCurrentClassLogger(); if (_options.MaxParallelism < 1) { throw new ArgumentException($"Max parallelism is {_options.MaxParallelism} which is an invalid value"); } if (options.WorkerShutdownTimeout < TimeSpan.Zero) { throw new ArgumentOutOfRangeException($"Cannot use '{options.WorkerShutdownTimeout}' as worker shutdown timeout as it"); } busLifetimeEvents.WorkersStopped += WaitForContinuationsToFinish; }
/// <summary> /// Constructs the transport with the specified settings /// </summary> public AmazonSqsTransport(string inputQueueAddress, string accessKeyId, string secretAccessKey, AmazonSQSConfig amazonSqsConfig, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory) { if (accessKeyId == null) throw new ArgumentNullException(nameof(accessKeyId)); if (secretAccessKey == null) throw new ArgumentNullException(nameof(secretAccessKey)); if (amazonSqsConfig == null) throw new ArgumentNullException(nameof(amazonSqsConfig)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); Address = inputQueueAddress; _log = rebusLoggerFactory.GetCurrentClassLogger(); if (Address != null) { if (Address.Contains("/") && !Uri.IsWellFormedUriString(Address, UriKind.Absolute)) { throw new ArgumentException( "You could either have a simple queue name without slash (eg. \"inputqueue\") - or a complete URL for the queue endpoint. (eg. \"https://sqs.eu-central-1.amazonaws.com/234234234234234/somqueue\")", nameof(inputQueueAddress)); } } _accessKeyId = accessKeyId; _secretAccessKey = secretAccessKey; _amazonSqsConfig = amazonSqsConfig; _asyncTaskFactory = asyncTaskFactory; }
/// <summary> /// Creates the data storage /// </summary> public FileSystemDataBusStorage(string directoryPath, IRebusLoggerFactory rebusLoggerFactory) { if (directoryPath == null) throw new ArgumentNullException(nameof(directoryPath)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _directoryPath = directoryPath; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Constructs the step, using the given transport and settings /// </summary> public SimpleRetryStrategyStep(ITransport transport, SimpleRetryStrategySettings simpleRetryStrategySettings, IErrorTracker errorTracker, IRebusLoggerFactory rebusLoggerFactory) { _transport = transport; _simpleRetryStrategySettings = simpleRetryStrategySettings; _errorTracker = errorTracker; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Constructs the step, using the specified transport to send the messages /// </summary> public SendOutgoingMessageStep(ITransport transport, IRebusLoggerFactory rebusLoggerFactory) { if (transport == null) throw new ArgumentNullException(nameof(transport)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _transport = transport; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
public ReplyHandlerStep(ConcurrentDictionary<string, TimedMessage> messages, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, TimeSpan replyMaxAge) { _messages = messages; _replyMaxAge = replyMaxAge; _log = rebusLoggerFactory.GetCurrentClassLogger(); _cleanupTask = asyncTaskFactory.Create("CleanupAbandonedRepliesTask", CleanupAbandonedReplies); }
/// <summary> /// Constructs the subscription storage, storing subscriptions in the specified <paramref name="tableName"/>. /// If <paramref name="isCentralized"/> is true, subscribing/unsubscribing will be short-circuited by manipulating /// subscriptions directly, instead of requesting via messages /// </summary> public PostgreSqlSubscriptionStorage(PostgresConnectionHelper connectionHelper, string tableName, bool isCentralized, IRebusLoggerFactory rebusLoggerFactory) { _connectionHelper = connectionHelper; _tableName = tableName; IsCentralized = isCentralized; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Constructs the storage using the specified connection provider and table to store its subscriptions. If the subscription /// storage is shared by all subscribers and publishers, the <paramref name="isCentralized"/> parameter can be set to true /// in order to subscribe/unsubscribe directly instead of sending subscription/unsubscription requests /// </summary> public SqlServerSubscriptionStorage(IDbConnectionProvider connectionProvider, string tableName, bool isCentralized, IRebusLoggerFactory rebusLoggerFactory) { IsCentralized = isCentralized; _log = rebusLoggerFactory.GetCurrentClassLogger(); _connectionProvider = connectionProvider; _tableName = tableName; }
/// <summary> /// Constructs the transport with the specified settings /// </summary> public AmazonSqsTransport(string inputQueueAddress, string accessKeyId, string secretAccessKey, RegionEndpoint regionEndpoint, IRebusLoggerFactory rebusLoggerFactory) { if (accessKeyId == null) throw new ArgumentNullException("accessKeyId"); if (secretAccessKey == null) throw new ArgumentNullException("secretAccessKey"); if (regionEndpoint == null) throw new ArgumentNullException("regionEndpoint"); if (rebusLoggerFactory == null) throw new ArgumentNullException("rebusLoggerFactory"); _inputQueueAddress = inputQueueAddress; _log = rebusLoggerFactory.GetCurrentClassLogger(); if (_inputQueueAddress != null) { if (_inputQueueAddress.Contains("/") && !Uri.IsWellFormedUriString(_inputQueueAddress, UriKind.Absolute)) { throw new ArgumentException( "You could either have a simple queue name without slash (eg. \"inputqueue\") - or a complete URL for the queue endpoint. (eg. \"https://sqs.eu-central-1.amazonaws.com/234234234234234/somqueue\")", "inputQueueAddress"); } } _accessKeyId = accessKeyId; _secretAccessKey = secretAccessKey; _regionEndpoint = regionEndpoint; _rebusLoggerFactory = rebusLoggerFactory; }
/// <summary> /// Constructs the transport with a connection to the RabbitMQ instance specified by the given connection string /// </summary> public RabbitMqTransport(string connectionString, string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory) { _connectionManager = new ConnectionManager(connectionString, inputQueueAddress, rebusLoggerFactory); _log = rebusLoggerFactory.GetCurrentClassLogger(); Address = inputQueueAddress; }
/// <summary> /// Constructs the step with the given saga storage /// </summary> public LoadSagaDataStep(ISagaStorage sagaStorage, IRebusLoggerFactory rebusLoggerFactory) { if (sagaStorage == null) throw new ArgumentNullException(nameof(sagaStorage)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _sagaStorage = sagaStorage; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
public void Run() { if (Verbose) { Text.PrintLine("Enabling verbose logging"); LoggerFactory = new ConsoleLoggerFactory(true) { ShowTimestamps = false, MinLevel = LogLevel.Debug, }; } else { Text.PrintLine("Verbose logging disabled (enable with -verbose)"); LoggerFactory = new ConsoleLoggerFactory(true) { MinLevel = LogLevel.Warn, ShowTimestamps = false }; } DoRun(); }
/// <summary> /// Constructs the saga storage, using the specified connection provider and tables for persistence. /// </summary> public SqlServerSagaStorage(IDbConnectionProvider connectionProvider, string dataTableName, string indexTableName, IRebusLoggerFactory rebusLoggerFactory) { _log = rebusLoggerFactory.GetCurrentClassLogger(); _connectionProvider = connectionProvider; _dataTableName = dataTableName; _indexTableName = indexTableName; }
/// <summary> /// Constructs the subscription storage using the specified document store. Can be configured to be centralized /// </summary> public RavenDbSubscriptionStorage(IDocumentStore documentStore, bool isCentralized, IRebusLoggerFactory rebusLoggerFactory) { if (documentStore == null) throw new ArgumentNullException(nameof(documentStore)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _documentStore = documentStore; IsCentralized = isCentralized; _logger = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Constructs the periodic background task with the given <paramref name="description"/>, periodically executing the given <paramref name="action"/>, /// waiting <see cref="Interval"/> between invocations. /// </summary> public TimerAsyncTask(string description, Func<Task> action, IRebusLoggerFactory rebusLoggerFactory, bool prettyInsignificant) { _log = rebusLoggerFactory.GetLogger<TimerAsyncTask>(); _description = description; _action = action; _prettyInsignificant = prettyInsignificant; Interval = DefaultInterval; }
/// <summary> /// Constructs the snapshot storage which will write saga data snapshots to files using file names on the form "ID-REVISION.json" /// </summary> public FileSystemSagaSnapshotStorage(string snapshotDirectory, IRebusLoggerFactory rebusLoggerFactory) { if (snapshotDirectory == null) throw new ArgumentNullException("snapshotDirectory"); if (rebusLoggerFactory == null) throw new ArgumentNullException("rebusLoggerFactory"); _snapshotDirectory = snapshotDirectory; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Creates the saga storage using the given <paramref name="basePath"/> /// </summary> public FileSystemSagaStorage(string basePath, IRebusLoggerFactory rebusLoggerFactory) { if (basePath == null) throw new ArgumentNullException(nameof(basePath)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _basePath = basePath; _log = rebusLoggerFactory.GetCurrentClassLogger(); _lockFile = Path.Combine(basePath, "lock.txt"); }
/// <summary> /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX /// </summary> public InMemErrorTracker(int maxDeliveryAttempts, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory) { if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); if (asyncTaskFactory == null) throw new ArgumentNullException(nameof(asyncTaskFactory)); _maxDeliveryAttempts = maxDeliveryAttempts; _log = rebusLoggerFactory.GetCurrentClassLogger(); _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(BackgroundTaskName, CleanupOldTrackedErrors, intervalSeconds: 60); }
/// <summary> /// Creates the timeout manager, storing timeouts in the given <paramref name="basePath"/> /// </summary> public FilesystemTimeoutManager(string basePath, IRebusLoggerFactory loggerFactory) { if (basePath == null) throw new ArgumentNullException(nameof(basePath)); if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); _basePath = basePath; _lockFile = Path.Combine(basePath, "lock.txt"); _log = loggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Constructs the periodic background task with the given <paramref name="description"/>, periodically executing the given <paramref name="action"/>, /// waiting <see cref="Interval"/> between invocations. /// </summary> public AsyncTask(string description, Func<Task> action, IRebusLoggerFactory rebusLoggerFactory, bool prettyInsignificant = false) { _description = description; _action = action; _prettyInsignificant = prettyInsignificant; _log = rebusLoggerFactory.GetCurrentClassLogger(); Interval = DefaultInterval; }
/// <summary> /// Creates the storage /// </summary> public AzureStorageSagaSnapshotStorage(CloudStorageAccount storageAccount, IRebusLoggerFactory loggerFactory, string containerName = "RebusSagaStorage") { if (storageAccount == null) throw new ArgumentNullException(nameof(storageAccount)); if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); _log = loggerFactory.GetCurrentClassLogger(); _container = storageAccount.CreateCloudBlobClient() .GetContainerReference(containerName.ToLowerInvariant()); }
/// <summary> /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX /// </summary> public InMemErrorTracker(int maxDeliveryAttempts, IRebusLoggerFactory rebusLoggerFactory) { _maxDeliveryAttempts = maxDeliveryAttempts; _log = rebusLoggerFactory.GetCurrentClassLogger(); _cleanupOldTrackedErrorsTask = new AsyncTask(BackgroundTaskName, CleanupOldTrackedErrors, rebusLoggerFactory) { Interval = TimeSpan.FromMinutes(1) }; }
/// <summary> /// Constructs the timeout manager /// </summary> public PostgreSqlTimeoutManager(PostgresConnectionHelper connectionHelper, string tableName, IRebusLoggerFactory rebusLoggerFactory) { if (connectionHelper == null) throw new ArgumentNullException(nameof(connectionHelper)); if (tableName == null) throw new ArgumentNullException(nameof(tableName)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _connectionHelper = connectionHelper; _tableName = tableName; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Creates the error handler /// </summary> public PoisonQueueErrorHandler(SimpleRetryStrategySettings simpleRetryStrategySettings, ITransport transport, IRebusLoggerFactory rebusLoggerFactory) { if (simpleRetryStrategySettings == null) throw new ArgumentNullException(nameof(simpleRetryStrategySettings)); if (transport == null) throw new ArgumentNullException(nameof(transport)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _simpleRetryStrategySettings = simpleRetryStrategySettings; _transport = transport; _log = rebusLoggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Constructs the step, using the specified <see cref="ITimeoutManager"/> to defer relevant messages /// and the specified <see cref="ITransport"/> to deliver messages when they're due. /// </summary> public HandleDeferredMessagesStep(ITimeoutManager timeoutManager, ITransport transport, Options options, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory) { _timeoutManager = timeoutManager; _transport = transport; _options = options; _log = rebusLoggerFactory.GetCurrentClassLogger(); _dueMessagesSenderBackgroundTask = asyncTaskFactory.Create(DueMessagesSenderTaskName, TimerElapsed, intervalSeconds: 1); }
/// <summary> /// Creates the data bus storage /// </summary> public AzureBlobsDataBusStorage(CloudStorageAccount storageAccount, string containerName, IRebusLoggerFactory loggerFactory) { if (storageAccount == null) throw new ArgumentNullException(nameof(storageAccount)); if (containerName == null) throw new ArgumentNullException(nameof(containerName)); if (loggerFactory == null) throw new ArgumentNullException(nameof(loggerFactory)); _containerName = containerName.ToLowerInvariant(); _client = storageAccount.CreateCloudBlobClient(); _log = loggerFactory.GetCurrentClassLogger(); }
/// <summary> /// Uses provided SqlConnection factory as constructor for SqlConnection used. Will use <see cref="System.Data.IsolationLevel.ReadCommitted"/> by default on transactions, /// unless another isolation level is set with the <see cref="IsolationLevel"/> property /// </summary> public DbConnectionFactoryProvider(Func<Task<IDbConnection>> connectionFactory, IRebusLoggerFactory rebusLoggerFactory) { if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _log = rebusLoggerFactory.GetCurrentClassLogger(); IsolationLevel = IsolationLevel.ReadCommitted; _connectionFactory = connectionFactory; }
public AzureStorageSubscriptionStorage(CloudStorageAccount cloudStorageAccount, IRebusLoggerFactory loggerFactory, bool isCentralized = false, string tableName = "RebusSubscriptions") { IsCentralized = isCentralized; _cloudStorageAccount = cloudStorageAccount; _loggerFactory = loggerFactory; _tableName = tableName; }
/// <summary> /// Constructs the transport with a connection to the RabbitMQ instance specified by the given connection string /// </summary> public RabbitMqTransport(string connectionString, string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory, ushort maxMessagesToPrefetch = 50) { if (connectionString == null) throw new ArgumentNullException(nameof(connectionString)); if (rebusLoggerFactory == null) throw new ArgumentNullException(nameof(rebusLoggerFactory)); _connectionManager = new ConnectionManager(connectionString, inputQueueAddress, rebusLoggerFactory); _maxMessagesToPrefetch = maxMessagesToPrefetch; _log = rebusLoggerFactory.GetCurrentClassLogger(); Address = inputQueueAddress; }
RabbitMqTransport(IRebusLoggerFactory rebusLoggerFactory, int maxMessagesToPrefetch, string inputQueueAddress) { if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } if (maxMessagesToPrefetch <= 0) { throw new ArgumentException($"Cannot set 'maxMessagesToPrefetch' to {maxMessagesToPrefetch} - it must be at least 1!"); } _maxMessagesToPrefetch = (ushort)maxMessagesToPrefetch; _log = rebusLoggerFactory.GetLogger <RabbitMqTransport>(); Address = inputQueueAddress; }
/// <summary> /// Constructs the transport, connecting to the service bus pointed to by the connection string. /// </summary> public AzureServiceBusTransport(string connectionString, string queueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, INameFormatter nameFormatter, CancellationToken cancellationToken = default(CancellationToken), ITokenProvider tokenProvider = null) { if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } if (asyncTaskFactory == null) { throw new ArgumentNullException(nameof(asyncTaskFactory)); } _nameFormatter = nameFormatter; if (queueName != null) { // this never happens if (queueName.StartsWith(MagicSubscriptionPrefix)) { throw new ArgumentException($"Sorry, but the queue name '{queueName}' cannot be used because it conflicts with Rebus' internally used 'magic subscription prefix': '{MagicSubscriptionPrefix}'. "); } Address = _nameFormatter.FormatQueueName(queueName); _subscriptionName = _nameFormatter.FormatSubscriptionName(queueName); } _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); _cancellationToken = cancellationToken; _log = rebusLoggerFactory.GetLogger <AzureServiceBusTransport>(); if (tokenProvider != null) { var connectionStringBuilder = new ServiceBusConnectionStringBuilder(connectionString); _managementClient = new ManagementClient(connectionStringBuilder, tokenProvider); _endpoint = connectionStringBuilder.Endpoint; _transportType = connectionStringBuilder.TransportType; } else { _managementClient = new ManagementClient(connectionString); } _tokenProvider = tokenProvider; _messageLockRenewalTask = asyncTaskFactory.Create("Peek Lock Renewal", RenewPeekLocks, prettyInsignificant: true, intervalSeconds: 10); }
/// <summary> /// Constructor /// </summary> /// <param name="connectionProvider">A <see cref="IDbConnection"/> to obtain a database connection</param> /// <param name="inputQueueName">Name of the queue this transport is servicing</param> /// <param name="rebusLoggerFactory">A <seealso cref="IRebusLoggerFactory"/> for building loggers</param> /// <param name="asyncTaskFactory">A <seealso cref="IAsyncTaskFactory"/> for creating periodic tasks</param> /// <param name="rebusTime">A <seealso cref="IRebusTime"/> to provide the current time</param> /// <param name="options">Additional options</param> public MySqlTransport( IDbConnectionProvider connectionProvider, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, IRebusTime rebusTime, MySqlTransportOptions options) { if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } if (asyncTaskFactory == null) { throw new ArgumentNullException(nameof(asyncTaskFactory)); } _rebusTime = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime)); _connectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider)); _receiveTableName = inputQueueName != null?TableName.Parse(inputQueueName) : null; _log = rebusLoggerFactory.GetLogger <MySqlTransport>(); var cleanupInterval = options.ExpiredMessagesCleanupInterval ?? DefaultExpiredMessagesCleanupInterval; var intervalSeconds = (int)cleanupInterval.TotalSeconds; _expiredMessagesCleanupTask = asyncTaskFactory.Create("ExpiredMessagesCleanup", PerformExpiredMessagesCleanupCycle, intervalSeconds: intervalSeconds); _autoDeleteQueue = options.AutoDeleteQueue; _leasedByFactory = options.LeasedByFactory ?? (() => Environment.MachineName); _leaseInterval = options.LeaseInterval ?? DefaultLeaseTime; _leaseTolerance = options.LeaseInterval ?? DefaultLeaseTolerance; _ensureTablesAreCreated = options.EnsureTablesAreCreated; var automaticLeaseRenewalInterval = options.LeaseAutoRenewInterval; if (!automaticLeaseRenewalInterval.HasValue) { _automaticLeaseRenewal = false; } else { _automaticLeaseRenewal = true; _automaticLeaseRenewalInterval = automaticLeaseRenewalInterval.Value; } }
internal ThreadPoolWorker(string name, ITransport transport, IRebusLoggerFactory rebusLoggerFactory, IPipeline pipeline, IPipelineInvoker pipelineInvoker, ParallelOperationsManager parallelOperationsManager, RebusBus owningBus, Options options, ISyncBackoffStrategy backoffStrategy) { Name = name; _log = rebusLoggerFactory.GetCurrentClassLogger(); _transport = transport; _pipeline = pipeline; _pipelineInvoker = pipelineInvoker; _parallelOperationsManager = parallelOperationsManager; _owningBus = owningBus; _options = options; _backoffStrategy = backoffStrategy; _workerThread = new Thread(Run) { Name = name, IsBackground = true }; _workerThread.Start(); }
/// <summary> /// Constructs the transport, connecting to the service bus pointed to by the connection string. /// </summary> public BasicAzureServiceBusTransport(string connectionString, string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory) { if (connectionString == null) { throw new ArgumentNullException("connectionString"); } _namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString); _connectionString = connectionString; _rebusLoggerFactory = rebusLoggerFactory; _asyncTaskFactory = asyncTaskFactory; _log = rebusLoggerFactory.GetCurrentClassLogger(); if (inputQueueAddress != null) { _inputQueueAddress = inputQueueAddress.ToLowerInvariant(); } }
public KafkaTransport( IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, ISerializer customSerializer, string brokerList, string groupId, string topicPrefix) { _log = rebusLoggerFactory.GetLogger <KafkaTransport>(); _brokerList = brokerList; _customSerializer = customSerializer; _groupId = groupId; _knownRoutes = new ConcurrentBag <string>(); _knownRoutes.Add($"^{topicPrefix}.*"); _knownRoutes.Add($"{topicPrefix}"); _topicPrefix = topicPrefix; _asyncTaskFactory = asyncTaskFactory ?? throw new ArgumentNullException(nameof(asyncTaskFactory)); }
internal KafkaSubscriptionStorage(IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory , string brokerList, string inputQueueName, string groupId = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(brokerList)) { throw new NullReferenceException(nameof(brokerList)); } var maxNameLength = 249; if (inputQueueName.Length > maxNameLength && _topicRegex.IsMatch(inputQueueName)) { throw new ArgumentException("Invalid characters or length of a topic (file)", nameof(inputQueueName)); } if (inputQueueName.StartsWith(_magicSubscriptionPrefix)) { throw new ArgumentException($"Sorry, but the queue name '{inputQueueName}' cannot be used because it conflicts with Rebus' internally used 'magic subscription prefix': '{_magicSubscriptionPrefix}'. "); } _config = new ConsumerConfig { BootstrapServers = brokerList, ApiVersionRequest = true, GroupId = !string.IsNullOrEmpty(groupId) ? groupId : Guid.NewGuid().ToString("N"), EnableAutoCommit = false, FetchWaitMaxMs = 5, FetchErrorBackoffMs = 5, QueuedMinMessages = 1000, SessionTimeoutMs = 6000, //StatisticsIntervalMs = 5000, #if DEBUG TopicMetadataRefreshIntervalMs = 20000, // Otherwise it runs maybe five minutes Debug = "msg", #endif AutoOffsetReset = AutoOffsetReset.Latest, EnablePartitionEof = true }; _config.Set("fetch.message.max.bytes", "10240"); _asyncTaskFactory = asyncTaskFactory ?? throw new ArgumentNullException(nameof(asyncTaskFactory)); _log = rebusLoggerFactory.GetLogger <KafkaSubscriptionStorage>(); _cancellationToken = cancellationToken; _subscriptions.TryAdd(inputQueueName, new[] { inputQueueName }); }
public TplWorker(string workerName, RebusBus owningBus, ITransport transport, IRebusLoggerFactory rebusLoggerFactory, IPipelineInvoker pipelineInvoker, ParallelOperationsManager parallelOperationsManager, Options options, IBackoffStrategy backoffStrategy, CancellationToken busDisposalCancellationToken) { _owningBus = owningBus; _transport = transport; _pipelineInvoker = pipelineInvoker; _parallelOperationsManager = parallelOperationsManager; _options = options; _backoffStrategy = backoffStrategy; _busDisposalCancellationToken = busDisposalCancellationToken; Name = workerName; _cancellationToken = _cancellationTokenSource.Token; _log = rebusLoggerFactory.GetLogger <TplWorker>(); Task.Run(Run); }
/// <summary> /// Enables message validation for incoming messages using FluentValidation. /// <para> /// When an incoming message fails to validate, by default it is wrapped in a <see cref="IValidationFailed{TMessage}"/> message and dispatched to handlers implementing this wrapped message type. Use the <paramref name="onFailed"/> builder to configure if messages should be handled differently (f.ex. move to error queue, drop, etc.). /// </para> /// </summary> /// <param name="configurer">The options configurer.</param> /// <param name="validatorFactory">The FluentValidation validator factory to resolve message validators from.</param> /// <param name="onFailed">A builder to configure how messages should be handled when validation fails.</param> public static void ValidateIncomingMessages(this OptionsConfigurer configurer, IValidatorFactory validatorFactory, Action <ValidationConfigurer>?onFailed = null) { if (configurer is null) { throw new ArgumentNullException(nameof(configurer)); } if (validatorFactory is null) { throw new ArgumentNullException(nameof(validatorFactory)); } var opts = new ValidationConfigurer(configurer); onFailed?.Invoke(opts); configurer.Register(ctx => { IRebusLoggerFactory loggerFactory = ctx.Get <IRebusLoggerFactory>(); return(new ValidateIncomingStep( loggerFactory.GetLogger <ValidateIncomingStep>(), validatorFactory, ctx.Get <IReadOnlyDictionary <Type, IValidationFailedStrategy> >(), // By default, handle as IValidationFailed<> ctx.Get <WrapAsValidationFailed>() )); }); configurer.Decorate <IPipeline>(ctx => { IPipeline pipeline = ctx.Get <IPipeline>(); var pipelineInjector = new PipelineStepInjector(pipeline); ValidateIncomingStep incomingStep = ctx.Get <ValidateIncomingStep>(); pipelineInjector.OnReceive( incomingStep, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep) ); return(pipelineInjector); }); }
public AmazonS3DataBusStorage( AmazonS3Config amazonS3Config, AmazonS3DataBusOptions options, TransferUtilityConfig transferUtilityConfig, IRebusLoggerFactory rebusLoggerFactory, IRebusTime rebusTime) { _amazonS3Config = amazonS3Config ?? throw new ArgumentNullException(nameof(amazonS3Config)); _transferUtilityConfig = transferUtilityConfig ?? throw new ArgumentNullException(nameof(transferUtilityConfig)); _rebusTime = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime)); _options = options ?? throw new ArgumentNullException(nameof(options)); _log = rebusLoggerFactory?.GetLogger <AmazonS3DataBusStorage>() ?? throw new ArgumentNullException(nameof(rebusLoggerFactory)); _metadataCollectionFactory = new S3MetadataCollectionFactory(options); if (options.AutoCreateBucket) { EnsureBucketExistsAsync().GetAwaiter().GetResult(); } }
public ConnectionManager(string connectionString, string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory) { if (connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } _log = rebusLoggerFactory.GetCurrentClassLogger(); if (inputQueueAddress != null) { _log.Info("Initializing RabbitMQ connection manager for transport with input queue '{0}'", inputQueueAddress); } else { _log.Info("Initializing RabbitMQ connection manager for one-way transport"); } _connectionFactories = connectionString.Split(";,".ToCharArray(), StringSplitOptions.RemoveEmptyEntries) .Select(uri => new ConnectionFactory { Uri = uri.Trim(), AutomaticRecoveryEnabled = true, NetworkRecoveryInterval = TimeSpan.FromSeconds(50), ClientProperties = CreateClientProperties(inputQueueAddress) }) .ToArray(); if (_connectionFactories.Length == 0) { throw new ArgumentException("Please remember to specify at least one connection string for a RabbitMQ server somewhere. You can also add multiple connection strings separated by ; or , which Rebus will use in failover scenarios"); } if (_connectionFactories.Length > 1) { _log.Info("RabbitMQ transport has {0} connection strings available", _connectionFactories.Length); } }
/// <summary> /// Constructs the transport with a connection to the RabbitMQ instance specified by the given connection string /// </summary> public RabbitMqTransport(string connectionString, string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory, int maxMessagesToPrefetch = 50) { if (connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } if (maxMessagesToPrefetch <= 0) { throw new ArgumentException($"Cannot set 'maxMessagesToPrefetch' to {maxMessagesToPrefetch} - it must be at least 1!"); } _connectionManager = new ConnectionManager(connectionString, inputQueueAddress, rebusLoggerFactory); _maxMessagesToPrefetch = (ushort)maxMessagesToPrefetch; _log = rebusLoggerFactory.GetCurrentClassLogger(); Address = inputQueueAddress; }
internal ThreadPoolWorker(string name, ITransport transport, IRebusLoggerFactory rebusLoggerFactory, IPipelineInvoker pipelineInvoker, ParallelOperationsManager parallelOperationsManager, RebusBus owningBus, Options options, IBackoffStrategy backoffStrategy, CancellationToken busDisposalCancellationToken) { Name = name; _log = rebusLoggerFactory.GetLogger <ThreadPoolWorker>(); _transport = transport; _pipelineInvoker = pipelineInvoker; _parallelOperationsManager = parallelOperationsManager; _owningBus = owningBus; _options = options; _backoffStrategy = backoffStrategy; _busDisposalCancellationToken = busDisposalCancellationToken; _workerThread = new Thread(Run) { Name = name, IsBackground = true }; _workerThread.Start(); }
public MySqlMessageStorage(MySqlConnectionHelper connectionHelper, string dataTableName, IRebusLoggerFactory rebusLoggerFactory) { if (connectionHelper == null) { throw new ArgumentNullException(nameof(connectionHelper)); } if (dataTableName == null) { throw new ArgumentNullException(nameof(dataTableName)); } if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } _connectionHelper = connectionHelper; _dataTableName = dataTableName; _log = rebusLoggerFactory.GetLogger <MySqlMessageStorage>(); _serializer = new IdempotencyDataSerializer(); }
/// <summary> /// Wraps the connection string with the given name from app.config (if it is found), or interprets the given string as /// a connection string to use. Will use <see cref="System.Data.IsolationLevel.ReadCommitted"/> by default on transactions, /// unless another isolation level is set with the <see cref="IsolationLevel"/> property /// </summary> public DbConnectionProvider(string connectionStringOrConnectionStringName, IRebusLoggerFactory rebusLoggerFactory #if NET45 , bool enlistInAmbientTransaction = false #endif ) { if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } _log = rebusLoggerFactory.GetLogger <DbConnectionProvider>(); var connectionString = GetConnectionString(connectionStringOrConnectionStringName); _connectionString = EnsureMarsIsEnabled(connectionString); #if NET45 _enlistInAmbientTransaction = enlistInAmbientTransaction; #endif IsolationLevel = IsolationLevel.ReadCommitted; }
public ConnectionManager(string connectionString, string inputQueueAddress, IRebusLoggerFactory rebusLoggerFactory) { _log = rebusLoggerFactory.GetCurrentClassLogger(); if (inputQueueAddress != null) { _log.Info("Initializing RabbitMQ connection manager for transport with input queue '{0}'", inputQueueAddress); } else { _log.Info("Initializing RabbitMQ connection manager for one-way transport"); } _connectionFactory = new ConnectionFactory { Uri = connectionString, ClientProperties = CreateClientProperties(inputQueueAddress), AutomaticRecoveryEnabled = true, NetworkRecoveryInterval = TimeSpan.FromSeconds(50), }; }
public RabbitMqMangler(ITransport transport, IRebusLoggerFactory rebusLoggerFactory) { transport = GetActualRabbitTransport(transport); if (rebusLoggerFactory == null) { throw new ArgumentNullException("rebusLoggerFactory cannot be null"); } if (transport == null) { throw new ArgumentNullException("transport cannot be null"); } EnsureIsRabbitMqTransport(transport); _transport = transport; _transportType = transport.GetType(); _connectionManager = ConnectionManagerField.Value.GetValue(transport); _log = rebusLoggerFactory.GetLogger <RabbitMqMangler>(); }
public KafkaTransport(IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, string brokerList, string inputQueueName, string groupId = null) { var maxNameLength = 249; if (inputQueueName.Length > maxNameLength && _topicRegex.IsMatch(inputQueueName)) { throw new ArgumentException("Недопустимые символы или длинна топика (файла)", nameof(inputQueueName)); } if (inputQueueName.StartsWith(_magicSubscriptionPrefix)) { throw new ArgumentException($"Sorry, but the queue name '{inputQueueName}' cannot be used because it conflicts with Rebus' internally used 'magic subscription prefix': '{_magicSubscriptionPrefix}'. "); } _knownRoutes = new ConcurrentDictionary <string, string>(); _knownRoutes.TryAdd(inputQueueName, inputQueueName); Address = inputQueueName; _brokerList = brokerList; _groupId = groupId; _log = rebusLoggerFactory.GetLogger <KafkaTransport>(); _asyncTaskFactory = asyncTaskFactory ?? throw new ArgumentNullException(nameof(asyncTaskFactory)); }
/// <summary>Creates new instance <see cref="KafkaTransport"/>. Performs a simplified /// configuration of the parameters of the manufacturer and the consumer used in this transport.</summary> /// <param name="rebusLoggerFactory"></param> /// <param name="asyncTaskFactory"></param> /// <param name="brokerList">Initial list of brokers as a CSV list of broker host or host:port.</param> /// <param name="inputQueueName">name of input queue</param> /// <param name="groupId">Id of group</param> /// <param name="cancellationToken"></param> public KafkaTransport(IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, string brokerList , string inputQueueName, string groupId = null, CancellationToken cancellationToken = default(CancellationToken)) { if (string.IsNullOrWhiteSpace(brokerList)) { throw new NullReferenceException(nameof(brokerList)); } _producerConfig = new ProducerConfig { BootstrapServers = brokerList, ApiVersionRequest = true, QueueBufferingMaxKbytes = 10240, //{ "socket.blocking.max.ms", 1 }, // **DEPRECATED * *No longer used. #if DEBUG Debug = "msg", #endif MessageTimeoutMs = 3000, }; _producerConfig.Set("request.required.acks", "-1"); _producerConfig.Set("queue.buffering.max.ms", "5"); if (!string.IsNullOrWhiteSpace(inputQueueName)) { var maxNameLength = 249; if (inputQueueName.Length > maxNameLength && _topicRegex.IsMatch(inputQueueName)) { throw new ArgumentException("Недопустимые символы или длинна топика (файла)", nameof(inputQueueName)); } Address = inputQueueName; _queueSubscriptionStorage = new KafkaSubscriptionStorage(rebusLoggerFactory, asyncTaskFactory, brokerList , inputQueueName, groupId, cancellationToken); } _log = rebusLoggerFactory.GetLogger <KafkaTransport>(); _asyncTaskFactory = asyncTaskFactory ?? throw new ArgumentNullException(nameof(asyncTaskFactory)); _cancellationToken = cancellationToken; }
/// <summary> /// Constructs the transport with the specified settings /// </summary> public AmazonSqsTransport(string inputQueueAddress, string accessKeyId, string secretAccessKey, RegionEndpoint regionEndpoint, IRebusLoggerFactory rebusLoggerFactory) { if (accessKeyId == null) { throw new ArgumentNullException("accessKeyId"); } if (secretAccessKey == null) { throw new ArgumentNullException("secretAccessKey"); } if (regionEndpoint == null) { throw new ArgumentNullException("regionEndpoint"); } if (rebusLoggerFactory == null) { throw new ArgumentNullException("rebusLoggerFactory"); } _inputQueueAddress = inputQueueAddress; _log = rebusLoggerFactory.GetCurrentClassLogger(); if (_inputQueueAddress != null) { if (_inputQueueAddress.Contains("/") && !Uri.IsWellFormedUriString(_inputQueueAddress, UriKind.Absolute)) { throw new ArgumentException( "You could either have a simple queue name without slash (eg. \"inputqueue\") - or a complete URL for the queue endpoint. (eg. \"https://sqs.eu-central-1.amazonaws.com/234234234234234/somqueue\")", "inputQueueAddress"); } } _accessKeyId = accessKeyId; _secretAccessKey = secretAccessKey; _regionEndpoint = regionEndpoint; _rebusLoggerFactory = rebusLoggerFactory; }
/// <summary> /// Enables message validation for outgoing messages using FluentValidation. /// <para> /// When an outgoing message sent/published to the bus fails to validate, a <see cref="ValidationException"/> will be thrown immediately. /// </para> /// </summary> /// <param name="configurer">The options configurer.</param> /// <param name="validatorFactory">The FluentValidation validator factory to resolve message validators from.</param> public static void ValidateOutgoingMessages(this OptionsConfigurer configurer, IValidatorFactory validatorFactory) { if (configurer is null) { throw new ArgumentNullException(nameof(configurer)); } if (validatorFactory is null) { throw new ArgumentNullException(nameof(validatorFactory)); } configurer.Register(ctx => { IRebusLoggerFactory loggerFactory = ctx.Get <IRebusLoggerFactory>(); return(new ValidateOutgoingStep( loggerFactory.GetLogger <ValidateIncomingStep>(), validatorFactory )); }); configurer.Decorate <IPipeline>(ctx => { IPipeline pipeline = ctx.Get <IPipeline>(); var pipelineInjector = new PipelineStepInjector(pipeline); ValidateOutgoingStep outgoingStep = ctx.Get <ValidateOutgoingStep>(); pipelineInjector.OnSend( outgoingStep, PipelineRelativePosition.Before, typeof(AssignDefaultHeadersStep) ); return(pipelineInjector); }); }
/// <summary> /// Constructor /// </summary> /// <param name="connectionProvider">A <see cref="IDbConnection"/> to obtain a database connection</param> /// <param name="inputQueueName">Name of the queue this transport is servicing</param> /// <param name="rebusLoggerFactory">A <seealso cref="IRebusLoggerFactory"/> for building loggers</param> /// <param name="asyncTaskFactory">A <seealso cref="IAsyncTaskFactory"/> for creating periodic tasks</param> /// <param name="leaseInterval">Interval of time messages are leased for</param> /// <param name="leaseTolerance">Buffer to allow lease overruns by</param> /// <param name="leasedByFactory">Factory for generating a string which identifies who has leased a message (eg. A hostname)</param> /// <param name="automaticLeaseRenewalInterval">If non-<c>null</c> messages will be automatically re-leased after this time period has elapsed</param> public SqlServerLeaseTransport( IDbConnectionProvider connectionProvider, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, TimeSpan leaseInterval, TimeSpan?leaseTolerance, Func <string> leasedByFactory, TimeSpan?automaticLeaseRenewalInterval = null ) : base(connectionProvider, inputQueueName, rebusLoggerFactory, asyncTaskFactory) { _leasedByFactory = leasedByFactory; _leaseIntervalMilliseconds = (long)Math.Ceiling(leaseInterval.TotalMilliseconds); _leaseToleranceMilliseconds = (long)Math.Ceiling((leaseTolerance ?? TimeSpan.FromSeconds(15)).TotalMilliseconds); if (automaticLeaseRenewalInterval.HasValue == false) { _automaticLeaseRenewal = false; } else { _automaticLeaseRenewal = true; _automaticLeaseRenewalIntervalMilliseconds = (long)Math.Ceiling(automaticLeaseRenewalInterval.Value.TotalMilliseconds); } }
/// <summary> /// Creates the data storage /// </summary> public SqlServerDataBusStorage(IDbConnectionProvider connectionProvider, string tableName, bool ensureTableIsCreated, IRebusLoggerFactory rebusLoggerFactory, IRebusTime rebusTime, int commandTimeout) { if (tableName == null) { throw new ArgumentNullException(nameof(tableName)); } if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } _connectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider)); _tableName = TableName.Parse(tableName); _ensureTableIsCreated = ensureTableIsCreated; _commandTimeout = commandTimeout; _rebusTime = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime)); _log = rebusLoggerFactory.GetLogger <SqlServerDataBusStorage>(); }
public AdvancedApiDecorator(IAdvancedApi innerAdvancedApi, IRebusLoggerFactory rebusLoggerFactory) { _innerAdvancedApi = innerAdvancedApi; _rebusLoggerFactory = rebusLoggerFactory; }
public OneWayClientBusDecorator(IBus innerBus, IRebusLoggerFactory rebusLoggerFactory) { _innerBus = innerBus; _advancedApiDecorator = new AdvancedApiDecorator(_innerBus.Advanced, rebusLoggerFactory); }
public OneWayClientWorkersApi(IRebusLoggerFactory rebusLoggerFactory) { _log = rebusLoggerFactory.GetLogger <OneWayClientWorkersApi>(); }
/// <summary> /// Constructs the timeout manager /// </summary> public MySqlTimeoutManager(MySqlConnectionHelper connectionHelper, string tableName, IRebusLoggerFactory rebusLoggerFactory, IRebusTime rebusTime) { if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } _connectionHelper = connectionHelper ?? throw new ArgumentNullException(nameof(connectionHelper)); _tableName = tableName ?? throw new ArgumentNullException(nameof(tableName)); _rebusTime = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime)); _log = rebusLoggerFactory.GetLogger <MySqlTimeoutManager>(); }
/// <summary> /// Creates the error handler /// </summary> public PoisonQueueErrorHandler(SimpleRetryStrategySettings simpleRetryStrategySettings, ITransport transport, IRebusLoggerFactory rebusLoggerFactory) { _log = rebusLoggerFactory?.GetLogger <PoisonQueueErrorHandler>() ?? throw new ArgumentNullException(nameof(rebusLoggerFactory)); _transport = transport ?? throw new ArgumentNullException(nameof(transport)); _simpleRetryStrategySettings = simpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(simpleRetryStrategySettings)); }
/// <summary> /// Constructs the transport with the given <see cref="IDbConnectionProvider"/> /// </summary> public MySqlTransport(IDbConnectionProvider connectionProvider, string inputQueueName, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, IRebusTime rebusTime, MySqlTransportOptions options) { if (rebusLoggerFactory == null) { throw new ArgumentNullException(nameof(rebusLoggerFactory)); } if (asyncTaskFactory == null) { throw new ArgumentNullException(nameof(asyncTaskFactory)); } _rebusTime = rebusTime ?? throw new ArgumentNullException(nameof(rebusTime)); _connectionProvider = connectionProvider ?? throw new ArgumentNullException(nameof(connectionProvider)); _receiveTableName = inputQueueName != null?TableName.Parse(inputQueueName) : null; _log = rebusLoggerFactory.GetLogger <MySqlTransport>(); var cleanupInterval = options.ExpiredMessagesCleanupInterval ?? DefaultExpiredMessagesCleanupInterval; var intervalSeconds = (int)cleanupInterval.TotalSeconds; _expiredMessagesCleanupTask = asyncTaskFactory.Create("ExpiredMessagesCleanup", PerformExpiredMessagesCleanupCycle, intervalSeconds: intervalSeconds); _autoDeleteQueue = options.AutoDeleteQueue; }