Skip to content

Commit

Permalink
Merge pull request #91 from canro91/aspirify
Browse files Browse the repository at this point in the history
Create a Boostrapper project to "aspirify" the solution
  • Loading branch information
ardalis authored Oct 28, 2024
2 parents 468845d + 18c5455 commit 9626219
Show file tree
Hide file tree
Showing 25 changed files with 376 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
uses: github/codeql-action/init@v3
with:
queries: security-and-quality

- name: Install .NET Aspire workload
run: dotnet workload install aspire

- name: Autobuild
uses: github/codeql-action/autobuild@v3
Expand Down
28 changes: 28 additions & 0 deletions Boostrapper/Boostrapper.AppHost/Boostrapper.AppHost.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
<UserSecretsId>d12db2d9-4513-4ed2-8c6c-bff19ed1edf1</UserSecretsId>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.1" />
<PackageReference Include="Aspire.Hosting.RabbitMQ" Version="8.2.1" />
<PackageReference Include="Aspire.Hosting.SqlServer" Version="8.2.1" />
<PackageReference Include="Nall.Aspire.Hosting.DependsOn" Version="1.0.1" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\ClinicManagement\src\ClinicManagement.Api\ClinicManagement.Api.csproj" />
<ProjectReference Include="..\..\ClinicManagement\src\ClinicManagement.Blazor.Host\ClinicManagement.Blazor.Host.csproj" />
<ProjectReference Include="..\..\FrontDesk\src\FrontDesk.Api\FrontDesk.Api.csproj" />
<ProjectReference Include="..\..\FrontDesk\src\FrontDesk.Blazor.Host\FrontDesk.Blazor.Host.csproj" />
<ProjectReference Include="..\..\VetClinicPublic\src\VetClinicPublic\VetClinicPublic.csproj" />
</ItemGroup>

</Project>
43 changes: 43 additions & 0 deletions Boostrapper/Boostrapper.AppHost/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
var builder = DistributedApplication.CreateBuilder(args);

var emailServer = builder.AddContainer("mailserver", "jijiechen/papercut")
.WithEndpoint(port: 37408, targetPort: 37408, scheme: "http")
.WithEndpoint(port: 25, targetPort: 25);

var rabbitmqUser = builder.AddParameter("rabbitmq-username", secret: true);
var rabbitmqPassword = builder.AddParameter("rabbitmq-password", secret: true);

var rabbitmq = builder.AddRabbitMQ("rabbitmq", rabbitmqUser, rabbitmqPassword, port: 5672)
.WithDataVolume()
.WithManagementPlugin();

builder.AddProject<Projects.VetClinicPublic>("vet-clinic-public")
.WaitFor(rabbitmq)
.WaitFor(emailServer);

var frontDeskDb = builder.AddSqlServer("frontdesk-sqlserver", port: 1434)
.WithImageTag("2019-latest")
.AddDatabase("frontdesk-db");

var frontDeskApi = builder.AddProject<Projects.FrontDesk_Api>("frontdesk-api")
.WaitFor(rabbitmq)
.WaitFor(frontDeskDb)
.WithReference(frontDeskDb, "DefaultConnection");

builder.AddProject<Projects.FrontDesk_Blazor_Host>("frontdesk-blazor-host")
.WaitFor(frontDeskApi);


var clinicManagementDb = builder.AddSqlServer("clinicmanagement-sqlserver", port: 1435)
.WithImageTag("2019-latest")
.AddDatabase("clinicmanagement-db");

var clinicManagementApi = builder.AddProject<Projects.ClinicManagement_Api>("clinicmanagement-api")
.WaitFor(rabbitmq)
.WaitFor(clinicManagementDb)
.WithReference(clinicManagementDb, "DefaultConnection");

builder.AddProject<Projects.ClinicManagement_Blazor_Host>("clinicmanagement-blazor-host")
.WaitFor(clinicManagementApi);

builder.Build().Run();
29 changes: 29 additions & 0 deletions Boostrapper/Boostrapper.AppHost/Properties/launchSettings.json
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:17274;http://localhost:15033",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21005",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22248"
}
},
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:15033",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
"DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19004",
"DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20143"
}
}
}
}
8 changes: 8 additions & 0 deletions Boostrapper/Boostrapper.AppHost/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
13 changes: 13 additions & 0 deletions Boostrapper/Boostrapper.AppHost/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Aspire.Hosting.Dcp": "Warning"
}
},
"Parameters": {
"rabbitmq-username": "guest",
"rabbitmq-password": "guest"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireSharedProject>true</IsAspireSharedProject>
</PropertyGroup>

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

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

</Project>
111 changes: 111 additions & 0 deletions Boostrapper/Boostrapper.ServiceDefaults/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;

namespace Microsoft.Extensions.Hosting;

// Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry.
// This project should be referenced by each service project in your solution.
// To learn more about using this project, see https://aka.ms/dotnet/aspire/service-defaults
public static class Extensions
{
public static IHostApplicationBuilder AddServiceDefaults(this IHostApplicationBuilder builder)
{
builder.ConfigureOpenTelemetry();

builder.AddDefaultHealthChecks();

builder.Services.AddServiceDiscovery();

builder.Services.ConfigureHttpClientDefaults(http =>
{
// Turn on resilience by default
http.AddStandardResilienceHandler();

// Turn on service discovery by default
http.AddServiceDiscovery();
});

return builder;
}

public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicationBuilder builder)
{
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});

builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation();
})
.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation()
// Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package)
//.AddGrpcClientInstrumentation()
.AddHttpClientInstrumentation();
});

builder.AddOpenTelemetryExporters();

return builder;
}

private static IHostApplicationBuilder AddOpenTelemetryExporters(this IHostApplicationBuilder builder)
{
var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);

if (useOtlpExporter)
{
builder.Services.AddOpenTelemetry().UseOtlpExporter();
}

// Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.AspNetCore package)
//if (!string.IsNullOrEmpty(builder.Configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]))
//{
// builder.Services.AddOpenTelemetry()
// .UseAzureMonitor();
//}

return builder;
}

public static IHostApplicationBuilder AddDefaultHealthChecks(this IHostApplicationBuilder builder)
{
builder.Services.AddHealthChecks()
// Add a default liveness check to ensure app is responsive
.AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]);

return builder;
}

public static WebApplication MapDefaultEndpoints(this WebApplication app)
{
// Adding health checks endpoints to applications in non-development environments has security implications.
// See https://aka.ms/dotnet/aspire/healthchecks for details before enabling these endpoints in non-development environments.
if (app.Environment.IsDevelopment())
{
// All health checks must pass for app to be considered ready to accept traffic after starting
app.MapHealthChecks("/health");

// Only health checks tagged with the "live" tag must pass for app to be considered alive
app.MapHealthChecks("/alive", new HealthCheckOptions
{
Predicate = r => r.Tags.Contains("live")
});
}

return app;
}
}
80 changes: 80 additions & 0 deletions Boostrapper/Boostrapper.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35327.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boostrapper.AppHost", "Boostrapper.AppHost\Boostrapper.AppHost.csproj", "{F66C35ED-43A6-4841-BF4F-1ED29C175FFB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boostrapper.ServiceDefaults", "Boostrapper.ServiceDefaults\Boostrapper.ServiceDefaults.csproj", "{EACC3C02-7D6E-413E-B4D0-B40AE88AE602}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VetClinicPublic", "VetClinicPublic", "{A218EB75-4210-4A23-9699-329ACCD1CB0D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VetClinicPublic", "..\VetClinicPublic\src\VetClinicPublic\VetClinicPublic.csproj", "{1924E63F-EC1B-4B0A-ACE6-AA52DA8BA7EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VetClinicPublic.Contracts", "..\VetClinicPublic\src\VetClinicPublic.Contracts\VetClinicPublic.Contracts.csproj", "{07D90B16-558F-4E72-9F93-7C402D80EAC9}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FrontDesk", "FrontDesk", "{6367C1FD-EA04-4EC0-B25E-5A76C8BFB85E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrontDesk.Api", "..\FrontDesk\src\FrontDesk.Api\FrontDesk.Api.csproj", "{22682767-0DE6-4BAF-B32F-B5186F6F34B5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrontDesk.Blazor.Host", "..\FrontDesk\src\FrontDesk.Blazor.Host\FrontDesk.Blazor.Host.csproj", "{3749151C-E180-4D44-AB41-3F1FB14A7D44}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ClinicManagement", "ClinicManagement", "{B5554F10-7AC8-4F0A-B9E7-58D669B0A9A0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClinicManagement.Api", "..\ClinicManagement\src\ClinicManagement.Api\ClinicManagement.Api.csproj", "{AC551A2C-5C81-4DC5-BEF2-290DE78ABE7C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClinicManagement.Blazor.Host", "..\ClinicManagement\src\ClinicManagement.Blazor.Host\ClinicManagement.Blazor.Host.csproj", "{965EE57B-9B02-42F2-A8F0-287D22D68496}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F66C35ED-43A6-4841-BF4F-1ED29C175FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F66C35ED-43A6-4841-BF4F-1ED29C175FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F66C35ED-43A6-4841-BF4F-1ED29C175FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F66C35ED-43A6-4841-BF4F-1ED29C175FFB}.Release|Any CPU.Build.0 = Release|Any CPU
{EACC3C02-7D6E-413E-B4D0-B40AE88AE602}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EACC3C02-7D6E-413E-B4D0-B40AE88AE602}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EACC3C02-7D6E-413E-B4D0-B40AE88AE602}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EACC3C02-7D6E-413E-B4D0-B40AE88AE602}.Release|Any CPU.Build.0 = Release|Any CPU
{1924E63F-EC1B-4B0A-ACE6-AA52DA8BA7EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1924E63F-EC1B-4B0A-ACE6-AA52DA8BA7EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1924E63F-EC1B-4B0A-ACE6-AA52DA8BA7EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1924E63F-EC1B-4B0A-ACE6-AA52DA8BA7EC}.Release|Any CPU.Build.0 = Release|Any CPU
{07D90B16-558F-4E72-9F93-7C402D80EAC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07D90B16-558F-4E72-9F93-7C402D80EAC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07D90B16-558F-4E72-9F93-7C402D80EAC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07D90B16-558F-4E72-9F93-7C402D80EAC9}.Release|Any CPU.Build.0 = Release|Any CPU
{22682767-0DE6-4BAF-B32F-B5186F6F34B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{22682767-0DE6-4BAF-B32F-B5186F6F34B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{22682767-0DE6-4BAF-B32F-B5186F6F34B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{22682767-0DE6-4BAF-B32F-B5186F6F34B5}.Release|Any CPU.Build.0 = Release|Any CPU
{3749151C-E180-4D44-AB41-3F1FB14A7D44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3749151C-E180-4D44-AB41-3F1FB14A7D44}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3749151C-E180-4D44-AB41-3F1FB14A7D44}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3749151C-E180-4D44-AB41-3F1FB14A7D44}.Release|Any CPU.Build.0 = Release|Any CPU
{AC551A2C-5C81-4DC5-BEF2-290DE78ABE7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC551A2C-5C81-4DC5-BEF2-290DE78ABE7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC551A2C-5C81-4DC5-BEF2-290DE78ABE7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC551A2C-5C81-4DC5-BEF2-290DE78ABE7C}.Release|Any CPU.Build.0 = Release|Any CPU
{965EE57B-9B02-42F2-A8F0-287D22D68496}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{965EE57B-9B02-42F2-A8F0-287D22D68496}.Debug|Any CPU.Build.0 = Debug|Any CPU
{965EE57B-9B02-42F2-A8F0-287D22D68496}.Release|Any CPU.ActiveCfg = Release|Any CPU
{965EE57B-9B02-42F2-A8F0-287D22D68496}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{1924E63F-EC1B-4B0A-ACE6-AA52DA8BA7EC} = {A218EB75-4210-4A23-9699-329ACCD1CB0D}
{07D90B16-558F-4E72-9F93-7C402D80EAC9} = {A218EB75-4210-4A23-9699-329ACCD1CB0D}
{22682767-0DE6-4BAF-B32F-B5186F6F34B5} = {6367C1FD-EA04-4EC0-B25E-5A76C8BFB85E}
{3749151C-E180-4D44-AB41-3F1FB14A7D44} = {6367C1FD-EA04-4EC0-B25E-5A76C8BFB85E}
{AC551A2C-5C81-4DC5-BEF2-290DE78ABE7C} = {B5554F10-7AC8-4F0A-B9E7-58D669B0A9A0}
{965EE57B-9B02-42F2-A8F0-287D22D68496} = {B5554F10-7AC8-4F0A-B9E7-58D669B0A9A0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {952056B2-661B-40C9-BC60-33B9C3D4E541}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\Boostrapper\Boostrapper.ServiceDefaults\Boostrapper.ServiceDefaults.csproj" />
<ProjectReference Include="..\ClinicManagement.BlazorShared\ClinicManagement.BlazorShared.csproj" />
<ProjectReference Include="..\ClinicManagement.Contracts\ClinicManagement.Contracts.csproj" />
<ProjectReference Include="..\ClinicManagement.Infrastructure\ClinicManagement.Infrastructure.csproj" />
Expand Down
6 changes: 5 additions & 1 deletion ClinicManagement/src/ClinicManagement.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;
using System.Reflection;
using BlazorShared;
using ClinicManagement.Api;
Expand All @@ -18,6 +18,8 @@

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

// use real database
// Requires LocalDB which can be installed with SQL Server Express 2016
// https://www.microsoft.com/en-us/download/details.aspx?id=54284
Expand Down Expand Up @@ -78,6 +80,8 @@

var app = builder.Build();

app.MapDefaultEndpoints();

await app.SeedDatabaseAsync();

app.UseResponseCompression();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"profiles": {
"ClinicManagement.Api": {
"commandName": "Project",
"dotnetRunMessages": "true",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:6251;http://localhost:6250",
Expand Down
Loading

0 comments on commit 9626219

Please sign in to comment.