-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Akka.Discovery.Config.Hosting (#1758)
* Add Akka.Discovery.Config.Hosting * Move Discovery.Config into Akka.Management project --------- Co-authored-by: Aaron Stannard <aaron@petabridge.com>
- Loading branch information
1 parent
7f0452a
commit 2bf82db
Showing
9 changed files
with
581 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/management/Akka.Management.Tests/Discovery/Config/ConfigServiceConfigSpec.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="ConfigServiceConfigSpec.cs" company="Akka.NET Project"> | ||
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net> | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using Akka.Discovery.Config; | ||
using Akka.Discovery.Config.Hosting; | ||
using Akka.Hosting; | ||
using FluentAssertions; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Xunit; | ||
|
||
namespace Akka.Management.Tests.Discovery.Config; | ||
|
||
public class ConfigServiceConfigSpec | ||
{ | ||
[Fact(DisplayName = "ConfigServiceDiscoveryOptions should generate proper HOCON config")] | ||
public void OptionsShouldGenerateHoconConfig() | ||
{ | ||
var builder = new AkkaConfigurationBuilder(new ServiceCollection(), "") | ||
.WithConfigDiscovery(new ConfigServiceDiscoveryOptions | ||
{ | ||
Services = new List<Service> | ||
{ | ||
new Service | ||
{ | ||
Name = "Test", | ||
Endpoints = new[] { "abc:1", "def:2" } | ||
} | ||
} | ||
}); | ||
var systemConfig = builder.Configuration.Value; | ||
var config = systemConfig.GetConfig(ConfigServiceDiscoveryOptions.FullPath); | ||
|
||
Type.GetType(config.GetString("class")).Should().Be(typeof(ConfigServiceDiscovery)); | ||
config.GetString("services-path").Should().Be("akka.discovery.config.services"); | ||
config.GetStringList("services.Test.endpoints").Should().BeEquivalentTo("abc:1", "def:2"); | ||
} | ||
} |
172 changes: 172 additions & 0 deletions
172
src/management/Akka.Management.Tests/Discovery/Config/End2End/ConfigServiceSpec.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="ConfigServiceSpec.cs" company="Akka.NET Project"> | ||
// Copyright (C) 2009-2023 Lightbend Inc. <http://www.lightbend.com> | ||
// Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net> | ||
// </copyright> | ||
// ----------------------------------------------------------------------- | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
using Akka.Actor; | ||
using Akka.Cluster.Hosting; | ||
using Akka.Discovery.Config.Hosting; | ||
using Akka.Hosting; | ||
using Akka.Management.Cluster.Bootstrap; | ||
using Akka.Remote.Hosting; | ||
using Akka.Util; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Extensions.Logging; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
namespace Akka.Management.Tests.Discovery.Config.End2End; | ||
|
||
public class ConfigServiceSpec: Akka.Hosting.TestKit.TestKit | ||
{ | ||
private const int ClusterNodeCount = 3; | ||
|
||
private readonly AtomicBoolean _clusterFormed = new (); | ||
private readonly int[] _remotingPorts = new int[ClusterNodeCount]; | ||
private readonly int[] _managementPorts = new int[ClusterNodeCount]; | ||
private readonly string[] _managementEndpoints = new string[ClusterNodeCount]; | ||
|
||
private IHost? _host1; | ||
private IHost? _host2; | ||
private ActorSystem? _sys1; | ||
private ActorSystem? _sys2; | ||
|
||
public ConfigServiceSpec(ITestOutputHelper output) : base(nameof(ConfigServiceSpec), output) | ||
{ | ||
var rnd = new Random(); | ||
var port = rnd.Next(30000, 40000); | ||
for (var i = 0; i < ClusterNodeCount; i++) | ||
{ | ||
_remotingPorts[i] = port; | ||
port++; | ||
_managementPorts[i] = port; | ||
_managementEndpoints[i] = $"127.0.0.1:{port}"; | ||
port++; | ||
} | ||
} | ||
|
||
#region Test Setup | ||
|
||
private async Task<IHost> StartAkkaHost(int index) | ||
{ | ||
var hostBuilder = new HostBuilder(); | ||
hostBuilder | ||
.ConfigureLogging(logger => | ||
{ | ||
logger.ClearProviders(); | ||
logger.AddProvider(new XUnitLoggerProvider(Output!, LogLevel)); | ||
logger.AddFilter("Akka.*", LogLevel); | ||
}) | ||
.ConfigureServices((_, services) => | ||
{ | ||
services.AddAkka(nameof(ConfigServiceSpec), (builder, _) => | ||
{ | ||
AddConfigDiscovery(builder, index); | ||
}); | ||
}); | ||
var host = hostBuilder.Build(); | ||
await host.StartAsync(); | ||
|
||
return host; | ||
} | ||
|
||
private AkkaConfigurationBuilder AddConfigDiscovery(AkkaConfigurationBuilder builder, int index) | ||
{ | ||
var port = _remotingPorts[index]; | ||
var managementPort = _managementPorts[index]; | ||
|
||
return builder | ||
.WithRemoting(options => | ||
{ | ||
options.Port = port; | ||
options.HostName = "localhost"; | ||
}) | ||
.WithClustering(new ClusterOptions | ||
{ | ||
MinimumNumberOfMembers = 3 | ||
}) | ||
.WithClusterBootstrap( | ||
requiredContactPoints:3, | ||
serviceName:"LocalService", | ||
// NOTE: this is needed to prevent cluster bootstrap from filtering out multiple result from a single domain name | ||
portName:"port") | ||
.WithAkkaManagement( | ||
hostName:"127.0.0.1", | ||
port: managementPort, | ||
bindHostname:"127.0.0.1", | ||
bindPort:managementPort, | ||
autoStart:true) | ||
.WithConfigDiscovery(opt => | ||
{ | ||
opt.Services.Add(new Service | ||
{ | ||
Name = "LocalService", | ||
Endpoints = _managementEndpoints | ||
}); | ||
}) | ||
.WithConfigDiscovery(new ConfigServiceDiscoveryOptions | ||
{ | ||
Services = new List<Service> | ||
{ | ||
new Service | ||
{ | ||
Name = "LocalService", | ||
Endpoints = _managementEndpoints | ||
} | ||
} | ||
}); | ||
} | ||
|
||
protected override void ConfigureAkka(AkkaConfigurationBuilder builder, IServiceProvider provider) | ||
{ | ||
AddConfigDiscovery(builder, 0) | ||
.AddStartup((system, _) => | ||
{ | ||
var cluster = Akka.Cluster.Cluster.Get(system); | ||
cluster.RegisterOnMemberUp(() => | ||
{ | ||
_clusterFormed.CompareAndSet(false, true); | ||
}); | ||
}); | ||
} | ||
|
||
protected override async Task BeforeTestStart() | ||
{ | ||
await base.BeforeTestStart(); | ||
_host1 = await StartAkkaHost(1); | ||
_sys1 = _host1.Services.GetRequiredService<ActorSystem>(); | ||
_host2 = await StartAkkaHost(2); | ||
_sys2 = _host2.Services.GetRequiredService<ActorSystem>(); | ||
Output!.WriteLine("Systems started"); | ||
} | ||
|
||
protected override async Task AfterAllAsync() | ||
{ | ||
await base.AfterAllAsync(); | ||
|
||
var tasks = new List<Task>(); | ||
if (_sys1 is not null) | ||
tasks.Add(_sys1.Terminate()); | ||
if(_sys2 is not null) | ||
tasks.Add(_sys2.Terminate()); | ||
await Task.WhenAll(tasks); | ||
|
||
_host1?.Dispose(); | ||
_host2?.Dispose(); | ||
} | ||
|
||
#endregion | ||
|
||
|
||
[Fact(DisplayName = "Cluster should form")] | ||
public async Task ClusterFormingSpec() | ||
{ | ||
await AwaitConditionAsync(() => Task.FromResult(_clusterFormed.Value), max:TimeSpan.FromSeconds(30)); | ||
} | ||
} |
Oops, something went wrong.