Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
s2quake committed Aug 14, 2024
1 parent f53400e commit 6ca1a1e
Show file tree
Hide file tree
Showing 17 changed files with 216 additions and 123 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Options.Schema;
using Microsoft.AspNetCore.Server.Kestrel.Core;

namespace Libplanet.Node.API.EntryPoints;

[Singleton<IApplicationEntryPoint>]
[Singleton<IApplicationBuilderEntryPoint>]
internal sealed class DefaultEntryPoint
: IApplicationEntryPoint, IApplicationBuilderEntryPoint
{
private const string HandlerMessage = """
Communication with gRPC endpoints must be made through a gRPC client. To learn how to
create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
""";

public void Run(WebApplicationBuilder builder)
{
builder.Logging.AddConsole();

if (builder.Environment.IsDevelopment())
{
builder.WebHost.ConfigureKestrel(options =>
{
// Setup a HTTP/2 endpoint without TLS.
options.ListenLocalhost(5259, o => o.Protocols =
HttpProtocols.Http1AndHttp2);
});
}
}

public async Task RunAsync(WebApplication app, CancellationToken cancellationToken)
{
var serviceProvider = app.Services;
var schema = await OptionsSchemaBuilder.GetSchemaAsync(cancellationToken);
app.MapGet("/", () => HandlerMessage);
app.MapGet("/schema", () => schema);
}
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
using Libplanet.Node.API.Options;
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Extensions;
using Libplanet.Node.Extensions.NodeBuilder;
using Microsoft.Extensions.Options;

namespace Libplanet.Node.API.EntryPoints;

[Singleton<IServiceEntryPoint>]
[Singleton<IApplicationBuilderEntryPoint>]
[Singleton<IApplicationEntryPoint>]
internal sealed class GrpcServiceEntryPoint(IOptions<GrpcOptions> options)
: IServiceEntryPoint, IApplicationEntryPoint
internal sealed class GrpcServiceEntryPoint(
IOptions<GrpcOptions> options, IWebHostEnvironment environment)
: IApplicationBuilderEntryPoint, IApplicationEntryPoint
{
private readonly GrpcOptions _options = options.Value;

public void Build(IEndpointRouteBuilder app, IWebHostEnvironment environment, string[] scopes)
public Task RunAsync(WebApplication app, CancellationToken cancellationToken)
{
app.MapGrpcServiceFromDomain(scopes);

var serviceProvider = app.Services;
var nodeBuilder = serviceProvider.GetRequiredService<ILibplanetNodeBuilder>();
app.MapGrpcServiceFromDomain(nodeBuilder.Scopes);
if (environment.IsDevelopment())
{
app.MapGrpcReflectionService().AllowAnonymous();
}

return Task.CompletedTask;
}

public void Run(IServiceCollection services, IWebHostEnvironment environment)
public void Run(WebApplicationBuilder builder)
{
if (_options.IsEnabled)
{
services.AddGrpc();
builder.Services.AddGrpc();

if (environment.IsDevelopment())
{
services.AddGrpcReflection();
builder.Services.AddGrpcReflection();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions sdk/node/Libplanet.Node.Executable/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global using Libplanet.Node.API;
62 changes: 62 additions & 0 deletions sdk/node/Libplanet.Node.Executable/NodeApplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Extensions;
using Libplanet.Node.Options;
using Microsoft.Extensions.Options;

namespace Libplanet.Node.API;

public sealed class NodeApplication : IAsyncDisposable
{
private readonly WebApplicationBuilder _builder;
private WebApplication? _app;

public NodeApplication(string[] args)
{
SynchronizationContext.SetSynchronizationContext(new());
var builder = WebApplication.CreateBuilder(args);
var nodeBuilder = builder.Services.AddLibplanetNode(builder.Configuration);
var serviceProvider = builder.Services.BuildServiceProvider();
var serviceEntryPoints
= serviceProvider.GetRequiredService<IEnumerable<IApplicationBuilderEntryPoint>>();
var nodeOptions = serviceProvider.GetRequiredService<IOptions<NodeOptions>>();
var seedOptionsMonitor = serviceProvider.GetRequiredService<IOptionsMonitor<SeedOptions>>();

foreach (var serviceEntryPoint in serviceEntryPoints)
{
serviceEntryPoint.Run(builder);
}

if (nodeOptions.Value.IsEnabled)
{
nodeBuilder.WithNode();
}

if (seedOptionsMonitor.Get(SeedOptions.BlocksyncSeed).IsEnabled)
{
nodeBuilder.WithBlocksyncSeed();
}

if (seedOptionsMonitor.Get(SeedOptions.ConsensusSeed).IsEnabled)
{
nodeBuilder.WithConsensusSeed();
}

_builder = builder;
}

public async ValueTask DisposeAsync()
{
if (_app is not null)
{
await _app.DisposeAsync();
_app = null;
}
}

public async Task RunAsync()
{
_app = _builder.Build();
await _app.RunEntryPointAsync(default);
await _app.RunAsync();
}
}
57 changes: 1 addition & 56 deletions sdk/node/Libplanet.Node.Executable/Program.cs
Original file line number Diff line number Diff line change
@@ -1,57 +1,2 @@
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Extensions;
using Libplanet.Node.Options.Schema;
using Microsoft.AspNetCore.Server.Kestrel.Core;

SynchronizationContext.SetSynchronizationContext(new());
var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();

if (builder.Environment.IsDevelopment())
{
builder.WebHost.ConfigureKestrel(options =>
{
// Setup a HTTP/2 endpoint without TLS.
options.ListenLocalhost(5259, o => o.Protocols =
HttpProtocols.Http1AndHttp2);
});
}

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS,
// visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.


// builder.Services.AddGrpc();
// builder.Services.AddGrpcReflection();
var libplanetBuilder = builder.Services.AddLibplanetNode(builder.Configuration)
.WithFlexible(builder.Environment);

var app = builder.Build();
var handlerMessage = """
Communication with gRPC endpoints must be made through a gRPC client. To learn how to
create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909
""";
var schema = await OptionsSchemaBuilder.GetSchemaAsync(default);
var applicationEntryPoints
= app.Services.GetRequiredService<IEnumerable<IApplicationEntryPoint>>();

foreach (var entryPoint in applicationEntryPoints)
{
entryPoint.Build(app, app.Environment, libplanetBuilder.Scopes);
}

// Configure the HTTP request pipeline.
// app.MapGrpcServiceFromDomain(libplanetBuilder.Scopes);
app.MapGet("/", () => handlerMessage);
app.MapGet("/schema", () => schema);

// if (builder.Environment.IsDevelopment())
// {
// app.MapGrpcReflectionService().AllowAnonymous();
// }

await using var app = new NodeApplication(args);
await app.RunAsync();
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ public static ILibplanetNodeBuilder AddLibplanetNode(
services.Configure<SoloProposeOption>(configuration.GetSection(SoloProposeOption.Position));
services.AddOptionsFromDomain(configuration);

return new LibplanetNodeBuilder(services, configuration);
var builder = new LibplanetNodeBuilder(services, configuration);
services.AddSingleton<ILibplanetNodeBuilder>(builder);

return builder;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace Libplanet.Node.Extensions.NodeBuilder;
Expand All @@ -18,6 +17,4 @@ public interface ILibplanetNodeBuilder
ILibplanetNodeBuilder WithBlocksyncSeed();

ILibplanetNodeBuilder WithConsensusSeed();

ILibplanetNodeBuilder WithFlexible(IWebHostEnvironment environment);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System.Reflection;
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Options;
using Libplanet.Node.Services;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
Expand All @@ -17,6 +18,7 @@ internal LibplanetNodeBuilder(IServiceCollection services, IConfiguration config
{
Services = services;
_configuration = configuration;
LoadPlugins();
Services.AddSingletonsFromDomain();
}

Expand Down Expand Up @@ -57,34 +59,24 @@ public ILibplanetNodeBuilder WithConsensusSeed()
return this;
}

public ILibplanetNodeBuilder WithFlexible(IWebHostEnvironment environment)
private void LoadPlugins()
{
var serviceProvider = Services.BuildServiceProvider();
var serviceEntryPoints
= serviceProvider.GetRequiredService<IEnumerable<IServiceEntryPoint>>();
var nodeOptions = serviceProvider.GetRequiredService<IOptions<NodeOptions>>();
var seedOptionsMonitor = serviceProvider.GetRequiredService<IOptionsMonitor<SeedOptions>>();
var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
?? throw new InvalidOperationException(
"Failed to get the directory of the current process.");
var files = Directory.GetFiles(directory, "Libplanet.Node.*.dll");

foreach (var serviceEntryPoint in serviceEntryPoints)
foreach (var file in files)
{
serviceEntryPoint.Run(Services, environment);
var filename = Path.GetFileNameWithoutExtension(file);
try
{
var assembly = Assembly.Load(filename);
}
catch
{
// Ignore the exception.
}
}

if (nodeOptions.Value.IsEnabled)
{
WithNode();
}

if (seedOptionsMonitor.Get(SeedOptions.BlocksyncSeed).IsEnabled)
{
WithBlocksyncSeed();
}

if (seedOptionsMonitor.Get(SeedOptions.ConsensusSeed).IsEnabled)
{
WithConsensusSeed();
}

return this;
}
}
6 changes: 0 additions & 6 deletions sdk/node/Libplanet.Node.Swagger/Class1.cs

This file was deleted.

41 changes: 41 additions & 0 deletions sdk/node/Libplanet.Node.Swagger/EntryPoints/SwaggerEntryPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Swagger.Options;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;

namespace Libplanet.Node.Swagger.EntryPoints;

[Singleton<IApplicationBuilderEntryPoint>]
[Singleton<IApplicationEntryPoint>]
internal sealed class SwaggerEntryPoint(
IOptions<SwaggerOptions> options, IWebHostEnvironment environment)
: IApplicationBuilderEntryPoint, IApplicationEntryPoint
{
private readonly SwaggerOptions _options = options.Value;

public Task RunAsync(WebApplication app, CancellationToken cancellationToken)
{
if (environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

return Task.CompletedTask;
}

public void Run(WebApplicationBuilder builder)
{
if (_options.IsEnabled)
{
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddAuthorization();
builder.Services.AddAuthentication("Bearer").AddJwtBearer();
}
}
}
3 changes: 3 additions & 0 deletions sdk/node/Libplanet.Node.Swagger/Libplanet.Node.Swagger.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.7.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions sdk/node/Libplanet.Node.Swagger/Options/SwaggerOptions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.ComponentModel;
using Libplanet.Node.DataAnnotations;
using Libplanet.Node.DependencyInjection;
using Libplanet.Node.Options;

Expand All @@ -11,5 +10,5 @@ public sealed class SwaggerOptions : OptionsBase<SwaggerOptions>
public const string Position = "Swagger";

[DefaultValue(true)]
public bool IsEnabled { get; set; }
public bool IsEnabled { get; set; } = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Microsoft.AspNetCore.Builder;

namespace Libplanet.Node.DependencyInjection;

public interface IApplicationBuilderEntryPoint
{
void Run(WebApplicationBuilder builder);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Builder;

namespace Libplanet.Node.DependencyInjection;

public interface IApplicationEntryPoint
{
void Build(IEndpointRouteBuilder app, IWebHostEnvironment environment, string[] scopes);
Task RunAsync(WebApplication app, CancellationToken cancellationToken);
}
Loading

0 comments on commit 6ca1a1e

Please sign in to comment.