public async Task Init(Func <MessageContext, Task> onMessage, Func <ErrorContext, Task <ErrorHandleResult> > onError, CriticalError criticalError, PushSettings settings) { _queueUrl = SqsQueueUrlCache.GetQueueUrl(SqsQueueNameHelper.GetSqsQueueName(settings.InputQueue, ConnectionConfiguration)); if (settings.PurgeOnStartup) { // SQS only allows purging a queue once every 60 seconds or so. // If you try to purge a queue twice in relatively quick succession, // PurgeQueueInProgressException will be thrown. // This will happen if you are trying to start an endpoint twice or more // in that time. try { await SqsClient.PurgeQueueAsync(_queueUrl).ConfigureAwait(false); } catch (PurgeQueueInProgressException ex) { Logger.Warn("Multiple queue purges within 60 seconds are not permitted by SQS.", ex); } catch (Exception ex) { Logger.Error("Exception thrown from PurgeQueue.", ex); throw; } } _onMessage = onMessage; _onError = onError; }
private async Task SendMessage(string message, string destination, List <DeliveryConstraint> constraints) { var delayWithConstraint = constraints.OfType <DelayDeliveryWith>().SingleOrDefault(); var deliverAtConstraint = constraints.OfType <DoNotDeliverBefore>().SingleOrDefault(); var delayDeliveryBy = TimeSpan.MaxValue; if (delayWithConstraint != null) { delayDeliveryBy = delayWithConstraint.Delay; } else { if (deliverAtConstraint != null) { delayDeliveryBy = deliverAtConstraint.At - DateTime.UtcNow; } } var sendMessageRequest = new SendMessageRequest( SqsQueueUrlCache.GetQueueUrl( SqsQueueNameHelper.GetSqsQueueName(destination, ConnectionConfiguration)), message); // There should be no need to check if the delay time is greater than the maximum allowed // by SQS (15 minutes); the call to AWS will fail with an appropriate exception if the limit is exceeded. if (delayDeliveryBy != TimeSpan.MaxValue) { sendMessageRequest.DelaySeconds = Math.Max(0, (int)delayDeliveryBy.TotalSeconds); } await SqsClient.SendMessageAsync(sendMessageRequest).ConfigureAwait(false); }
public async Task CreateQueueIfNecessary(string address) { try { var queueName = SqsQueueNameHelper.GetSqsQueueName(address, ConnectionConfiguration); var sqsRequest = new CreateQueueRequest { QueueName = queueName, }; Logger.Info($"Creating SQS Queue with name \"{sqsRequest.QueueName}\" for address \"{address}\"."); var createQueueResponse = await SqsClient.CreateQueueAsync(sqsRequest).ConfigureAwait(false); QueueUrlCache.SetQueueUrl(queueName, createQueueResponse.QueueUrl); // Set the queue attributes in a separate call. // If you call CreateQueue with a queue name that already exists, and with a different // value for MessageRetentionPeriod, the service throws. This will happen if you // change the MaxTTLDays configuration property. var sqsAttributesRequest = new SetQueueAttributesRequest { QueueUrl = createQueueResponse.QueueUrl }; sqsAttributesRequest.Attributes.Add(QueueAttributeName.MessageRetentionPeriod, ((int)(TimeSpan.FromDays(ConnectionConfiguration.MaxTTLDays).TotalSeconds)).ToString()); await SqsClient.SetQueueAttributesAsync(sqsAttributesRequest).ConfigureAwait(false); if (!string.IsNullOrEmpty(ConnectionConfiguration.S3BucketForLargeMessages)) { // determine if the configured bucket exists; create it if it doesn't var listBucketsResponse = await S3Client.ListBucketsAsync(new ListBucketsRequest()).ConfigureAwait(false); var bucketExists = listBucketsResponse.Buckets.Any(x => string.Equals(x.BucketName, ConnectionConfiguration.S3BucketForLargeMessages, StringComparison.InvariantCultureIgnoreCase)); if (!bucketExists) { await S3Client.RetryConflictsAsync(async() => await S3Client.PutBucketAsync(new PutBucketRequest { BucketName = ConnectionConfiguration.S3BucketForLargeMessages }).ConfigureAwait(false), onRetry : x => { Logger.Warn($"Conflict when creating S3 bucket, retrying after {x}ms."); }).ConfigureAwait(false); } var lifecycleConfig = await S3Client.GetLifecycleConfigurationAsync(ConnectionConfiguration.S3BucketForLargeMessages).ConfigureAwait(false); bool setLifecycleConfig = lifecycleConfig.Configuration.Rules.All(x => x.Id != "NServiceBus.SQS.DeleteMessageBodies"); if (setLifecycleConfig) { await S3Client.RetryConflictsAsync(async() => await S3Client.PutLifecycleConfigurationAsync(new PutLifecycleConfigurationRequest { BucketName = ConnectionConfiguration.S3BucketForLargeMessages, Configuration = new LifecycleConfiguration { Rules = new List <LifecycleRule> { new LifecycleRule { Id = "NServiceBus.SQS.DeleteMessageBodies", Filter = new LifecycleFilter { LifecycleFilterPredicate = new LifecyclePrefixPredicate { Prefix = ConnectionConfiguration.S3KeyPrefix } }, Status = LifecycleRuleStatus.Enabled, Expiration = new LifecycleRuleExpiration { Days = ConnectionConfiguration.MaxTTLDays } } } } }).ConfigureAwait(false), onRetry : x => { Logger.Warn($"Conflict when setting S3 lifecycle configuration, retrying after {x}ms."); }).ConfigureAwait(false); } } } catch (Exception e) { Logger.Error("Exception from CreateQueueIfNecessary.", e); throw; } }