diff --git a/src/BuslyCLI.Console/Config/AmazonsqsTransportConfig.cs b/src/BuslyCLI.Console/Config/AmazonsqsTransportConfig.cs index 244a00c..c9c09dd 100644 --- a/src/BuslyCLI.Console/Config/AmazonsqsTransportConfig.cs +++ b/src/BuslyCLI.Console/Config/AmazonsqsTransportConfig.cs @@ -10,4 +10,12 @@ public class AmazonsqsTransportConfig : ITransportConfig public string AccessKey { get; set; } public string SecretKey { get; set; } + public AwsS3BucketSettings S3BucketSettings { get; set; } + +} + +public class AwsS3BucketSettings +{ + public string BucketName { get; set; } + public string KeyPrefix { get; set; } } \ No newline at end of file diff --git a/src/BuslyCLI.Console/Config/Validators/AmazonsqsTransportConfigValidator.cs b/src/BuslyCLI.Console/Config/Validators/AmazonsqsTransportConfigValidator.cs index 41d75b9..37e4b0a 100644 --- a/src/BuslyCLI.Console/Config/Validators/AmazonsqsTransportConfigValidator.cs +++ b/src/BuslyCLI.Console/Config/Validators/AmazonsqsTransportConfigValidator.cs @@ -15,5 +15,21 @@ public AmazonsqsTransportConfigValidator() || (!string.IsNullOrEmpty(x.AccessKey) && !string.IsNullOrEmpty(x.SecretKey)) // both set ) .WithMessage("AWS AccessKey and SecretKey are mutually dependent: if one is set, the other must also be set."); + + RuleFor(x => x.S3BucketSettings) + .SetValidator(new AwsS3BucketSettingsValidator()); + } +} + +public class AwsS3BucketSettingsValidator : AbstractValidator +{ + public AwsS3BucketSettingsValidator() + { + RuleFor(x => x.BucketName) + .NotEmpty(); + + RuleFor(x => x.KeyPrefix) + .NotEmpty(); + } } \ No newline at end of file diff --git a/src/BuslyCLI.Console/Factories/RawEndpointFactory.cs b/src/BuslyCLI.Console/Factories/RawEndpointFactory.cs index dce9d65..3ef3137 100644 --- a/src/BuslyCLI.Console/Factories/RawEndpointFactory.cs +++ b/src/BuslyCLI.Console/Factories/RawEndpointFactory.cs @@ -1,5 +1,6 @@ using Amazon; using Amazon.Runtime; +using Amazon.S3; using Amazon.SimpleNotificationService; using Amazon.SQS; using BuslyCLI.Config; @@ -77,6 +78,7 @@ private TransportDefinition CreateAmazonSQSTransport(AmazonsqsTransportConfig am var credentials = new BasicAWSCredentials(amazonsqsTransportConfig.AccessKey, amazonsqsTransportConfig.SecretKey); var amazonSqsConfig = new AmazonSQSConfig(); var amazonSnsConfig = new AmazonSimpleNotificationServiceConfig(); + var amazonS3Config = new AmazonS3Config(); if (!string.IsNullOrWhiteSpace(amazonsqsTransportConfig.RegionName)) { @@ -92,10 +94,21 @@ private TransportDefinition CreateAmazonSQSTransport(AmazonsqsTransportConfig am amazonSqsConfig.ServiceURL = amazonsqsTransportConfig.ServiceUrl; } - var sqsClient = new AmazonSQSClient(credentials, amazonSqsConfig); + if (amazonsqsTransportConfig.S3BucketSettings is not null) + { + amazonS3Config.ServiceURL = amazonsqsTransportConfig.ServiceUrl; + amazonS3Config.RegionEndpoint = RegionEndpoint.GetBySystemName(amazonsqsTransportConfig.RegionName); + } + var sqsClient = new AmazonSQSClient(credentials, amazonSqsConfig); var snsClient = new AmazonSimpleNotificationServiceClient(credentials, amazonSnsConfig); + var sqsTransport = new SqsTransport(sqsClient, snsClient); + if (amazonsqsTransportConfig.S3BucketSettings is not null) + { + sqsTransport.S3 = new S3Settings(amazonsqsTransportConfig.S3BucketSettings.BucketName, amazonsqsTransportConfig.S3BucketSettings.KeyPrefix, new AmazonS3Client(amazonS3Config)); + } + return new SqsTransport(sqsClient, snsClient); } diff --git a/tests/BuslyCLI.Console.Tests/Config/Validators/AwsS3BucketSettingsValidatorTests.cs b/tests/BuslyCLI.Console.Tests/Config/Validators/AwsS3BucketSettingsValidatorTests.cs new file mode 100644 index 0000000..401b2f1 --- /dev/null +++ b/tests/BuslyCLI.Console.Tests/Config/Validators/AwsS3BucketSettingsValidatorTests.cs @@ -0,0 +1,51 @@ +using BuslyCLI.Config; +using BuslyCLI.Config.Validators; +using FluentValidation.TestHelper; + +namespace BuslyCLI.Console.Tests.Config.Validators; + + +[TestFixture] +public class AwsS3BucketSettingsValidatorTests +{ + private readonly AwsS3BucketSettingsValidator _validator; + + public AwsS3BucketSettingsValidatorTests() + { + _validator = new AwsS3BucketSettingsValidator(); + } + + [Test] + public async Task ShouldErrorWhenBucketNameIsNotPassed() + { + // Arrange + var awsS3BucketSettings = new AwsS3BucketSettings() + { + BucketName = null + }; + + // Act + var result = await _validator.TestValidateAsync(awsS3BucketSettings); + + // Assert + result.ShouldHaveValidationErrorFor(c => c.BucketName) + .WithErrorMessage("'Bucket Name' must not be empty."); + } + + [Test] + public async Task ShouldErrorWhenKeyPrefixIsNotPassed() + { + // Arrange + var awsS3BucketSettings = new AwsS3BucketSettings() + { + KeyPrefix = null + }; + + // Act + var result = await _validator.TestValidateAsync(awsS3BucketSettings); + + // Assert + result.ShouldHaveValidationErrorFor(c => c.KeyPrefix) + .WithErrorMessage("'Key Prefix' must not be empty."); + } +} \ No newline at end of file diff --git a/website/docs/transports/amazon-sqs.md b/website/docs/transports/amazon-sqs.md index 8a4aa93..63c6f94 100644 --- a/website/docs/transports/amazon-sqs.md +++ b/website/docs/transports/amazon-sqs.md @@ -39,6 +39,15 @@ The Amazon SQS transport implementation currently works only with **AWS access k --- +## `s3-bucket-settings` Fields + +| Field | Required | Type | Default | Description | +| ------------- | -------- | ------ | ------- | ------------------------------------------------------------------------ | +| `bucket-name` | yes | string | — | Name of the S3 bucket for storing large messages. | +| `key-prefix` | yes | string | — | This is the path within the specified S3 bucket to store large messages. | + +--- + ## Field Details ### `region-name` (required) @@ -86,3 +95,17 @@ Examples: ```yaml service-url: http://127.0.0.1:32813/ ``` + +--- + +### `s3-bucket-settings` (optional) + +Used to configure S3 bucket storage for large messages. + +Examples: + +```yaml +s3-bucket-settings: + bucket-name: nsb-sqs-messages + key-prefix: my/sample/path +```