Skip to content

Commit 060985b

Browse files
Copilotkamilbaczek
andcommitted
Add Aspire AppHost and ServiceDefaults projects with RabbitMQ support
Co-authored-by: kamilbaczek <74410956+kamilbaczek@users.noreply.github.com>
1 parent 2ec071c commit 060985b

13 files changed

Lines changed: 262 additions & 8 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bin/
2+
obj/
3+
.vs/
4+
*.user
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<IsAspireHost>true</IsAspireHost>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
13+
<PackageReference Include="Aspire.Hosting.PostgreSQL" Version="9.0.0" />
14+
<PackageReference Include="Aspire.Hosting.RabbitMQ" Version="9.0.0" />
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\Fitnet.Contracts\Src\Fitnet.Contracts\Fitnet.Contracts.csproj" />
19+
<ProjectReference Include="..\Fitnet\Src\Fitnet\Fitnet.csproj" />
20+
<ProjectReference Include="..\Fitnet.ServiceDefaults\Fitnet.ServiceDefaults.csproj" />
21+
</ItemGroup>
22+
23+
</Project>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
var builder = DistributedApplication.CreateBuilder(args);
2+
3+
// Add PostgreSQL database
4+
var postgres = builder.AddPostgres("postgres")
5+
.WithImage("postgres")
6+
.WithImageTag("14.3")
7+
.WithEnvironment("POSTGRES_PASSWORD", "mysecretpassword")
8+
.WithHealthCheck();
9+
10+
var fitnetDb = postgres.AddDatabase("fitnet");
11+
12+
// Add RabbitMQ message broker
13+
var rabbitmq = builder.AddRabbitMQ("rabbitmq")
14+
.WithImage("rabbitmq")
15+
.WithImageTag("management")
16+
.WithManagementPlugin()
17+
.WithHealthCheck();
18+
19+
// Add Fitnet Contracts Microservice
20+
var contractsApi = builder.AddProject<Projects.Fitnet_Contracts>("fitnet-contracts-microservice")
21+
.WithReference(fitnetDb)
22+
.WithReference(rabbitmq)
23+
.WithHttpEndpoint(port: 8081, targetPort: 80, name: "http")
24+
.WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development");
25+
26+
// Add Fitnet Modular Monolith
27+
var fitnetApi = builder.AddProject<Projects.Fitnet>("fitnet-modular-monolith")
28+
.WithReference(fitnetDb)
29+
.WithReference(rabbitmq)
30+
.WithHttpEndpoint(port: 8080, targetPort: 80, name: "http")
31+
.WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development");
32+
33+
builder.Build().Run();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning",
6+
"Aspire.Hosting.DistributedApplication": "Information"
7+
}
8+
}
9+
}

