Skip to content

Commit

Permalink
Restructure backend/endpoint config, config reload #9 (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tratcher authored Apr 10, 2020
1 parent bc92983 commit 61055e1
Show file tree
Hide file tree
Showing 28 changed files with 217 additions and 564 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ csharp_using_directive_placement = outside_namespace:error

# New-line options
# https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-formatting-conventions?view=vs-2019#new-line-options
csharp_new_line_before_open_brace = methods, properties, control_blocks, types
csharp_new_line_before_open_brace = methods, properties, control_blocks, types, anonymous_methods, lambdas
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
Expand Down
24 changes: 24 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,26 @@ Additional feedback: Why is it using arrays instead of objects? These items are
},
```

Update: The backend and endpoint layout has been modified to the following:
```
"Backends": {
"backend1": {
"Endpoints": {
"backend1/endpoint1": {
"Address": "https://localhost:10000/"
}
}
},
"backend2": {
"Endpoints": {
"backend2/endpoint1": {
"Address": "https://localhost:10001/"
}
}
}
},
```

## Config reloading

Expand All @@ -158,6 +178,10 @@ Config reload for proxy routes, backends, and endpoints already works. You edit

Also, when a kestrel endpoint is modified or removed should existing connections on that endpoint be eagerly drained and closed, or should they be allowed to run a normal lifecycle? Kestrel does not currently track active connection per endpoint so additional tracking would be needed if we wanted to shut them down.

Updates:

The config reload code has been moved from the sample into the product assemblies.

## Augmenting config via code

Some things are easier to do in code and we want to be able to support that while still pulling more transient data from config. [Kestrel](https://github.com/dotnet/aspnetcore/blob/aff01ebd7f82d641a4cfbd4a34954300311d9c2b/src/Servers/Kestrel/samples/SampleApp/Startup.cs#L138-L147) has a model where endpoints are named in config and then can be reference by name in code for additional configuration.
Expand Down
25 changes: 0 additions & 25 deletions samples/ReverseProxy.Sample/Config/ProxyConfigRoot.cs

This file was deleted.

16 changes: 0 additions & 16 deletions samples/ReverseProxy.Sample/Config/StaticDiscoveryOptions.cs

This file was deleted.

8 changes: 1 addition & 7 deletions samples/ReverseProxy.Sample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.ReverseProxy.Core.Configuration.DependencyInjection;
using Microsoft.ReverseProxy.Sample.Config;

namespace Microsoft.ReverseProxy.Sample
{
Expand All @@ -30,12 +29,7 @@ public Startup(IConfiguration configuration)
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddReverseProxy();

// The following 2 lines are all that we need to react to config changes on the fly.
// You can then change appsettings.json on disk and we will apply the new configs without a restart.
services.Configure<ProxyConfigRoot>(_configuration.GetSection("ReverseProxy"));
services.AddHostedService<ProxyConfigApplier>();
services.AddReverseProxy().LoadFromConfig(_configuration.GetSection("ReverseProxy"), reloadOnChange: true);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion samples/ReverseProxy.Sample/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Logging": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Warning",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
Expand Down
44 changes: 22 additions & 22 deletions samples/ReverseProxy.Sample/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,32 @@
}
},
"ReverseProxy": {
"DiscoveryMechanism": "static",
"StaticDiscoveryOptions": {
"Backends": [
{
"BackendId": "backend1"
}
],
"Endpoints": {
"backend1": [
{
"EndpointId": "backend1/endpoint1",
"Backends": {
"backend1": {
"Endpoints": {
"backend1/endpoint1": {
"Address": "https://localhost:10000/"
}
]
}
},
"Routes": [
{
"RouteId": "backend1/route1",
"BackendId": "backend1",
"Match": {
"Methods": [ "GET", "POST" ],
"Host": "localhost",
"Path": "/{**catchall}"
"backend2": {
"Endpoints": {
"backend2/endpoint1": {
"Address": "https://localhost:10001/"
}
}
]
}
}
},
"Routes": [
{
"RouteId": "backend1/route1",
"BackendId": "backend1",
"Match": {
"Methods": [ "GET", "POST" ],
"Host": "localhost",
"Path": "/{**catchall}"
}
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,8 @@ namespace Microsoft.ReverseProxy.Core.Abstractions
/// by proxying to any endpoint within the matching backend,
/// honoring load balancing and partitioning policies when applicable.
/// </summary>
/// <remarks>
/// When proxying to Service Fabric services, a <see cref="Backend"/> will generally correspond to a Serice Fabric service instance,
/// and the backend endpoints correspond to the endpoints of the replicas of said service.
/// </remarks>
public sealed class Backend : IDeepCloneable<Backend>
{
/// <summary>
/// Unique identifier of this backend. No other backend may specify the same value.
/// </summary>
public string BackendId { get; set; }

/// <summary>
/// Circuit breaker options.
/// </summary>
Expand All @@ -48,6 +39,11 @@ public sealed class Backend : IDeepCloneable<Backend>
/// </summary>
public HealthCheckOptions HealthCheckOptions { get; set; }

/// <summary>
/// The set of backend endpoints associated with this backend.
/// </summary>
public IDictionary<string, BackendEndpoint> Endpoints { get; private set; } = new Dictionary<string, BackendEndpoint>(StringComparer.Ordinal);

/// <summary>
/// Arbitrary key-value pairs that further describe this backend.
/// </summary>
Expand All @@ -58,12 +54,12 @@ Backend IDeepCloneable<Backend>.DeepClone()
{
return new Backend
{
BackendId = BackendId,
CircuitBreakerOptions = CircuitBreakerOptions?.DeepClone(),
QuotaOptions = QuotaOptions?.DeepClone(),
PartitioningOptions = PartitioningOptions?.DeepClone(),
LoadBalancingOptions = LoadBalancingOptions?.DeepClone(),
HealthCheckOptions = HealthCheckOptions?.DeepClone(),
Endpoints = Endpoints.DeepClone(StringComparer.Ordinal),
Metadata = Metadata?.DeepClone(StringComparer.Ordinal),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ public interface IBackendsRepo
/// <summary>
/// Gets the current set of backends.
/// </summary>
Task<IList<Backend>> GetBackendsAsync(CancellationToken cancellation);
Task<IDictionary<string, Backend>> GetBackendsAsync(CancellationToken cancellation);

/// <summary>
/// Sets the current set of backends.
/// </summary>
Task SetBackendsAsync(IList<Backend> backends, CancellationToken cancellation);
Task SetBackendsAsync(IDictionary<string, Backend> backends, CancellationToken cancellation);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
Expand All @@ -11,11 +11,6 @@ namespace Microsoft.ReverseProxy.Core.Abstractions
/// </summary>
public sealed class BackendEndpoint : IDeepCloneable<BackendEndpoint>
{
/// <summary>
/// Unique identifier of this endpoint. This must be globally unique.
/// </summary>
public string EndpointId { get; set; }

/// <summary>
/// Address of this endpoint. E.g. <c>https://127.0.0.1:123/abcd1234/</c>.
/// </summary>
Expand All @@ -31,7 +26,6 @@ BackendEndpoint IDeepCloneable<BackendEndpoint>.DeepClone()
{
return new BackendEndpoint
{
EndpointId = EndpointId,
Address = Address,
Metadata = Metadata?.DeepClone(StringComparer.Ordinal),
};
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public static IReverseProxyBuilder AddMetrics(this IReverseProxyBuilder builder)
public static IReverseProxyBuilder AddInMemoryRepos(this IReverseProxyBuilder builder)
{
builder.Services.AddSingleton<IBackendsRepo, InMemoryBackendsRepo>();
builder.Services.AddSingleton<IBackendEndpointsRepo, InMemoryEndpointsRepo>();
builder.Services.AddSingleton<IRoutesRepo, InMemoryRoutesRepo>();

return builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.ReverseProxy.Core.Configuration.DependencyInjection
Expand Down Expand Up @@ -30,5 +31,21 @@ public static IReverseProxyBuilder AddReverseProxy(this IServiceCollection servi

return builder;
}

/// <summary>
/// Loads routes and endpoints from config.
/// </summary>
/// <param name="builder"></param>
/// <param name="config"></param>
/// <param name="reloadOnChange"></param>
/// <returns></returns>
public static IReverseProxyBuilder LoadFromConfig(this IReverseProxyBuilder builder, IConfiguration config, bool reloadOnChange = true)
{
builder.Services.Configure<ProxyConfigOptions>(config);
builder.Services.Configure<ProxyConfigOptions>(options => options.ReloadOnChange = reloadOnChange);
builder.Services.AddHostedService<ProxyConfigLoader>();

return builder;
}
}
}
Loading

0 comments on commit 61055e1

Please sign in to comment.