Files
CBDDC/samples/ZB.MOM.WW.CBDDC.Sample.Console/Program.cs

127 lines
4.8 KiB
C#
Executable File

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ZB.MOM.WW.CBDDC.Core;
using ZB.MOM.WW.CBDDC.Core.Storage;
using ZB.MOM.WW.CBDDC.Core.Cache;
using ZB.MOM.WW.CBDDC.Core.Sync;
using ZB.MOM.WW.CBDDC.Core.Diagnostics;
using ZB.MOM.WW.CBDDC.Core.Resilience;
using ZB.MOM.WW.CBDDC.Network;
using ZB.MOM.WW.CBDDC.Network.Security;
using ZB.MOM.WW.CBDDC.Persistence.BLite;
using ZB.MOM.WW.CBDDC.Sample.Console;
using Microsoft.Extensions.Hosting;
using Serilog;
using ZB.MOM.WW.CBDDC.Core.Network;
namespace ZB.MOM.WW.CBDDC.Sample.Console;
// Local User/Address classes removed in favor of Shared project
class Program
{
static async Task Main(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
// Configuration
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
// Logging
builder.Logging.ClearProviders();
builder.Services.AddSerilog((_, loggerConfiguration) =>
loggerConfiguration
.MinimumLevel.Information()
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", "CBDDC.Sample.Console")
.WriteTo.Console());
var randomPort = new Random().Next(1000, 9999);
// Node ID
string nodeId = args.Length > 0 ? args[0] : ("node-" + randomPort);
int tcpPort = args.Length > 1 ? int.Parse(args[1]) : randomPort;
// Conflict Resolution Strategy (can be switched at runtime via service replacement)
var useRecursiveMerge = args.Contains("--merge");
if (useRecursiveMerge)
{
builder.Services.AddSingleton<IConflictResolver, RecursiveNodeMergeConflictResolver>();
}
IPeerNodeConfigurationProvider peerNodeConfigurationProvider = new StaticPeerNodeConfigurationProvider(
new PeerNodeConfiguration
{
NodeId = nodeId,
TcpPort = tcpPort,
AuthToken = "Test-Cluster-Key",
//KnownPeers = builder.Configuration.GetSection("CBDDC:KnownPeers").Get<List<KnownPeerConfiguration>>() ?? new()
});
builder.Services.AddSingleton<IPeerNodeConfigurationProvider>(peerNodeConfigurationProvider);
// Database path
var dataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "data");
Directory.CreateDirectory(dataPath);
var databasePath = Path.Combine(dataPath, $"{nodeId}.blite");
// Register CBDDC Services using Fluent Extensions with BLite, SampleDbContext, and SampleDocumentStore
builder.Services.AddCBDDCCore()
.AddCBDDCBLite<SampleDbContext, SampleDocumentStore>(sp => new SampleDbContext(databasePath))
.AddCBDDCNetwork<StaticPeerNodeConfigurationProvider>(); // useHostedService = true by default
builder.Services.AddHostedService<ConsoleInteractiveService>(); // Runs the Input Loop
var host = builder.Build();
System.Console.WriteLine($"? Node {nodeId} initialized on port {tcpPort}");
System.Console.WriteLine($"? Database: {databasePath}");
System.Console.WriteLine();
await host.RunAsync();
}
private class StaticPeerNodeConfigurationProvider : IPeerNodeConfigurationProvider
{
/// <summary>
/// Gets or sets the current peer node configuration.
/// </summary>
public PeerNodeConfiguration Configuration { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="StaticPeerNodeConfigurationProvider"/> class.
/// </summary>
/// <param name="configuration">The initial peer node configuration.</param>
public StaticPeerNodeConfigurationProvider(PeerNodeConfiguration configuration)
{
Configuration = configuration;
}
/// <summary>
/// Occurs when the peer node configuration changes.
/// </summary>
public event PeerNodeConfigurationChangedEventHandler? ConfigurationChanged;
/// <summary>
/// Gets the current peer node configuration.
/// </summary>
/// <returns>A task that returns the current configuration.</returns>
public Task<PeerNodeConfiguration> GetConfiguration()
{
return Task.FromResult(Configuration);
}
/// <summary>
/// Raises the configuration changed event.
/// </summary>
/// <param name="newConfig">The new configuration value.</param>
protected virtual void OnConfigurationChanged(PeerNodeConfiguration newConfig)
{
ConfigurationChanged?.Invoke(this, newConfig);
}
}
}