Chapter-3-microservice-extraction/Fitnet.Contracts/Src/Fitnet.Contracts.Infrastructure/EventBus/EventBusModule.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace EvolutionaryArchitecture.Fitnet.Contracts.Infrastructure.EventBus;
88
internal static class EventBusModule
99
{
1010
private const string EventBusConfiguration = "EventBus";
11+
private const string RabbitMqConnectionName = "rabbitmq";
1112

1213
internal static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
1314
{
@@ -17,11 +18,32 @@ internal static IServiceCollection AddEventBus(this IServiceCollection services,
1718
configurator.SetSnakeCaseEndpointNameFormatter();
1819
configurator.UsingRabbitMq((context, factoryConfigurator) =>
1920
{
20-
var options = context.GetRequiredService<IOptions<EventBusOptions>>();
21-
var externalEventBusConfigured = options.Value is not null;
22-
if (!externalEventBusConfigured)
21+
// Try to get Aspire connection string first
22+
var connectionString = configuration.GetConnectionString(RabbitMqConnectionName);
23+
24+
if (!string.IsNullOrEmpty(connectionString))
2325
{
24-
return;
26+
// Use Aspire connection string
27+
factoryConfigurator.Host(new Uri(connectionString));
28+
}
29+
else
30+
{
31+
// Fallback to legacy configuration
32+
var options = context.GetRequiredService<IOptions<EventBusOptions>>();
33+
if (options.Value is not null && !string.IsNullOrEmpty(options.Value.Uri))
34+
{
35+
factoryConfigurator.Host(options.Value.Uri, hostConfigurator =>
36+
{
37+
if (!string.IsNullOrEmpty(options.Value.Username))
38+
{
39+
hostConfigurator.Username(options.Value.Username);
40+
}
41+
if (!string.IsNullOrEmpty(options.Value.Password))
42+
{
43+
hostConfigurator.Password(options.Value.Password);
44+
}
45+
});
46+
}
2547
}
2648

2749
factoryConfigurator.ConfigureEndpoints(context);

Chapter-3-microservice-extraction/Fitnet.Contracts/Src/Fitnet.Contracts/Fitnet.Contracts.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
<ItemGroup>
1414
<ProjectReference Include="..\Fitnet.Contracts.Api\Fitnet.Contracts.Api.csproj" />
15+
<ProjectReference Include="..\..\..\Fitnet.ServiceDefaults\Fitnet.ServiceDefaults.csproj" />
1516
</ItemGroup>
1617

1718
</Project>

Chapter-3-microservice-extraction/Fitnet.Contracts/Src/Fitnet.Contracts/Program.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
using EvolutionaryArchitecture.Fitnet.Common.Api.ErrorHandling;
22
using EvolutionaryArchitecture.Fitnet.Common.Infrastructure.Clock;
33
using EvolutionaryArchitecture.Fitnet.Contracts.Api;
4+
using Fitnet.ServiceDefaults;
45

56
var builder = WebApplication.CreateBuilder(args);
67

8+
builder.AddServiceDefaults();
9+
710
builder.Services.AddControllers();
811
builder.Services.AddEndpointsApiExplorer();
912
builder.Services.AddSwaggerGen();
@@ -20,6 +23,8 @@
2023
app.UseSwaggerUI();
2124
}
2225

26+
app.MapDefaultEndpoints();
27+
2328
app.UseHttpsRedirection();
2429
app.UseAuthorization();
2530
app.UseErrorHandling();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bin/
2+
obj/
3+
.vs/
4+
*.user
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using Microsoft.AspNetCore.Builder;
2+
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using Microsoft.Extensions.Diagnostics.HealthChecks;
5+
using Microsoft.Extensions.Hosting;
6+
using Microsoft.Extensions.Logging;
7+
using OpenTelemetry;
8+
using OpenTelemetry.Metrics;
9+
using OpenTelemetry.Trace;
10+
11+
namespace Fitnet.ServiceDefaults;
12+
13+
/// <summary>
14+
/// Provides extension methods for configuring Aspire service defaults.
15+
/// </summary>
16+
public static class Extensions
17+
{
18+
/// <summary>
19+
/// Configures Aspire service defaults including OpenTelemetry, health checks, and service discovery.
20+
/// </summary>
21+
public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder)
22+
{
23+
builder.ConfigureOpenTelemetry();
24+
builder.AddDefaultHealthChecks();
25+
builder.Services.AddServiceDiscovery();
26+
builder.Services.ConfigureHttpClientDefaults(http =>
27+
{
28+
http.AddStandardResilienceHandler();
29+
http.AddServiceDiscovery();
30+
});
31+
32+
return builder;
33+
}
34+
35+
/// <summary>
36+
/// Configures OpenTelemetry for logging, metrics, and tracing.
37+
/// </summary>
38+
public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder)
39+
{
40+
builder.Logging.AddOpenTelemetry(logging =>
41+
{
42+
logging.IncludeFormattedMessage = true;
43+
logging.IncludeScopes = true;
44+
});
45+
46+
builder.Services.AddOpenTelemetry()
47+
.WithMetrics(metrics =>
48+
{
49+
metrics.AddAspNetCoreInstrumentation()
50+
.AddHttpClientInstrumentation()
51+
.AddRuntimeInstrumentation();
52+
})
53+
.WithTracing(tracing =>
54+
{
55+
tracing.AddAspNetCoreInstrumentation()
56+
.AddHttpClientInstrumentation();
57+
});
58+
59+
builder.AddOpenTelemetryExporters();
60+
61+
return builder;
62+
}
63+
64+
private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder)
65+
{
66+
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
67+
68+
if (useOtlpExporter)
69+
{
70+
builder.Services.AddOpenTelemetry().UseOtlpExporter();
71+
}
72+
73+
return builder;
74+
}
75+
76+
/// <summary>
77+
/// Adds default health checks including a basic liveness check.
78+
/// </summary>
79+
public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder)
80+
{
81+
builder.Services.AddHealthChecks()
82+
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);
83+
84+
return builder;
85+
}
86+
87+
/// <summary>
88+
/// Maps default health check endpoints.
89+
/// </summary>
90+
public static WebApplication MapDefaultEndpoints(this WebApplication app)
91+
{
92+
app.MapHealthChecks("/health");
93+
app.MapHealthChecks("/alive", new HealthCheckOptions
94+
{
95+
Predicate = r => r.Tags.Contains("live")
96+
});
97+
98+
return app;
99+
}
100+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsAspireSharedProject>true</IsAspireSharedProject>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="9.0.0" />
12+
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="9.0.0" />
13+
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.10.0" />
14+
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.10.0" />
15+
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.10.0" />
16+
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.10.0" />
17+
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.10.0" />
18+
</ItemGroup>
19+
20+
<ItemGroup>
21+
<FrameworkReference Include="Microsoft.AspNetCore.App" />
22+
</ItemGroup>
23+
24+
</Project>

0 commit comments

Comments
 (0)