SQS.Extensions 5.6.0

dotnet add package SQS.Extensions --version 5.6.0
NuGet\Install-Package SQS.Extensions -Version 5.6.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SQS.Extensions" Version="5.6.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SQS.Extensions --version 5.6.0
#r "nuget: SQS.Extensions, 5.6.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SQS.Extensions as a Cake Addin
#addin nuget:?package=SQS.Extensions&version=5.6.0

// Install SQS.Extensions as a Cake Tool
#tool nuget:?package=SQS.Extensions&version=5.6.0

SQS.Extensions

Nuget GitHub

SQS.Extensions is a .NET library with the idea to helps developer using AWS Sqs.

Behind the scenes it covers a set of repetitive tasks, handle complexity and highly customizable.

Quickstart

Installation

Add the NuGet Package to your project:

dotnet add package SQS.Extensions

Configuration

Configuration is pretty simple if you don't want any particular customization.

// This is needed by AWS library
builder.Services.AddDefaultAWSOptions(new AWSOptions { Region = RegionEndpoint.EUCentral1 });
builder.Services.AddAWSService<IAmazonSQS>();

// Dependency Injection
// Configuration
builder.Services.AddSqsConsumerServices(
    () => new AwsConfiguration(region: "eu-central-1", accountId: "775704350706")
{
    QueuePrefix = "develop-"
});

// Consumer registrations
// this is needed only in you have to dequeue from SQS
// in case of send only is not needed
builder.Services.AddSqsConsumer<MySqsConsumer>();

Sending message to queue

app.MapPost("/SendMessageToQueue", async (
    MySqsMessage request,
    ISqsDispatcher sqsDispatcher,
    CancellationToken cancellationToken) =>
{
    // Do your stuff
    await sqsDispatcher.QueueAsync(request, Constants.QUEUE_NAME_1, cancellationToken);

    return Results.NoContent();
});

Pooling message from queue

The library allows you to receive messages using a background task. Everytime a new message came into the queue, you function will be invocated.

You could register multiple consumers with different queues

internal sealed class MySqsConsumer : SqsHostedService<MySqsMessage>
{
    public MySqsConsumer(
        ILogger<MySqsConsumer> logger,
        ISqsMessagePumpFactory messagePumpFactory)
            : base(logger, messagePumpFactory)
    {
    }

    protected override Func<MySqsMessage?, CancellationToken, Task> ProcessMessageFunc => ConsumeMessageAsync;

    protected override MessagePumpConfiguration MessagePumpConfiguration =>
        new (Constants.QUEUE_NAME_1)
        {
            // waiting time between calls to SQS.
            BatchDelay = TimeSpan.FromSeconds(10),

            // the max number of concurrent operations
            MaxConcurrentOperation = 10,

            // if true every time the app start cleans the queue
            // helpful for testing
            PurgeOnStartup = true
        };

    private Task ConsumeMessageAsync(MySqsMessage? message, CancellationToken cancellationToken)
    {
        // Do your staff here

        return Task.CompletedTask;
    }
}

Customization

Serialization

The library allows you to choice your favorite serialization library. If you don't specify anything, the recente System.Text.Json will be used. If you prefer to use something different you can create your own serializer in this way

public sealed class MySuperSerializer : IMessageSerializer
{
    public string Serialize<T>(T itemToSerialized)
    {
    }

    public T? Deserialize<T>(string serializedObject)
    {
        
    }
}

Then register it on DI

builder.Services.AddSqsConsumerWithCustomSerializer<MySuperSerializer>(() => new AwsConfiguration(region: "eu-central-1", accountId: "775704350706")
{
    QueuePrefix = "develop-"
});
Queue name customization

Out of the box the library offers you the opportunity to add automatically a prefix and/or suffix to the queue name. Sometimes this could be helpful for temporary queue or for different environment like development and production (would be better to use different account for security reason)

When you add the library to your DI you can specify these parameters

// Dependency Injection
builder.Services.AddSqsConsumerServices(
    () => new AwsConfiguration()
{
    QueuePrefix = "develop-",
    QueueSuffix = "-temp"
});

If you don't like this way or you have a super strange queue name algorithm you can add your custom logic in this way:

/// <inheritdoc />
public sealed class MySuperSqsQueueHelper : DefaultSqsQueueHelper
{
    /// <inheritdoc />
    public MySuperSqsQueueHelper(AwsConfiguration awsConfiguration, IAmazonSQS sqsClient)
        : base(awsConfiguration, sqsClient)
    {
    }

