Skip to content

Commit 75fcd3c

Browse files
committed
Include ServicePulse frontend code into ServiceControl
1 parent b13b01d commit 75fcd3c

File tree

6 files changed

+137
-2
lines changed

6 files changed

+137
-2
lines changed

src/Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<PackageVersion Include="Particular.Licensing.Sources" Version="6.1.0" />
6262
<PackageVersion Include="Particular.LicensingComponent.Report" Version="1.0.0" />
6363
<PackageVersion Include="Particular.Obsoletes" Version="1.0.0" />
64+
<PackageVersion Include="Particular.PlatformSample.ServicePulse" Version="2.4.0" />
6465
<PackageVersion Include="Polly.Core" Version="8.5.2" />
6566
<PackageVersion Include="PropertyChanged.Fody" Version="4.1.0" />
6667
<PackageVersion Include="PropertyChanging.Fody" Version="1.30.3" />

src/ServiceControl/Hosting/Commands/RunCommand.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
namespace ServiceControl.Hosting.Commands
22
{
3+
using System;
4+
using System.IO;
5+
using System.Reflection;
36
using System.Threading.Tasks;
47
using Infrastructure.WebApi;
58
using Microsoft.AspNetCore.Builder;
9+
using Microsoft.Extensions.FileProviders;
610
using NServiceBus;
711
using Particular.ServiceControl;
812
using Particular.ServiceControl.Hosting;
@@ -23,8 +27,18 @@ public override async Task Execute(HostArguments args, Settings settings)
2327
hostBuilder.AddServiceControl(settings, endpointConfiguration);
2428
hostBuilder.AddServiceControlApi();
2529

30+
var servicePulsePath = Path.Combine(AppContext.BaseDirectory, "platform", "servicepulse", "ServicePulse.dll");
31+
var manifestEmbeddedFileProvider = new ManifestEmbeddedFileProvider(Assembly.LoadFrom(servicePulsePath), "wwwroot");
32+
var fileProvider = new CompositeFileProvider(hostBuilder.Environment.WebRootFileProvider, manifestEmbeddedFileProvider);
33+
var defaultFilesOptions = new DefaultFilesOptions { FileProvider = fileProvider };
34+
var staticFileOptions = new StaticFileOptions { FileProvider = fileProvider };
35+
2636
var app = hostBuilder.Build();
27-
app.UseServiceControl();
37+
app.UseServiceControl()
38+
.UseMiddleware<AppConstantsMiddleware>()
39+
.UseDefaultFiles(defaultFilesOptions)
40+
.UseStaticFiles(staticFileOptions);
41+
2842
await app.RunAsync(settings.RootUrl);
2943
}
3044
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
namespace ServiceControl.Infrastructure.WebApi
2+
{
3+
using System.Net.Mime;
4+
using System.Text.Json;
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Http;
7+
8+
class AppConstantsMiddleware
9+
{
10+
readonly RequestDelegate next;
11+
readonly string content;
12+
static AppConstantsMiddleware() => FileVersion = ServiceControlVersion.GetFileVersion();
13+
static readonly string FileVersion;
14+
15+
public AppConstantsMiddleware(RequestDelegate next)
16+
{
17+
this.next = next;
18+
19+
var settings = ServicePulseSettings.GetFromEnvironmentVariables();
20+
var constants = new
21+
{
22+
default_route = "/dashboard",
23+
service_control_url = "api/",
24+
monitoring_urls = new[] { settings.MonitoringUri.ToString() },
25+
showPendingRetry = settings.ShowPendingRetry,
26+
version = FileVersion,
27+
embedded = true
28+
};
29+
var options = new JsonSerializerOptions { PropertyNamingPolicy = null };
30+
31+
content = $"window.defaultConfig = {JsonSerializer.Serialize(constants, options)}";
32+
}
33+
34+
public async Task InvokeAsync(HttpContext context)
35+
{
36+
if (context.Request.Path.StartsWithSegments("/js/app.constants.js"))
37+
{
38+
context.Response.ContentType = MediaTypeNames.Text.JavaScript;
39+
40+
await context.Response.WriteAsync(content);
41+
return;
42+
}
43+
44+
await next(context);
45+
}
46+
}
47+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Text.Json;
3+
4+
class ServicePulseSettings
5+
{
6+
public required Uri MonitoringUri { get; init; }
7+
8+
public required string DefaultRoute { get; init; }
9+
10+
public required bool ShowPendingRetry { get; init; }
11+
12+
13+
public static ServicePulseSettings GetFromEnvironmentVariables()
14+
{
15+
var monitoringUrls = ParseLegacyMonitoringValue(Environment.GetEnvironmentVariable("MONITORING_URLS"));
16+
var monitoringUrl = Environment.GetEnvironmentVariable("MONITORING_URL");
17+
18+
monitoringUrl ??= monitoringUrls;
19+
monitoringUrl ??= "http://localhost:33633/";
20+
21+
var monitoringUri = monitoringUrl == "!" ? null : new Uri(monitoringUrl);
22+
var defaultRoute = Environment.GetEnvironmentVariable("DEFAULT_ROUTE") ?? "/dashboard";
23+
24+
var showPendingRetryValue = Environment.GetEnvironmentVariable("SHOW_PENDING_RETRY");
25+
bool.TryParse(showPendingRetryValue, out var showPendingRetry);
26+
27+
return new ServicePulseSettings
28+
{
29+
MonitoringUri = monitoringUri,
30+
DefaultRoute = defaultRoute,
31+
ShowPendingRetry = showPendingRetry,
32+
};
33+
}
34+
35+
static string ParseLegacyMonitoringValue(string value)
36+
{
37+
if (value is null)
38+
{
39+
return null;
40+
}
41+
42+
var cleanedValue = value.Replace('\'', '"');
43+
var json = $$"""{"Addresses":{{cleanedValue}}}""";
44+
45+
MonitoringUrls result;
46+
47+
try
48+
{
49+
result = JsonSerializer.Deserialize<MonitoringUrls>(json);
50+
}
51+
catch (JsonException)
52+
{
53+
return null;
54+
}
55+
56+
var addresses = result?.Addresses;
57+
58+
if (addresses is not null && addresses.Length > 0)
59+
{
60+
return addresses[0];
61+
}
62+
63+
return null;
64+
}
65+
66+
class MonitoringUrls
67+
{
68+
public string[] Addresses { get; set; } = [];
69+
}
70+
}

src/ServiceControl/ServiceControl.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<PackageReference Include="NServiceBus.CustomChecks" />
3333
<PackageReference Include="NServiceBus.Extensions.Hosting" />
3434
<PackageReference Include="NServiceBus.Extensions.Logging" />
35+
<PackageReference Include="Particular.PlatformSample.ServicePulse"/>
3536
<PackageReference Include="ServiceControl.Contracts" />
3637
<PackageReference Include="System.Reactive.Linq" />
3738
<PackageReference Include="Yarp.ReverseProxy" />

src/ServiceControl/WebApplicationExtensions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace ServiceControl;
77

88
public static class WebApplicationExtensions
99
{
10-
public static void UseServiceControl(this WebApplication app)
10+
public static IApplicationBuilder UseServiceControl(this WebApplication app)
1111
{
1212
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All });
1313
app.UseResponseCompression();
@@ -16,5 +16,7 @@ public static void UseServiceControl(this WebApplication app)
1616
app.MapHub<MessageStreamerHub>("/api/messagestream");
1717
app.UseCors();
1818
app.MapControllers();
19+
20+
return app;
1921
}
2022
}

0 commit comments

Comments
 (0)