Skip to content

Commit

Permalink
feat: Add LavinMQ support #477 (#486)
Browse files Browse the repository at this point in the history
Update src/CommunityToolkit.Aspire.Hosting.LavinMQ/LavinMQHostingExtension.cs


refactor: remove connection string builder.

Co-authored-by: Aaron Powell <[email protected]>
  • Loading branch information
prom3theu5 and aaronpowell authored Feb 19, 2025
1 parent 60172d0 commit 6b47e96
Show file tree
Hide file tree
Showing 28 changed files with 765 additions and 2 deletions.
38 changes: 38 additions & 0 deletions CommunityToolkit.Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "redis-ext", "redis-ext", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.Redis.Extensions.Tests", "tests\CommunityToolkit.Aspire.Hosting.Redis.Extensions.Tests\CommunityToolkit.Aspire.Hosting.Redis.Extensions.Tests.csproj", "{958A251E-9D2A-4D67-9D1C-47D6A9E36B3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.LavinMQ", "src\CommunityToolkit.Aspire.Hosting.LavinMQ\CommunityToolkit.Aspire.Hosting.LavinMQ.csproj", "{F218A6C1-3D4F-4351-9580-C99DBC3774FF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.LavinMQ.Tests", "tests\CommunityToolkit.Aspire.Hosting.LavinMQ.Tests\CommunityToolkit.Aspire.Hosting.LavinMQ.Tests.csproj", "{E0B23172-E795-4AC5-B9E2-6922E4F167BB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "lavinmq", "lavinmq", "{35E5A4C8-219B-44AC-AB93-B07A67BCC810}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.LavinMQ.AppHost", "examples\lavinmq\CommunityToolkit.Aspire.Hosting.LavinMQ.AppHost\CommunityToolkit.Aspire.Hosting.LavinMQ.AppHost.csproj", "{7068DDA8-71B9-428E-BCC3-89658670B830}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit", "examples\lavinmq\CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit\CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit.csproj", "{8C463360-0156-461C-A065-CC30FE3B0595}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.LavinMQ.ServiceDefaults", "examples\lavinmq\CommunityToolkit.Aspire.Hosting.LavinMQ.ServiceDefaults\CommunityToolkit.Aspire.Hosting.LavinMQ.ServiceDefaults.csproj", "{A5C87DA6-6793-4824-88E5-4F8310FE55B8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mailpit", "mailpit", "{734EF69D-EE4D-4E9B-96BD-A44E53C5D2EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityToolkit.Aspire.Hosting.MailPit", "src\CommunityToolkit.Aspire.Hosting.MailPit\CommunityToolkit.Aspire.Hosting.MailPit.csproj", "{73E7BC19-A626-4C55-990B-A878BF84D4CA}"
Expand Down Expand Up @@ -867,6 +879,26 @@ Global
{958A251E-9D2A-4D67-9D1C-47D6A9E36B3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{958A251E-9D2A-4D67-9D1C-47D6A9E36B3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{958A251E-9D2A-4D67-9D1C-47D6A9E36B3A}.Release|Any CPU.Build.0 = Release|Any CPU
{F218A6C1-3D4F-4351-9580-C99DBC3774FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F218A6C1-3D4F-4351-9580-C99DBC3774FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F218A6C1-3D4F-4351-9580-C99DBC3774FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F218A6C1-3D4F-4351-9580-C99DBC3774FF}.Release|Any CPU.Build.0 = Release|Any CPU
{E0B23172-E795-4AC5-B9E2-6922E4F167BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0B23172-E795-4AC5-B9E2-6922E4F167BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0B23172-E795-4AC5-B9E2-6922E4F167BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0B23172-E795-4AC5-B9E2-6922E4F167BB}.Release|Any CPU.Build.0 = Release|Any CPU
{7068DDA8-71B9-428E-BCC3-89658670B830}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7068DDA8-71B9-428E-BCC3-89658670B830}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7068DDA8-71B9-428E-BCC3-89658670B830}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7068DDA8-71B9-428E-BCC3-89658670B830}.Release|Any CPU.Build.0 = Release|Any CPU
{8C463360-0156-461C-A065-CC30FE3B0595}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8C463360-0156-461C-A065-CC30FE3B0595}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8C463360-0156-461C-A065-CC30FE3B0595}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8C463360-0156-461C-A065-CC30FE3B0595}.Release|Any CPU.Build.0 = Release|Any CPU
{A5C87DA6-6793-4824-88E5-4F8310FE55B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5C87DA6-6793-4824-88E5-4F8310FE55B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5C87DA6-6793-4824-88E5-4F8310FE55B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5C87DA6-6793-4824-88E5-4F8310FE55B8}.Release|Any CPU.Build.0 = Release|Any CPU
{73E7BC19-A626-4C55-990B-A878BF84D4CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{73E7BC19-A626-4C55-990B-A878BF84D4CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{73E7BC19-A626-4C55-990B-A878BF84D4CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -1050,6 +1082,12 @@ Global
{CB491C52-A3D5-4F36-97C4-75C482F90A30} = {734EF69D-EE4D-4E9B-96BD-A44E53C5D1EC}
{734EF69D-EE4D-4E9B-96BD-A44E53C5D1EC} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
{958A251E-9D2A-4D67-9D1C-47D6A9E36B3A} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{F218A6C1-3D4F-4351-9580-C99DBC3774FF} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
{E0B23172-E795-4AC5-B9E2-6922E4F167BB} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{35E5A4C8-219B-44AC-AB93-B07A67BCC810} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
{7068DDA8-71B9-428E-BCC3-89658670B830} = {35E5A4C8-219B-44AC-AB93-B07A67BCC810}
{8C463360-0156-461C-A065-CC30FE3B0595} = {35E5A4C8-219B-44AC-AB93-B07A67BCC810}
{A5C87DA6-6793-4824-88E5-4F8310FE55B8} = {35E5A4C8-219B-44AC-AB93-B07A67BCC810}
{73E7BC19-A626-4C55-990B-A878BF84D4CA} = {414151D4-7009-4E78-A5C6-D99EBD1E67D1}
{9C66ECFF-8077-4D5A-9CEB-6E9AB6CCBE94} = {899F0713-7FC6-4750-BAFC-AC650B35B453}
{734EF69D-EE4D-4E9B-96BD-A44E53C5D2EC} = {8519CC01-1370-47C8-AD94-B0F326B1563F}
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<PackageVersion Include="Aspire.Hosting.SqlServer" Version="$(AspireVersion)" />
<!-- AspNetCore packages -->
<PackageVersion Include="AspNetCore.HealthChecks.EventStore.gRPC" Version="9.0.0" />
<PackageVersion Include="AspNetCore.HealthChecks.Rabbitmq" Version="9.0.0" />
<PackageVersion Include="AspNetCore.HealthChecks.Sqlite" Version="9.0.0" />
<PackageVersion Include="AspNetCore.HealthChecks.SqlServer" Version="9.0.0" />
<PackageVersion Include="AspNetCore.HealthChecks.Uris" Version="9.0.0" />
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ This repository contains the source code for the .NET Aspire Community Toolkit,
| - **Learn More**: [`Hosting.MongoDB.Extensions`][mongodb-ext-integration-docs] <br /> - Stable 📦: [![CommunityToolkit.Aspire.MongoDB.Extensions][mongodb-ext-shields]][mongodb-ext-nuget] <br /> - Preview 📦: [![CommunityToolkit.Aspire.Hosting.MongoDB.Extensions][mongodb-ext-shields-preview]][mongodb-ext-nuget-preview] | An integration that contains some additional extensions for hosting MongoDB container. |
| - **Learn More**: [`Hosting.PostgreSQL.Extensions`][postgres-ext-integration-docs] <br /> - Stable 📦: [![CommunityToolkit.Aspire.PostgreSQL.Extensions][postgres-ext-shields]][postgres-ext-nuget] <br /> - Preview 📦: [![CommunityToolkit.Aspire.Hosting.PostgreSQL.Extensions][postgres-ext-shields-preview]][postgres-ext-nuget-preview] | An integration that contains some additional extensions for hosting PostgreSQL container. |
| - **Learn More**: [`Hosting.Redis.Extensions`][redis-ext-integration-docs] <br /> - Stable 📦: [![CommunityToolkit.Aspire.Redis.Extensions][redis-ext-shields]][redis-ext-nuget] <br /> - Preview 📦: [![CommunityToolkit.Aspire.Hosting.Redis.Extensions][redis-ext-shields-preview]][redis-ext-nuget-preview] | An integration that contains some additional extensions for hosting Redis container. |
| - **Learn More**: [`Hosting.LavinMQ`][lavinmq-integration-docs] <br /> - Stable 📦: [![CommunityToolkit.Aspire.Hosting.LavinMQ][lavinmq-shields]][lavinmq-nuget] <br /> - Preview 📦: [![CommunityToolkit.Aspire.Hosting.LavinMQ][lavinmq-shields-preview]][lavinmq-nuget-preview] | An Aspire hosting integration for [LavinMQ](https://www.lavinmq.com). |
| - **Learn More**: [`Hosting.MailPit`][mailpit-ext-integration-docs] <br /> - Stable 📦: [![CommunityToolkit.Aspire.Hosting.MailPit][mailpit-ext-shields]][mailpit-ext-nuget] <br /> - Preview 📦: [![CommunityToolkit.Aspire.Hosting.MailPit][mailpit-ext-shields-preview]][mailpit-ext-nuget-preview] | An Aspire integration leveraging the [MailPit](https://mailpit.axllent.org/) container. |


## 🙌 Getting Started

Each of the integrations in the toolkit is available as a NuGet package, and can be added to your .NET project. Refer to the table above for the available integrations and the documentation on how to use them.
Expand Down Expand Up @@ -224,8 +224,13 @@ This project is supported by the [.NET Foundation](https://dotnetfoundation.org)
[redis-ext-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.Redis.Extensions/
[redis-ext-shields-preview]: https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.Hosting.Redis.Extensions?label=nuget%20(preview)
[redis-ext-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.Redis.Extensions/absoluteLatest
[lavinmq-integration-docs]: https://learn.microsoft.com/dotnet/aspire/community-toolkit/hosting-lavinmq
[lavinmq-shields]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.LavinMQ
[lavinmq-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.LavinMQ/
[lavinmq-shields-preview]: https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.Hosting.LavinMQ?label=nuget%20(preview)
[lavinmq-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.LavinMQ/absoluteLatest
[mailpit-ext-integration-docs]: https://learn.microsoft.com/dotnet/aspire/community-toolkit/hosting-mailpit
[mailpit-ext-shields]: https://img.shields.io/nuget/v/CommunityToolkit.Aspire.Hosting.MailPit
[mailpit-ext-nuget]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.MailPit/
[mailpit-ext-shields-preview]: https://img.shields.io/nuget/vpre/CommunityToolkit.Aspire.Hosting.MailPit?label=nuget%20(preview)
[mailpit-ext-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.MailPit/absoluteLatest
[mailpit-ext-nuget-preview]: https://nuget.org/packages/CommunityToolkit.Aspire.Hosting.MailPit/absoluteLatest
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="$(AspireAppHostSdkVersion)" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>cb846a57-bdaf-4abd-a7fb-0299aa095f5e</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting" />
<PackageReference Include="Aspire.Hosting.AppHost" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\CommunityToolkit.Aspire.Hosting.LavinMQ\CommunityToolkit.Aspire.Hosting.LavinMQ.csproj" IsAspireProjectResource="false" />
<ProjectReference Include="..\CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit\CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Projects;

var builder = DistributedApplication.CreateBuilder(args);

var lavinmq = builder.AddLavinMQ("lavinmq")
.PublishAsConnectionString();

builder.AddProject<CommunityToolkit_Aspire_Hosting_LavinMQ_MassTransit>("masstransitExample")
.WithReference(lavinmq)
.WithHttpHealthCheck(path: "/health")
.WaitFor(lavinmq);

builder.Build().Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:17276;http://localhost:15246",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21269",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22000"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15246",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19099",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20012"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MassTransit" />
<PackageReference Include="MassTransit.RabbitMQ" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\CommunityToolkit.Aspire.Hosting.LavinMQ.ServiceDefaults\CommunityToolkit.Aspire.Hosting.LavinMQ.ServiceDefaults.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit_HostAddress = http://localhost:5004

POST http://localhost:5004/send/Hello%20World
Accept: application/json

###
GET http://localhost:5004/alive
Accept: application/json

###
GET http://localhost:5004/received
Accept: application/json

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using MassTransit;

namespace CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit;

public class HelloWorldConsumer(ILogger<HelloWorldConsumer> logger, MessageCounter messageCounter) : IConsumer<Message>
{
public async Task Consume(ConsumeContext<Message> context)
{
logger.LogInformation("Received message: {Text}", context.Message.Text);
messageCounter.ReceivedMessages++;
await context.RespondAsync<MessageReply>(new
{
Reply = "I've received your message: " + context.Message.Text
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit;

public record Message
{
public required string Text { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit;

public class MessageCounter
{
public int ReceivedMessages { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit;

public record MessageReply
{
public required string Reply { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using CommunityToolkit.Aspire.Hosting.LavinMQ.MassTransit;
using MassTransit;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();
builder.Services
.AddSingleton(KebabCaseEndpointNameFormatter.Instance)
.AddSingleton<MessageCounter>();
builder.Services.AddMassTransit(x =>
{
x.UsingRabbitMq((context, cfg) =>
{
string connectionString = builder.Configuration.GetConnectionString("lavinmq")!;
cfg.ConfigureEndpoints(context, new KebabCaseEndpointNameFormatter("aspire", false));
cfg.Host(new Uri(connectionString), _ => {});
});
x.AddConsumers(typeof(HelloWorldConsumer).Assembly);
});

WebApplication app = builder.Build();

app.MapPost("/send/{text}", async (string text,
[FromServices] IRequestClient<Message> requestClient,
[FromServices] ILogger<Program> logger) =>
{
logger.LogInformation("Send message: {Text}", text);
Response<MessageReply> response = await requestClient.GetResponse<MessageReply>(new { Text = text });
logger.LogInformation("Sent message: {Text}", text);
return response.Message.Reply;
})
.WithName("SendMessage");

app.MapGet("/received", ([FromServices] MessageCounter messageCounter) => messageCounter)
.WithName("ReceivedMessages");

app.MapDefaultEndpoints();
app.Run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5004",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7038;http://localhost:5004",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"ConnectionStrings": {
"lavinmq": "amqp://localhost:5672"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
</ItemGroup>

</Project>
Loading

0 comments on commit 6b47e96

Please sign in to comment.