Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/ServicePulse.Core/ServicePulse.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="8.0.17" />
<PackageReference Include="Particular.Packaging" Version="4.5.0" PrivateAssets="All" />
</ItemGroup>

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

<ItemGroup>
<EmbeddedResource Include="..\Frontend\dist\**\*" Exclude="..\Frontend\dist\js\**\*" LinkBase="wwwroot" />
</ItemGroup>

</Project>
80 changes: 80 additions & 0 deletions src/ServicePulse.Core/ServicePulseExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
namespace ServicePulse;

using System.Net.Mime;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.FileProviders;

/// <summary>
/// Extension methods for hosting a ServicePulse instance.
/// </summary>
public static class ServicePulseExtensions
{
/// <summary>
/// Adds ServicePulse static file hosting to the application builder.
/// </summary>
public static IApplicationBuilder UseServicePulse(this IApplicationBuilder app, IFileProvider? overrideFileProvider = null)
{
var embeddedFileProvider = new ManifestEmbeddedFileProvider(typeof(ServicePulseExtensions).Assembly, "wwwroot");

IFileProvider fileProvider = overrideFileProvider is null
? embeddedFileProvider
: new CompositeFileProvider(overrideFileProvider, embeddedFileProvider);

return app
.UseDefaultFiles(new DefaultFilesOptions
{
FileProvider = fileProvider
})
.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider
});
}

/// <summary>
/// Maps the ServicePulse constants endpoint.
/// Used to pass settings to the frontend application.
/// </summary>
public static IEndpointRouteBuilder MapServicePulseConstants(this IEndpointRouteBuilder app, ServicePulseSettings settings)
{
var constantsFile = GetConstantsFileContents(settings);

app.MapGet("/js/app.constants.js", (HttpContext context) =>
{
context.Response.ContentType = MediaTypeNames.Text.JavaScript;
return constantsFile;
});

return app;
}