    public override ValueTask<string> GetQueueUrlAsync(string queueName)
    {
        // Add your logic here.
    }
}

Then register it on DI

builder.Services.AddSqsConsumerWithCustomQueueHeper<MySqsQueueHelper>(
    () => new AwsConfiguration();

Telemetry

The library is ready for OpenTelemetry metrics, the only thing you have to do is to register it in this way:

var meterProviderProvider = Sdk.CreateMeterProviderBuilder()
    .AddMeter("SQS.Extensions")
    // ... Add other meters
    // ... Add exporters
    .Build();

    //......

Monitoring SQS.Extensions with Prometheus and Grafana

Prometheus is a monitoring solution for storing time series data like metrics. Grafana visualizes the data stored in Prometheus (and other sources). This sample demonstrates how to capture OpenTelemetry metrics, store them in Prometheus and visualize these metrics using a Grafana dashboard.

Prerequisites

To run this sample, Prometheus and Grafana are required. If you are not familiar on how to install it here you can find a starting point.

Now some Nuget packages are required:

<ItemGroup>
    <PackageReference Include="OpenTelemetry.Api" Version="1.5.1" />
    <PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.5.0-rc.1" />
</ItemGroup>
// Open Telemetry
services
    .AddOpenTelemetry()
    .WithMetrics(
        b =>
        {
            // receive metrics from our own custom sources
            b.AddMeter(serviceName);

            // decorate our service name so we can find it when we look inside Prometheus
            b.SetResourceBuilder(resource);

            b.AddPrometheusExporter();
            
            b.AddMeter("SQS.Extensions");
    );

Last step is to register the metric endpoint to ASP.NET Routing

app.UseOpenTelemetryPrometheusScrapingEndpoint(ctx => ctx.Request.Path == "/metrics" && ctx.Connection.LocalPort == 4999);

A good practice is to expose the metrics on a different port of your application that will not be reachable by internet, in this example I've used the 4999

Now if you call /metrics endpoint you should see lot of information that will include the SQS.Extensions metrics (only in case you application did something from SQS)

The exposed metrics are:

  • sqs_extensions_messaging_successes
  • sqs_extensions_messaging_fetches
  • sqs_extensions_messaging_failures
  • sqs_extensions_messaging_expired
  • sqs_extensions_messaging_deleted

Importing Grafana Dashboard

Grafana

To graph the metrics, the following steps must be performed:

  • Add a new dashboard
  • Import
  • Paste json from here

That's it!

Sample

Take a look here

License

SQS.Extensions MIT licensed.

Contributing

Thanks to all the people who already contributed!

<a href="https://github.com/imperugo/SQS.Extensions/graphs/contributors"> <img src="https://contributors-img.web.app/image?repo=imperugo/SQS.Extensions" /> </a>

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
5.6.0 151 4/2/2024
5.5.2 74 4/2/2024
5.5.1 398 3/26/2024
5.5.0 99 3/14/2024
5.4.2 1,071 12/13/2023
5.4.1 248 12/3/2023
5.4.0 140 12/3/2023
5.3.1 497 10/12/2023
5.3.0 273 9/18/2023
5.2.0 202 9/12/2023
5.1.4 128 9/9/2023
5.0.4 121 9/9/2023
5.0.3 127 9/9/2023
5.0.2 126 9/9/2023
5.0.1 127 9/9/2023
5.0.0 129 9/8/2023
4.0.3 190 9/6/2023
4.0.2 192 9/4/2023
4.0.1 134 9/3/2023
4.0.0 128 9/3/2023
3.2.1 151 9/1/2023
3.2.0 123 9/1/2023
3.1.1 136 8/31/2023
3.1.0 168 8/30/2023
3.0.0 160 8/29/2023
2.4.2 187 8/25/2023
2.4.0 134 8/19/2023
2.3.1 201 8/18/2023
2.3.0 143 8/18/2023
2.2.1 141 8/16/2023
2.2.0 184 8/14/2023
2.1.1 172 8/12/2023
2.1.0 127 8/12/2023
2.0.9 180 8/7/2023
2.0.8 148 8/7/2023
2.0.7 173 8/6/2023
2.0.6 152 8/6/2023
2.0.5 164 8/6/2023
2.0.4 152 8/4/2023
2.0.3 165 8/2/2023
2.0.2 133 8/2/2023
2.0.1 131 8/2/2023
2.0.0 138 8/2/2023
1.0.4 155 7/31/2023
1.0.3 155 7/31/2023
1.0.2 138 7/31/2023
1.0.1 254 11/17/2022
1.0.0 182 11/17/2022