Skip to content

Commit

Permalink
Invoke consumer-defined action when exceptions raised during consumpt…
Browse files Browse the repository at this point in the history
…ion Redis streams (#1618)

* #1611
Enhanced logging and error handling in RedisConsumer
Added new unit tests for various functionalities and configurations.
Improved code formatting and consistency across the project.

* update summary

* OnConsumeError Updates

update CapRedisOptions with OnConsumeError option
  • Loading branch information
MahmoudSamir101 authored Dec 2, 2024
1 parent c29e8d6 commit 40a56d2
Show file tree
Hide file tree
Showing 31 changed files with 664 additions and 265 deletions.
6 changes: 6 additions & 0 deletions CAP.sln
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Dashboard.Jwt", "sam
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetCore.CAP.Dashboard.K8s", "src\DotNetCore.CAP.Dashboard.K8s\DotNetCore.CAP.Dashboard.K8s.csproj", "{48655118-CEC3-4BD9-B510-64C1195C2729}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetCore.CAP.RedisStreams.Test", "test\DotNetCore.CAP.RedisStreams.Test\DotNetCore.CAP.RedisStreams.Test.csproj", "{789E851F-37B4-49D6-B405-7EC9AA1D2CF8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -225,6 +227,9 @@ Global
{48655118-CEC3-4BD9-B510-64C1195C2729}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48655118-CEC3-4BD9-B510-64C1195C2729}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48655118-CEC3-4BD9-B510-64C1195C2729}.Release|Any CPU.Build.0 = Release|Any CPU
{789E851F-37B4-49D6-B405-7EC9AA1D2CF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{789E851F-37B4-49D6-B405-7EC9AA1D2CF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{789E851F-37B4-49D6-B405-7EC9AA1D2CF8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -262,6 +267,7 @@ Global
{D9681967-DAC2-43EF-999F-3727F1046711} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
{F739A8C9-565F-4B1D-8F91-FEE056C03FBD} = {3A6B6931-A123-477A-9469-8B468B5385AF}
{48655118-CEC3-4BD9-B510-64C1195C2729} = {9B2AE124-6636-4DE9-83A3-70360DABD0C4}
{789E851F-37B4-49D6-B405-7EC9AA1D2CF8} = {C09CDAB0-6DD4-46E9-B7F3-3EF2A4741EA0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2E70565D-94CF-40B4-BFE1-AC18D5F736AB}
Expand Down
2 changes: 1 addition & 1 deletion docs/content/user-guide/en/transport/redis-streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ NAME | DESCRIPTION | TYPE | DEFAULT
Configuration | redis connection configuration (StackExchange.Redis) | ConfigurationOptions | ConfigurationOptions
StreamEntriesCount | number of entries returned from a stream while reading | uint | 10
ConnectionPoolSize | number of connections pool | uint | 10

OnConsumeError | callback function that will be invoked when an error occurred during message consumption. | Func<ConsumeErrorContext, Task> | null
#### Redis Configuration Options

If you need **more** native Redis related configuration options, you can set them in the `Configuration` option:
Expand Down
75 changes: 36 additions & 39 deletions samples/Samples.Redis.SqlServer/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
@@ -1,54 +1,51 @@
using DotNetCore.CAP;
using DotNetCore.CAP.Messages;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;

namespace Samples.Redis.SqlServer.Controllers
namespace Samples.Redis.SqlServer.Controllers;

[ApiController]
[Route("[controller]/[action]")]
public class HomeController : ControllerBase
{
[ApiController]
[Route("[controller]/[action]")]
public class HomeController : ControllerBase
private readonly ILogger<HomeController> _logger;
private readonly ICapPublisher _publisher;
private readonly IOptions<CapOptions> _options;

public HomeController(ILogger<HomeController> logger, ICapPublisher publisher, IOptions<CapOptions> options)
{
private readonly ILogger<HomeController> _logger;
private readonly ICapPublisher _publisher;
private readonly IOptions<CapOptions> _options;

public HomeController(ILogger<HomeController> logger, ICapPublisher publisher, IOptions<CapOptions> options)
{
_logger = logger;
_publisher = publisher;
this._options = options;
}

[HttpGet]
public async Task Publish([FromQuery] string message = "test-message")
{
await _publisher.PublishAsync(message, new Person() { Age = 11, Name = "James" });
}

[CapSubscribe("test-message")]
[CapSubscribe("test-message-1")]
[CapSubscribe("test-message-2")]
[CapSubscribe("test-message-3")]
[NonAction]
public void Subscribe(Person p, [FromCap] CapHeader header)
{
_logger.LogInformation($"{header[Headers.MessageName]} subscribed with value --> " + p);
}
_logger = logger;
_publisher = publisher;
this._options = options;
}

[HttpGet]
public async Task Publish([FromQuery] string message = "test-message")
{
await _publisher.PublishAsync(message, new Person() { Age = 11, Name = "James" });
}

public class Person
[CapSubscribe("test-message")]
[CapSubscribe("test-message-1")]
[CapSubscribe("test-message-2")]
[CapSubscribe("test-message-3")]
[NonAction]
public void Subscribe(Person p, [FromCap] CapHeader header)
{
public string Name { get; set; }
_logger.LogInformation($"{header[Headers.MessageName]} subscribed with value --> " + p);
}

public int Age { get; set; }
}

public class Person
{
public string Name { get; set; }

public override string ToString()
{
return "Name:" + Name + ", Age:" + Age;
}
public int Age { get; set; }

public override string ToString()
{
return "Name:" + Name + ", Age:" + Age;
}
}
21 changes: 14 additions & 7 deletions samples/Samples.Redis.SqlServer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["src/Directory.Build.props", "src/"]
COPY ["samples/Samples.Redis.SqlServer/Samples.Redis.SqlServer.csproj", "samples/Samples.Redis.SqlServer/"]
COPY ["src/DotNetCore.CAP.RedisStreams/DotNetCore.CAP.RedisStreams.csproj", "src/DotNetCore.CAP.RedisStreams/"]
COPY ["src/DotNetCore.CAP/DotNetCore.CAP.csproj", "src/DotNetCore.CAP/"]
COPY ["src/DotNetCore.CAP.SqlServer/DotNetCore.CAP.SqlServer.csproj", "src/DotNetCore.CAP.SqlServer/"]
RUN dotnet restore "samples/Samples.Redis.SqlServer/Samples.Redis.SqlServer.csproj"
RUN dotnet restore "./samples/Samples.Redis.SqlServer/Samples.Redis.SqlServer.csproj"
COPY . .
WORKDIR "/src/samples/Samples.Redis.SqlServer"
RUN dotnet build "Samples.Redis.SqlServer.csproj" -c Release -o /app/build
RUN dotnet build "./Samples.Redis.SqlServer.csproj" -c $BUILD_CONFIGURATION -o /app/build

# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
RUN dotnet publish "Samples.Redis.SqlServer.csproj" -c Release -o /app/publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Samples.Redis.SqlServer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
Expand Down
58 changes: 42 additions & 16 deletions samples/Samples.Redis.SqlServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,46 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace Samples.Redis.SqlServer
{
public class Program
using StackExchange.Redis;

var builder = WebApplication.CreateBuilder(args);

builder.Services
.AddControllers();

builder.Services
.AddEndpointsApiExplorer();
builder.Services
.AddSwaggerGen();

builder.Services
.AddCap(options =>
{
public static void Main(string[] args)
options.UseRedis(redis =>
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
redis.Configuration = ConfigurationOptions.Parse("redis-node-0:6379,password=cap");
redis.OnConsumeError = context =>
{
throw new InvalidOperationException("");
};
});

options.UseSqlServer("Server=db;Database=master;User=sa;Password=P@ssw0rd;Encrypt=False");

options.UseDashboard();

});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
33 changes: 18 additions & 15 deletions samples/Samples.Redis.SqlServer/Samples.Redis.SqlServer.csproj
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>eb622624-fbc4-46d0-b006-dfe8e66df5bb</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<DockerComposeProjectPath>..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.RedisStreams\DotNetCore.CAP.RedisStreams.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.SqlServer\DotNetCore.CAP.SqlServer.csproj" />
</ItemGroup>

</Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<UserSecretsId>eb622624-fbc4-46d0-b006-dfe8e66df5bb</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<ImplicitUsings>enable</ImplicitUsings>
<DockerfileContext>..\..</DockerfileContext>
<DockerComposeProjectPath>..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\DotNetCore.CAP.Dashboard\DotNetCore.CAP.Dashboard.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.RedisStreams\DotNetCore.CAP.RedisStreams.csproj" />
<ProjectReference Include="..\..\src\DotNetCore.CAP.SqlServer\DotNetCore.CAP.SqlServer.csproj" />
</ItemGroup>
</Project>
37 changes: 0 additions & 37 deletions samples/Samples.Redis.SqlServer/Startup.cs

This file was deleted.

2 changes: 1 addition & 1 deletion samples/Samples.Redis.SqlServer/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*"
}
24 changes: 14 additions & 10 deletions samples/Samples.Redis.SqlServer/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
version: '2'
services:
redis-node-0:
image: docker.io/bitnami/redis-cluster:6.2
image: docker.io/bitnami/redis-cluster:7.0
volumes:
- redis-cluster_data-0:/bitnami/redis/data
environment:
- 'REDIS_PASSWORD=cap'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'

redis-node-1:
image: docker.io/bitnami/redis-cluster:6.2
image: docker.io/bitnami/redis-cluster:7.0
volumes:
- redis-cluster_data-1:/bitnami/redis/data
environment:
- 'REDIS_PASSWORD=cap'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'

redis-node-2:
image: docker.io/bitnami/redis-cluster:6.2
image: docker.io/bitnami/redis-cluster:7.0
volumes:
- redis-cluster_data-2:/bitnami/redis/data
environment:
- 'REDIS_PASSWORD=cap'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'

redis-node-3:
image: docker.io/bitnami/redis-cluster:6.2
image: docker.io/bitnami/redis-cluster:7.0
volumes:
- redis-cluster_data-3:/bitnami/redis/data
environment:
- 'REDIS_PASSWORD=cap'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'

redis-node-4:
image: docker.io/bitnami/redis-cluster:6.2
image: docker.io/bitnami/redis-cluster:7.0
volumes:
- redis-cluster_data-4:/bitnami/redis/data
environment:
- 'REDIS_PASSWORD=cap'
- 'REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5'

redis-node-5:
image: docker.io/bitnami/redis-cluster:6.2
image: docker.io/bitnami/redis-cluster:7.0
ports:
- 6379:6379
volumes:
- redis-cluster_data-5:/bitnami/redis/data
depends_on:
Expand All @@ -63,14 +64,17 @@ services:
- 1433:1433
environment:
SA_PASSWORD: "P@ssw0rd"
ACCEPT_EULA: "Y"
ACCEPT_EULA: "Y"

redis-sample:
build:
context: ../..
dockerfile: samples/Samples.Redis.SqlServer/Dockerfile
environment:
- ASPNETCORE_URLS:http://*:8080
- ASPNETCORE_ENVIRONMENT=Development
ports:
- 5000:80
- 8080:8080
depends_on:
- db
- redis-node-5
Expand All @@ -87,4 +91,4 @@ volumes:
redis-cluster_data-4:
driver: local
redis-cluster_data-5:
driver: local
driver: local
Loading

0 comments on commit 40a56d2

Please sign in to comment.