static string GetConstantsFileContents(ServicePulseSettings settings)
=> $$"""
window.defaultConfig = {
default_route: '{{settings.DefaultRoute}}',
version: '{{GetVersionInformation()}}',
service_control_url: '{{settings.ServiceControlUrl}}',
monitoring_urls: ['{{settings.MonitoringUrl ?? "!"}}'],
showPendingRetry: {{(settings.ShowPendingRetry ? "true" : "false")}},
}
""";
static string GetVersionInformation()
{
var majorMinorPatch = "0.0.0";

var attributes = typeof(ServicePulseExtensions).Assembly.GetCustomAttributes<AssemblyMetadataAttribute>();

foreach (var attribute in attributes)
{
if (attribute.Key == "MajorMinorPatch")
{
majorMinorPatch = attribute.Value ?? "0.0.0";
}
}

return majorMinorPatch;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,35 @@

using System.Text.Json;

class Settings
/// <summary>
/// The runtime settings of a ServicePulse instance.
/// </summary>
public record ServicePulseSettings
{
public required Uri ServiceControlUri { get; init; }
/// <summary>
/// The default route to navigate to.
/// </summary>
public required string DefaultRoute { get; init; }

public required Uri? MonitoringUri { get; init; }
/// <summary>
/// The location of the ServiceControl API.
/// </summary>
public required string ServiceControlUrl { get; init; }

public required string DefaultRoute { get; init; }
/// <summary>
/// The location of the ServiceControl Monitoring API.
/// </summary>
public required string? MonitoringUrl { get; init; }

/// <summary>
/// Show the pending retry tab.
/// </summary>
public required bool ShowPendingRetry { get; init; }

public required bool EnableReverseProxy { get; init; }

public static Settings GetFromEnvironmentVariables()
/// <summary>
/// Loads the settings from environment variables.
/// </summary>
public static ServicePulseSettings GetFromEnvironmentVariables()
{
var serviceControlUrl = Environment.GetEnvironmentVariable("SERVICECONTROL_URL") ?? "http://localhost:33333/api/";

Expand Down Expand Up @@ -43,20 +59,12 @@ public static Settings GetFromEnvironmentVariables()
var showPendingRetryValue = Environment.GetEnvironmentVariable("SHOW_PENDING_RETRY");
bool.TryParse(showPendingRetryValue, out var showPendingRetry);

var enableReverseProxyValue = Environment.GetEnvironmentVariable("ENABLE_REVERSE_PROXY");

if (!bool.TryParse(enableReverseProxyValue, out var enableReverseProxy))
{
enableReverseProxy = true;
}

return new Settings
return new()
{
ServiceControlUri = serviceControlUri,
MonitoringUri = monitoringUri,
ServiceControlUrl = serviceControlUri.ToString(),
MonitoringUrl = monitoringUri?.ToString(),
DefaultRoute = defaultRoute,
ShowPendingRetry = showPendingRetry,
EnableReverseProxy = enableReverseProxy
ShowPendingRetry = showPendingRetry
};
}

Expand Down Expand Up @@ -95,4 +103,4 @@ class MonitoringUrls
{
public string[] Addresses { get; set; } = [];
}
}
}
10 changes: 8 additions & 2 deletions src/ServicePulse.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32319.34
# Visual Studio Version 18
VisualStudioVersion = 18.1.11312.151 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServicePulse.Host", "ServicePulse.Host\ServicePulse.Host.csproj", "{D120B791-BD1B-4E06-B4E1-69801A73209B}"
EndProject
Expand Down Expand Up @@ -36,6 +36,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePulse", "ServicePulse\ServicePulse.csproj", "{084808CF-4B93-4097-BFA1-2604AA7B4594}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServicePulse.Core", "ServicePulse.Core\ServicePulse.Core.csproj", "{51B99A95-FD20-4B5F-A460-0A1D589BE9F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -88,6 +90,10 @@ Global
{084808CF-4B93-4097-BFA1-2604AA7B4594}.Debug|Any CPU.Build.0 = Debug|Any CPU
{084808CF-4B93-4097-BFA1-2604AA7B4594}.Release|Any CPU.ActiveCfg = Release|Any CPU
{084808CF-4B93-4097-BFA1-2604AA7B4594}.Release|Any CPU.Build.0 = Release|Any CPU
{51B99A95-FD20-4B5F-A460-0A1D589BE9F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51B99A95-FD20-4B5F-A460-0A1D589BE9F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51B99A95-FD20-4B5F-A460-0A1D589BE9F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51B99A95-FD20-4B5F-A460-0A1D589BE9F9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
54 changes: 0 additions & 54 deletions src/ServicePulse/ConstantsFile.cs

This file was deleted.

29 changes: 7 additions & 22 deletions src/ServicePulse/Program.cs
Original file line number Diff line number Diff line change
@@ -1,39 +1,24 @@
using System.Net.Mime;
using Microsoft.Extensions.FileProviders;
using ServicePulse;

var builder = WebApplication.CreateBuilder(args);

var settings = Settings.GetFromEnvironmentVariables();
var hostSettings = ServicePulseHostSettings.GetFromEnvironmentVariables();
var servicePulseSettings = ServicePulseSettings.GetFromEnvironmentVariables();

if (settings.EnableReverseProxy)
if (hostSettings.EnableReverseProxy)
{
var (routes, clusters) = ReverseProxy.GetConfiguration(settings);
builder.Services.AddReverseProxy().LoadFromMemory(routes, clusters);
builder.Services.AddServicePulseReverseProxy(ref servicePulseSettings);
}

var app = builder.Build();

var manifestEmbeddedFileProvider = new ManifestEmbeddedFileProvider(typeof(Program).Assembly, "wwwroot");
var fileProvider = new CompositeFileProvider(builder.Environment.WebRootFileProvider, manifestEmbeddedFileProvider);
app.UseServicePulse(builder.Environment.ContentRootFileProvider);

var defaultFilesOptions = new DefaultFilesOptions { FileProvider = fileProvider };
app.UseDefaultFiles(defaultFilesOptions);

var staticFileOptions = new StaticFileOptions { FileProvider = fileProvider };
app.UseStaticFiles(staticFileOptions);

if (settings.EnableReverseProxy)
if (hostSettings.EnableReverseProxy)
{
app.MapReverseProxy();
}

var constantsFile = ConstantsFile.GetContent(settings);

app.MapGet("/js/app.constants.js", (HttpContext context) =>
{
context.Response.ContentType = MediaTypeNames.Text.JavaScript;
return constantsFile;
});
app.MapServicePulseConstants(servicePulseSettings);

app.Run();
Loading