diff --git a/.github/workflows/pr_ci.yml b/.github/workflows/pr_ci.yml index 7dcde8681af..19a2d28215d 100644 --- a/.github/workflows/pr_ci.yml +++ b/.github/workflows/pr_ci.yml @@ -24,6 +24,13 @@ jobs: - uses: actions/setup-dotnet@v3 with: dotnet-version: '8.0.x' + dotnet-quality: 'preview' + - name: Update Workload + run: | + dotnet workload update --from-previous-sdk + - name: Setup Aspire + run: | + dotnet workload install aspire - name: Build run: | dotnet build -c Release diff --git a/OrchardCore.sln b/OrchardCore.sln index 012a41a30d5..c9f860434f2 100644 --- a/OrchardCore.sln +++ b/OrchardCore.sln @@ -507,6 +507,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Sms", "src\Orch EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Sms.Core", "src\OrchardCore\OrchardCore.Sms.Core\OrchardCore.Sms.Core.csproj", "{20356393-B16D-466C-8203-877A534E287D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.AppHost", "src\Aspire\Aspire.AppHost\Aspire.AppHost.csproj", "{B8A5D532-1F7D-40ED-B6B0-BE36C8B81D91}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.ServiceDefaults", "src\Aspire\Aspire.ServiceDefaults\Aspire.ServiceDefaults.csproj", "{C2BB6BBB-4F5F-4D2F-975D-D50DD38FCABF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aspire", "Aspire", "{5DC4B8E4-9BE0-4B57-8065-7DC0A44DBD20}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.OrchardCore.Cms.Web", "src\Aspire\Aspire.OrchardCore.Cms.Web\Aspire.OrchardCore.Cms.Web.csproj", "{3DE87BB4-BA03-4C02-861F-6EE51898E682}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aspire.OrchardCore.Mvc.Web", "src\Aspire\Aspire.OrchardCore.Mvc.Web\Aspire.OrchardCore.Mvc.Web.csproj", "{59D2CC21-A422-42D5-8118-C16B7EE52F77}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Search.AzureAI", "src\OrchardCore.Modules\OrchardCore.Search.AzureAI\OrchardCore.Search.AzureAI.csproj", "{5527BACF-FA5D-4617-978B-7EDE8942E6F6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrchardCore.Search.AzureAI.Core", "src\OrchardCore\OrchardCore.Search.AzureAI.Core\OrchardCore.Search.AzureAI.Core.csproj", "{E9428DE8-5D81-4359-BF84-31435041FF1A}" @@ -1339,6 +1348,22 @@ Global {20356393-B16D-466C-8203-877A534E287D}.Debug|Any CPU.Build.0 = Debug|Any CPU {20356393-B16D-466C-8203-877A534E287D}.Release|Any CPU.ActiveCfg = Release|Any CPU {20356393-B16D-466C-8203-877A534E287D}.Release|Any CPU.Build.0 = Release|Any CPU + {B8A5D532-1F7D-40ED-B6B0-BE36C8B81D91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8A5D532-1F7D-40ED-B6B0-BE36C8B81D91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8A5D532-1F7D-40ED-B6B0-BE36C8B81D91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8A5D532-1F7D-40ED-B6B0-BE36C8B81D91}.Release|Any CPU.Build.0 = Release|Any CPU + {C2BB6BBB-4F5F-4D2F-975D-D50DD38FCABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2BB6BBB-4F5F-4D2F-975D-D50DD38FCABF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2BB6BBB-4F5F-4D2F-975D-D50DD38FCABF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2BB6BBB-4F5F-4D2F-975D-D50DD38FCABF}.Release|Any CPU.Build.0 = Release|Any CPU + {3DE87BB4-BA03-4C02-861F-6EE51898E682}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3DE87BB4-BA03-4C02-861F-6EE51898E682}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3DE87BB4-BA03-4C02-861F-6EE51898E682}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3DE87BB4-BA03-4C02-861F-6EE51898E682}.Release|Any CPU.Build.0 = Release|Any CPU + {59D2CC21-A422-42D5-8118-C16B7EE52F77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {59D2CC21-A422-42D5-8118-C16B7EE52F77}.Debug|Any CPU.Build.0 = Debug|Any CPU + {59D2CC21-A422-42D5-8118-C16B7EE52F77}.Release|Any CPU.ActiveCfg = Release|Any CPU + {59D2CC21-A422-42D5-8118-C16B7EE52F77}.Release|Any CPU.Build.0 = Release|Any CPU {5527BACF-FA5D-4617-978B-7EDE8942E6F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5527BACF-FA5D-4617-978B-7EDE8942E6F6}.Debug|Any CPU.Build.0 = Debug|Any CPU {5527BACF-FA5D-4617-978B-7EDE8942E6F6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -1578,6 +1603,11 @@ Global {2D93F509-1FB3-4E22-92F0-588D0EFBA921} = {F23AC6C2-DE44-4699-999D-3C478EF3D691} {CBF6DB53-FD0C-47F8-9E60-A1D247ACFD05} = {A066395F-6F73-45DC-B5A6-B4E306110DCE} {20356393-B16D-466C-8203-877A534E287D} = {F23AC6C2-DE44-4699-999D-3C478EF3D691} + {B8A5D532-1F7D-40ED-B6B0-BE36C8B81D91} = {5DC4B8E4-9BE0-4B57-8065-7DC0A44DBD20} + {C2BB6BBB-4F5F-4D2F-975D-D50DD38FCABF} = {5DC4B8E4-9BE0-4B57-8065-7DC0A44DBD20} + {5DC4B8E4-9BE0-4B57-8065-7DC0A44DBD20} = {275E087F-A4E2-4A7B-A924-ED68E3A52086} + {3DE87BB4-BA03-4C02-861F-6EE51898E682} = {5DC4B8E4-9BE0-4B57-8065-7DC0A44DBD20} + {59D2CC21-A422-42D5-8118-C16B7EE52F77} = {5DC4B8E4-9BE0-4B57-8065-7DC0A44DBD20} {5527BACF-FA5D-4617-978B-7EDE8942E6F6} = {90030E85-0C4F-456F-B879-443E8A3F220D} {E9428DE8-5D81-4359-BF84-31435041FF1A} = {F23AC6C2-DE44-4699-999D-3C478EF3D691} EndGlobalSection diff --git a/src/Aspire/Aspire.AppHost/Aspire.AppHost.csproj b/src/Aspire/Aspire.AppHost/Aspire.AppHost.csproj new file mode 100644 index 00000000000..5f4dcd6bb78 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/Aspire.AppHost.csproj @@ -0,0 +1,21 @@ + + + + Exe + enable + enable + true + + + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.AppHost/Program.cs b/src/Aspire/Aspire.AppHost/Program.cs new file mode 100644 index 00000000000..e0f47e57d24 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/Program.cs @@ -0,0 +1,10 @@ +var builder = DistributedApplication.CreateBuilder(args); + +var redis = builder.AddRedisContainer("Redis", 50963); + +builder.AddProject("OrchardCore CMS App") + .WithReference(redis); + +builder.AddProject("OrchardCore MVC App"); + +await builder.Build().RunAsync(); diff --git a/src/Aspire/Aspire.AppHost/Properties/launchSettings.json b/src/Aspire/Aspire.AppHost/Properties/launchSettings.json new file mode 100644 index 00000000000..6296f010cc7 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/Properties/launchSettings.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:15139", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "DOTNET_ENVIRONMENT": "Development", + "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:16125" + } + } + } +} diff --git a/src/Aspire/Aspire.AppHost/appsettings.Development.json b/src/Aspire/Aspire.AppHost/appsettings.Development.json new file mode 100644 index 00000000000..0c208ae9181 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/Aspire/Aspire.AppHost/appsettings.json b/src/Aspire/Aspire.AppHost/appsettings.json new file mode 100644 index 00000000000..31c092aa450 --- /dev/null +++ b/src/Aspire/Aspire.AppHost/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Aspire.Hosting.Dcp": "Warning" + } + } +} diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/Aspire.OrchardCore.Cms.Web.csproj b/src/Aspire/Aspire.OrchardCore.Cms.Web/Aspire.OrchardCore.Cms.Web.csproj new file mode 100644 index 00000000000..dc7cff0639c --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/Aspire.OrchardCore.Cms.Web.csproj @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/Localization/.placeholder b/src/Aspire/Aspire.OrchardCore.Cms.Web/Localization/.placeholder new file mode 100644 index 00000000000..95c193c13ef --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/Localization/.placeholder @@ -0,0 +1 @@ +# This file is used to ensure the Localization folder is created during deployment diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/NLog.config b/src/Aspire/Aspire.OrchardCore.Cms.Web/NLog.config new file mode 100644 index 00000000000..8d4eef2d62b --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/NLog.config @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/Program.cs b/src/Aspire/Aspire.OrchardCore.Cms.Web/Program.cs new file mode 100644 index 00000000000..772eb0500ad --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/Program.cs @@ -0,0 +1,41 @@ +using OrchardCore.Logging; + +var builder = WebApplication.CreateBuilder(args); + +builder.Host.UseNLogHost(); +builder.AddServiceDefaults(); + +var ocBuilder = builder.Services + .AddOrchardCms() + .AddSetupFeatures("OrchardCore.AutoSetup"); + +if (builder.Configuration.GetValue("EnableAzureCoreFeatures")) +{ + // Enable Azure based resources to store the shell configs and the data protections. + ocBuilder.AddAzureShellsConfiguration() + .AddGlobalFeatures("OrchardCore.DataProtection.Azure"); +} + +if (builder.Configuration.GetValue("EnableRedisCache")) +{ + ocBuilder.AddSetupFeatures("OrchardCore.Redis", "OrchardCore.Redis.Lock") + .AddGlobalFeatures("OrchardCore.Redis", "OrchardCore.Redis.Cache", "OrchardCore.Redis.DataProtection", "OrchardCore.Redis.Lock"); +} + +if (builder.Configuration.GetValue("EnableAzureStorage")) +{ + ocBuilder.AddTenantFeatures("OrchardCore.Media.Azure.Storage"); +} + +var app = builder.Build(); + +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error"); +} + +app.UseStaticFiles(); + +app.UseOrchardCore(); + +await app.RunAsync(); diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/Properties/launchSettings.json b/src/Aspire/Aspire.OrchardCore.Cms.Web/Properties/launchSettings.json new file mode 100644 index 00000000000..448ea2ff178 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:23843", + "sslPort": 44303 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5084", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7179;http://localhost:5084", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/appsettings.Development.json b/src/Aspire/Aspire.OrchardCore.Cms.Web/appsettings.Development.json new file mode 100644 index 00000000000..0c208ae9181 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/Aspire/Aspire.OrchardCore.Cms.Web/appsettings.json b/src/Aspire/Aspire.OrchardCore.Cms.Web/appsettings.json new file mode 100644 index 00000000000..261a52e72a6 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Cms.Web/appsettings.json @@ -0,0 +1,17 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "EnableAzureCoreFeatures": false, + "EnableAzureStorage": false, + "EnableRedisCache": true, + "OrchardCore": { + "OrchardCore_Redis": { + "Configuration": "127.0.0.1:50963,allowAdmin=true", + "InstancePrefix": "" + } + } +} diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/Aspire.OrchardCore.Mvc.Web.csproj b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Aspire.OrchardCore.Mvc.Web.csproj new file mode 100644 index 00000000000..7a46d082b87 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Aspire.OrchardCore.Mvc.Web.csproj @@ -0,0 +1,19 @@ + + + + enable + enable + + + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/Models/ErrorViewModel.cs b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Models/ErrorViewModel.cs new file mode 100644 index 00000000000..41677d219d4 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Models/ErrorViewModel.cs @@ -0,0 +1,8 @@ +namespace Aspire.OrchardCore.Mvc.Web.Models; + +public class ErrorViewModel +{ + public string? RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); +} diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/Program.cs b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Program.cs new file mode 100644 index 00000000000..10957c770d8 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Program.cs @@ -0,0 +1,20 @@ +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); + +builder.Services + .AddOrchardCore() + .AddMvc(); + +var app = builder.Build(); + +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error"); +} + +app.UseStaticFiles(); + +app.UseOrchardCore(); + +await app.RunAsync(); diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/Properties/launchSettings.json b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Properties/launchSettings.json new file mode 100644 index 00000000000..f47de3dde58 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:41929", + "sslPort": 44395 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5287", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7244;http://localhost:5287", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/Shared/_Layout.cshtml b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/Shared/_Layout.cshtml new file mode 100644 index 00000000000..d550057bd4a --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/Shared/_Layout.cshtml @@ -0,0 +1,46 @@ + + + + + + @ViewData["Title"] - MvcSandbox + + + + + +
+ @RenderBody() +
+
+

