Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ WORKDIR /app
RUN adduser -u 5678 --disabled-password --gecos "" relay && chown -R relay /app

# Add .NET Diagnostic Counters
RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists && \
RUN apt-get update && apt-get install -y wget curl && rm -rf /var/lib/apt/lists && \
wget -O dotnet-counters https://aka.ms/dotnet-counters/linux-x64 && \
chmod +x dotnet-counters && \
apt purge wget --yes
Expand Down
86 changes: 63 additions & 23 deletions src/docker/Thinktecture.Relay.ManagementApi.Docker/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Serilog;
Expand All @@ -10,53 +13,63 @@
using Thinktecture.Relay.ManagementApi.Docker;
using Thinktecture.Relay.Server.Management;
using Thinktecture.Relay.Server.Management.Extensions;
using Thinktecture.Relay.Server.Persistence.EntityFrameworkCore;

try
{
const string applicationName = "ManagementApi";

var builder = WebApplication.CreateBuilder(args);

builder.Logging
.ClearProviders()
.AddSerilog(new LoggerConfiguration()
.MinimumLevel.Information()
.Destructure.With<StreamDestructuringPolicy>()
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", applicationName)
.ReadFrom.Configuration(builder.Configuration)
.WriteTo.Console()
.CreateBootstrapLogger()
builder
.Logging.ClearProviders()
.AddSerilog(
new LoggerConfiguration()
.MinimumLevel.Information()
.Destructure.With<StreamDestructuringPolicy>()
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", applicationName)
.ReadFrom.Configuration(builder.Configuration)
.WriteTo.Console()
.CreateBootstrapLogger()
);

// Register the db context, which in turn also registers the persistence services
builder.Services.AddRelayServerDbContext(builder.Configuration);

// Add health checks
builder.Services.AddHealthChecks().AddDbContextCheck<RelayDbContext>("database", tags: new[] { "ready" });

// Example: Add some authentication system, in this example we use api keys defined in the config file
builder.Services.AddAuthentication(ApiKeyAuthenticationDefaults.AuthenticationScheme)
.AddApiKey(ApiKeyAuthenticationDefaults.AuthenticationScheme, "Api Key", o =>
builder.Configuration.GetSection("Authentication:ApiKey").Bind(o));
builder
.Services.AddAuthentication(ApiKeyAuthenticationDefaults.AuthenticationScheme)
.AddApiKey(
ApiKeyAuthenticationDefaults.AuthenticationScheme,
"Api Key",
o => builder.Configuration.GetSection("Authentication:ApiKey").Bind(o)
);

// Example: Add policies and corresponding requirements for our chosen authentication
// Here we use the default policy names
builder.Services.AddAuthorization(o =>
{
o.AddPolicy(ManagementApiPolicyNames.Read, c =>
c.RequireClaim("managementapi", "read", "readwrite"));
o.AddPolicy(ManagementApiPolicyNames.Read, c => c.RequireClaim("managementapi", "read", "readwrite"));

o.AddPolicy(ManagementApiPolicyNames.Write, c =>
c.RequireClaim("managementapi", "write", "readwrite"));
o.AddPolicy(ManagementApiPolicyNames.Write, c => c.RequireClaim("managementapi", "write", "readwrite"));
});

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc(applicationName, new OpenApiInfo()
{
Version = "v1",
Title = "RelayServer Example Management API",
Description = "An example API to manage RelayServer configuration",
});
options.SwaggerDoc(
applicationName,
new OpenApiInfo()
{
Version = "v1",
Title = "RelayServer Example Management API",
Description = "An example API to manage RelayServer configuration",
}
);

options.EnableAnnotations();
});
Expand All @@ -67,6 +80,33 @@
app.UseAuthentication();
app.UseAuthorization();

// Map health check endpoints
app.MapHealthChecks(
"/health/live",
new HealthCheckOptions
{
Predicate = _ => false, // Liveness check - no dependencies
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync(report.Status == HealthStatus.Healthy ? "Healthy" : "Unhealthy");
},
}
);

app.MapHealthChecks(
"/health/ready",
new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("ready"), // Readiness check - includes database
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync(report.Status == HealthStatus.Healthy ? "Ready" : "Not Ready");
},
}
);

// This adds the default management api endpoints at the default paths ( /api/management/... )
// with the default authorization policies
app.UseRelayServerManagementEndpoints();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.13" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="7.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="8.0.2" />
Expand Down
16 changes: 14 additions & 2 deletions src/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ x-curl-defaults: &curl-defaults
<<: *defaults
image: alpine/curl
depends_on:
- relay-server-migrations
- relay-management-api
relay-server-migrations:
condition: service_completed_successfully
relay-management-api:
condition: service_healthy
configs:
- source: curl-headers
target: /headers
Expand Down Expand Up @@ -178,6 +180,12 @@ services:
<<: [*db-connection, *logging]
depends_on:
- relay-server-migrations
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:5000/health/ready || exit 1"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s

relay-seed-tenant1:
<<: *curl-defaults
Expand Down Expand Up @@ -253,6 +261,7 @@ services:
RelayConnector__TenantName: TestTenant1
depends_on:
- relay-server-a
- relay-seed-tenant1
relay-connector-a2:
<<: *defaults
image: relay-connector
Expand All @@ -264,6 +273,7 @@ services:
RelayConnector__TenantName: TestTenant2
depends_on:
- relay-server-a
- relay-seed-tenant2

relay-connector-b1:
<<: *defaults
Expand All @@ -276,6 +286,7 @@ services:
RelayConnector__TenantName: TestTenant1
depends_on:
- relay-server-b
- relay-seed-tenant1
relay-connector-b2:
<<: *defaults
image: relay-connector
Expand All @@ -287,6 +298,7 @@ services:
RelayConnector__TenantName: TestTenant2
depends_on:
- relay-server-b
- relay-seed-tenant2

volumes:
seq-data:
Expand Down