public void PostConfigure(string name, AzureQueueStorageTransportOptions options) { // Ensure the connection string if (string.IsNullOrWhiteSpace(options.ConnectionString)) { throw new InvalidOperationException($"The '{nameof(options.ConnectionString)}' must be provided"); } // Ensure there's only one consumer per event var registrations = busOptions.GetRegistrations(TransportNames.AzureQueueStorage); var multiple = registrations.FirstOrDefault(r => r.Consumers.Count > 1); if (multiple != null) { throw new InvalidOperationException($"More than one consumer registered for '{multiple.EventType.Name}' yet " + "Azure Queue Storage does not support more than one consumer per event in the same application domain."); } // Ensure the entity names are not longer than the limits // See https://docs.microsoft.com/en-us/rest/api/storageservices/naming-queues-and-metadata#queue-names foreach (var ereg in registrations) { // Event names become topic names and they should not be longer than 63 characters if (ereg.EventName.Length > 63) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "Azure Queue Storage does not allow more than 63 characters for Queue names."); } } }
public void PostConfigure(string name, KafkaTransportOptions options) { if (options.BootstrapServers == null && options.AdminConfig == null) { throw new InvalidOperationException($"Either '{nameof(options.BootstrapServers)}' or '{nameof(options.AdminConfig)}' must be provided"); } if (options.BootstrapServers != null && options.BootstrapServers.Any(b => string.IsNullOrWhiteSpace(b))) { throw new ArgumentNullException(nameof(options.BootstrapServers), "A bootstrap server cannot be null or empty"); } // ensure we have a config options.AdminConfig ??= new AdminClientConfig { BootstrapServers = string.Join(",", options.BootstrapServers) }; if (string.IsNullOrWhiteSpace(options.AdminConfig.BootstrapServers)) { throw new InvalidOperationException($"BootstrapServers must be provided via '{nameof(options.BootstrapServers)}' or '{nameof(options.AdminConfig)}'."); } // ensure the checkpoint interval is not less than 1 options.CheckpointInterval = Math.Max(options.CheckpointInterval, 1); // ensure there's only one consumer per event var registrations = busOptions.GetRegistrations(TransportNames.Kafka); var multiple = registrations.FirstOrDefault(r => r.Consumers.Count > 1); if (multiple != null) { throw new InvalidOperationException($"More than one consumer registered for '{multiple.EventType.Name}' yet " + "Kafka does not support more than one consumer per event in the same application domain."); } // Ensure the entity names are not longer than the limits // See https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-quotas#common-limits-for-all-tiers foreach (var ereg in registrations) { // Event names become Topic names and they should not be longer than 255 characters // https://www.ibm.com/support/knowledgecenter/SSMKHH_10.0.0/com.ibm.etools.mft.doc/bz91041_.html if (ereg.EventName.Length > 255) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "Kafka does not allow more than 255 characters for Topic names."); } // Consumer names become Consumer Group IDs and they should not be longer than 255 characters foreach (var creg in ereg.Consumers) { if (creg.ConsumerName.Length > 255) { throw new InvalidOperationException($"ConsumerName '{creg.ConsumerName}' generated from '{creg.ConsumerType.Name}' is too long. " + "Kafka does not allow more than 255 characters for Consumer Group IDs."); } } } }
public void PostConfigure(string name, AmazonKinesisTransportOptions options) { // Ensure the region is provided if (string.IsNullOrWhiteSpace(options.RegionName) && options.Region == null) { throw new InvalidOperationException($"Either '{nameof(options.RegionName)}' or '{nameof(options.Region)}' must be provided"); } options.Region ??= RegionEndpoint.GetBySystemName(options.RegionName); // Ensure the access key is specified if (string.IsNullOrWhiteSpace(options.AccessKey)) { throw new InvalidOperationException($"The '{nameof(options.AccessKey)}' must be provided"); } // Ensure the secret is specified if (string.IsNullOrWhiteSpace(options.SecretKey)) { throw new InvalidOperationException($"The '{nameof(options.SecretKey)}' must be provided"); } // Ensure we have options for Kinesis and the region is set options.KinesisConfig ??= new AmazonKinesisConfig(); options.KinesisConfig.RegionEndpoint ??= options.Region; // Ensure the partition key resolver is set if (options.PartitionKeyResolver == null) { throw new InvalidOperationException($"The '{nameof(options.PartitionKeyResolver)}' must be provided"); } // Ensure the entity names are not longer than the limits var registrations = busOptions.GetRegistrations(TransportNames.AmazonKinesis); foreach (var ereg in registrations) { // Event names become Stream names and they should not be longer than 128 characters // See https://docs.aws.amazon.com/kinesis/latest/APIReference/API_CreateStream.html if (ereg.EventName.Length > 128) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "Amazon Kinesis does not allow more than 128 characters for Stream names."); } // Consumer names become Queue names and they should not be longer than 128 characters // See https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RegisterStreamConsumer.html foreach (var creg in ereg.Consumers) { if (creg.ConsumerName.Length > 128) { throw new InvalidOperationException($"ConsumerName '{creg.ConsumerName}' generated from '{creg.ConsumerType.Name}' is too long. " + "Amazon Kinesis does not allow more than 128 characters for Stream Consumer names."); } } } }
public void PostConfigure(string name, AmazonSqsTransportOptions options) { // Ensure the region is provided if (string.IsNullOrWhiteSpace(options.RegionName) && options.Region == null) { throw new InvalidOperationException($"Either '{nameof(options.RegionName)}' or '{nameof(options.Region)}' must be provided"); } options.Region ??= RegionEndpoint.GetBySystemName(options.RegionName); // Ensure the access key is specified if (string.IsNullOrWhiteSpace(options.AccessKey)) { throw new InvalidOperationException($"The '{nameof(options.AccessKey)}' must be provided"); } // Ensure the secret is specified if (string.IsNullOrWhiteSpace(options.SecretKey)) { throw new InvalidOperationException($"The '{nameof(options.SecretKey)}' must be provided"); } // Ensure we have options for SQS and SNS and their regions are set options.SqsConfig ??= new AmazonSQSConfig(); options.SqsConfig.RegionEndpoint ??= options.Region; options.SnsConfig ??= new AmazonSimpleNotificationServiceConfig(); options.SnsConfig.RegionEndpoint ??= options.Region; // Ensure the entity names are not longer than the limits var registrations = busOptions.GetRegistrations(TransportNames.AmazonSqs); foreach (var ereg in registrations) { // Event names become Topic names and they should not be longer than 256 characters // See https://aws.amazon.com/sns/faqs/#:~:text=Features%20and%20functionality,and%20underscores%20(_)%20are%20allowed. if (ereg.EventName.Length > 256) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "Amazon SNS does not allow more than 256 characters for Topic names."); } // Consumer names become Queue names and they should not be longer than 80 characters // See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-queues.html foreach (var creg in ereg.Consumers) { if (creg.ConsumerName.Length > 80) { throw new InvalidOperationException($"ConsumerName '{creg.ConsumerName}' generated from '{creg.ConsumerType.Name}' is too long. " + "Amazon SQS does not allow more than 80 characters for Queue names."); } } } }
public void PostConfigure(string name, AzureEventHubsTransportOptions options) { // Ensure the connection string if (string.IsNullOrWhiteSpace(options.ConnectionString)) { throw new InvalidOperationException($"The '{nameof(options.ConnectionString)}' must be provided"); } // If there are consumers for this transport, we must check azure blob storage var registrations = busOptions.GetRegistrations(TransportNames.AzureEventHubs); if (registrations.Any(r => r.Consumers.Count > 0)) { // ensure the connection string for blob storage is valid if (string.IsNullOrWhiteSpace(options.BlobStorageConnectionString)) { throw new InvalidOperationException($"The '{nameof(options.BlobStorageConnectionString)}' must be provided"); } // ensure the blob container name is provided if (string.IsNullOrWhiteSpace(options.BlobContainerName)) { throw new InvalidOperationException($"The '{nameof(options.BlobContainerName)}' must be provided"); } // ensure the prefix is always lower case. options.BlobContainerName = options.BlobContainerName.ToLower(); } // Ensure the entity names are not longer than the limits // See https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-quotas#common-limits-for-all-tiers foreach (var ereg in registrations) { // Event names become Event Hub names and they should not be longer than 256 characters if (ereg.EventName.Length > 256) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "Azure Event Hubs does not allow more than 256 characters for Event Hub names."); } // Consumer names become Consumer Group names and they should not be longer than 256 characters foreach (var creg in ereg.Consumers) { if (creg.ConsumerName.Length > 256) { throw new InvalidOperationException($"ConsumerName '{creg.ConsumerName}' generated from '{creg.ConsumerType.Name}' is too long. " + "Azure Event Hubs does not allow more than 256 characters for Consumer Group names."); } } } }
public void PostConfigure(string name, AzureServiceBusTransportOptions options) { // Ensure the connection string is not null if (string.IsNullOrWhiteSpace(options.ConnectionString)) { throw new InvalidOperationException($"The '{nameof(options.ConnectionString)}' must be provided"); } // Ensure the entity names are not longer than the limits // See https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-quotas#messaging-quotas var registrations = busOptions.GetRegistrations(TransportNames.AzureServiceBus); foreach (var ereg in registrations) { // Event names become Topic and Queue names and they should not be longer than 260 characters if (ereg.EventName.Length > 260) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "Azure Service Bus does not allow more than 260 characters for Topic and Queue names."); } // Consumer names become Subscription names and they should not be longer than 50 characters // When not using basic tier or when mapped to Queue, ConsumerName -> SubscriptionName does not happen if (!options.UseBasicTier && !ereg.UseQueueInsteadOfTopic()) { foreach (var creg in ereg.Consumers) { if (creg.ConsumerName.Length > 50) { throw new InvalidOperationException($"ConsumerName '{creg.ConsumerName}' generated from '{creg.ConsumerType.Name}' is too long. " + "Azure Service Bus does not allow more than 50 characters for Subscription names."); } } } } }
public void PostConfigure(string name, RabbitMqTransportOptions options) { // If there are consumers for this transport, confirm the right Bus options var registrations = busOptions.GetRegistrations(TransportNames.RabbitMq); if (registrations.Any(r => r.Consumers.Count > 0)) { // we need full type names if (!busOptions.Naming.UseFullTypeNames) { throw new NotSupportedException($"When using RabbitMQ transport '{nameof(busOptions.Naming.UseFullTypeNames)}' must be 'true'"); } // consumer names must be suffixed if (!busOptions.Naming.SuffixConsumerName) { throw new NotSupportedException($"When using RabbitMQ transport '{nameof(busOptions.Naming.SuffixConsumerName)}' must be 'true'"); } } // if we do not have a connection factory, attempt to create one if (options.ConnectionFactory == null) { // ensure we have a hostname if (string.IsNullOrWhiteSpace(options.Hostname)) { throw new ArgumentNullException(nameof(options.Hostname), "The hostname is required to connect to a RabbitMQ broker"); } // ensure we have a username and password options.Username ??= "guest"; options.Password ??= "guest"; options.ConnectionFactory = new ConnectionFactory { HostName = options.Hostname, UserName = options.Username, Password = options.Password, }; } // at this point we have a connection factory, ensure certain settings are what we need them to be options.ConnectionFactory.DispatchConsumersAsync = true; // ensure the retries are not less than zero options.RetryCount = Math.Max(options.RetryCount, 0); // Ensure the entity names are not longer than the limits // See https://www.rabbitmq.com/queues.html#:~:text=Names,bytes%20of%20UTF%2D8%20characters. foreach (var ereg in registrations) { // Event names become Exchange names and they should not be longer than 255 characters if (ereg.EventName.Length > 255) { throw new InvalidOperationException($"EventName '{ereg.EventName}' generated from '{ereg.EventType.Name}' is too long. " + "RabbitMQ does not allow more than 255 characters for Exchange names."); } // Consumer names become Queue names and they should not be longer than 255 characters foreach (var creg in ereg.Consumers) { if (creg.ConsumerName.Length > 255) { throw new InvalidOperationException($"ConsumerName '{creg.ConsumerName}' generated from '{creg.ConsumerType.Name}' is too long. " + "RabbitMQ does not allow more than 255 characters for Queue names."); } } } }