© 2015 - MvcSandbox

+
+
+ + + + + @RenderSection("scripts", required: false) + + diff --git a/src/OrchardCore.Mvc.Web/_ViewImports.cshtml b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/_ViewImports.cshtml similarity index 100% rename from src/OrchardCore.Mvc.Web/_ViewImports.cshtml rename to src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/_ViewImports.cshtml diff --git a/src/OrchardCore.Mvc.Web/_ViewStart.cshtml b/src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/_ViewStart.cshtml similarity index 100% rename from src/OrchardCore.Mvc.Web/_ViewStart.cshtml rename to src/Aspire/Aspire.OrchardCore.Mvc.Web/Views/_ViewStart.cshtml diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/appsettings.Development.json b/src/Aspire/Aspire.OrchardCore.Mvc.Web/appsettings.Development.json new file mode 100644 index 00000000000..0c208ae9181 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/Aspire/Aspire.OrchardCore.Mvc.Web/appsettings.json b/src/Aspire/Aspire.OrchardCore.Mvc.Web/appsettings.json new file mode 100644 index 00000000000..9c0b05b1642 --- /dev/null +++ b/src/Aspire/Aspire.OrchardCore.Mvc.Web/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Sample": "Sample Value" +} diff --git a/src/Aspire/Aspire.ServiceDefaults/Aspire.ServiceDefaults.csproj b/src/Aspire/Aspire.ServiceDefaults/Aspire.ServiceDefaults.csproj new file mode 100644 index 00000000000..52455379fbd --- /dev/null +++ b/src/Aspire/Aspire.ServiceDefaults/Aspire.ServiceDefaults.csproj @@ -0,0 +1,25 @@ + + + + Library + enable + enable + true + + + + + + + + + + + + + + + + + + diff --git a/src/Aspire/Aspire.ServiceDefaults/Extensions.cs b/src/Aspire/Aspire.ServiceDefaults/Extensions.cs new file mode 100644 index 00000000000..c59308d50da --- /dev/null +++ b/src/Aspire/Aspire.ServiceDefaults/Extensions.cs @@ -0,0 +1,119 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +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.UseServiceDiscovery(); + }); + + 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.AddRuntimeInstrumentation() + .AddBuiltInMeters(); + }) + .WithTracing(tracing => + { + if (builder.Environment.IsDevelopment()) + { + // We want to view all traces in development + tracing.SetSampler(new AlwaysOnSampler()); + } + + tracing.AddAspNetCoreInstrumentation() + .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.Configure(logging => logging.AddOtlpExporter()); + builder.Services.ConfigureOpenTelemetryMeterProvider(metrics => metrics.AddOtlpExporter()); + builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter()); + } + + // Uncomment the following lines to enable the Prometheus exporter (requires the OpenTelemetry.Exporter.Prometheus.AspNetCore package) + // builder.Services.AddOpenTelemetry() + // .WithMetrics(metrics => metrics.AddPrometheusExporter()); + + // Uncomment the following lines to enable the Azure Monitor exporter (requires the Azure.Monitor.OpenTelemetry.Exporter package) + // 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) + { + // Uncomment the following line to enable the Prometheus endpoint (requires the OpenTelemetry.Exporter.Prometheus.AspNetCore package) + // app.MapPrometheusScrapingEndpoint(); + + // 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; + } + + private static MeterProviderBuilder AddBuiltInMeters(this MeterProviderBuilder meterProviderBuilder) => + meterProviderBuilder.AddMeter( + "Microsoft.AspNetCore.Hosting", + "Microsoft.AspNetCore.Server.Kestrel", + "System.Net.Http"); +} diff --git a/src/Aspire/Directory.Build.props b/src/Aspire/Directory.Build.props new file mode 100644 index 00000000000..77240662b47 --- /dev/null +++ b/src/Aspire/Directory.Build.props @@ -0,0 +1,13 @@ + + + + + net8.0 + enable + False + False + false + 612,618 + + + diff --git a/src/OrchardCore.Cms.Web/Program.cs b/src/OrchardCore.Cms.Web/Program.cs index 4b4d39392bd..f5e06716d21 100644 --- a/src/OrchardCore.Cms.Web/Program.cs +++ b/src/OrchardCore.Cms.Web/Program.cs @@ -19,4 +19,4 @@ app.UseOrchardCore(); -app.Run(); +await app.RunAsync(); diff --git a/src/OrchardCore.Cms.Web/wwwroot/.placeholder b/src/OrchardCore.Cms.Web/wwwroot/.placeholder index 46b134b197f..8b137891791 100644 --- a/src/OrchardCore.Cms.Web/wwwroot/.placeholder +++ b/src/OrchardCore.Cms.Web/wwwroot/.placeholder @@ -1 +1 @@ -ÿþ \ No newline at end of file + diff --git a/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/OrchardCore.Mvc.HelloWorld.csproj b/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/OrchardCore.Mvc.HelloWorld.csproj index c3c14a820a3..17cfec99d09 100644 --- a/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/OrchardCore.Mvc.HelloWorld.csproj +++ b/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/OrchardCore.Mvc.HelloWorld.csproj @@ -10,6 +10,22 @@ $(PackageTags) OrchardCoreFramework + + + + + + + + true + PreserveNewest + + + true + PreserveNewest + + + diff --git a/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/Views/_ViewImports.cshtml b/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/Views/_ViewImports.cshtml new file mode 100644 index 00000000000..a757b413b92 --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/Views/_ViewImports.cshtml @@ -0,0 +1 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/Views/_ViewStart.cshtml b/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/Views/_ViewStart.cshtml new file mode 100644 index 00000000000..2de62418c07 --- /dev/null +++ b/src/OrchardCore.Modules/OrchardCore.Mvc.HelloWorld/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "~/Views/Shared/_Layout.cshtml"; +} diff --git a/src/OrchardCore.Mvc.Web/Program.cs b/src/OrchardCore.Mvc.Web/Program.cs index d93a0dc32b3..785623cd759 100644 --- a/src/OrchardCore.Mvc.Web/Program.cs +++ b/src/OrchardCore.Mvc.Web/Program.cs @@ -15,4 +15,4 @@ app.UseOrchardCore(); -app.Run(); +await app.RunAsync(); diff --git a/src/OrchardCore.Mvc.Web/Views/_ViewImports.cshtml b/src/OrchardCore.Mvc.Web/Views/_ViewImports.cshtml new file mode 100644 index 00000000000..a757b413b92 --- /dev/null +++ b/src/OrchardCore.Mvc.Web/Views/_ViewImports.cshtml @@ -0,0 +1 @@ +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/src/OrchardCore.Mvc.Web/Views/_ViewStart.cshtml b/src/OrchardCore.Mvc.Web/Views/_ViewStart.cshtml new file mode 100644 index 00000000000..2de62418c07 --- /dev/null +++ b/src/OrchardCore.Mvc.Web/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "~/Views/Shared/_Layout.cshtml"; +} diff --git a/src/README.md b/src/README.md index 7f6d137faf0..799539d2d83 100644 --- a/src/README.md +++ b/src/README.md @@ -104,6 +104,11 @@ For more details on the various development tools we recommend for using with Or Docker images and parameters can be found at +### .NET Aspire + +The configuration of the OrchardCore solution is tailored for execution within the Aspire project. To initiate the Aspire project rather than the CMS directly, designate the `Aspire.AppHost` project as the startup project of the solution, then launch it. To run the Aspire project, [install .NET Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=visual-studio) on your local machine. Ensure you have Docker Desktop installed, and you are using Visual Studio version 17.9.0 or later + + ## Showcasing Orchard Core CMS