Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #80 from petabridge/dev
Browse files Browse the repository at this point in the history
v0.4.0-rc2 release
  • Loading branch information
Aaronontheweb authored Mar 5, 2020
2 parents 89f5c93 + 22c2237 commit 58a5a2b
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 111 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ If you need any information on the supported commands, please execute the `build

This build script is powered by [FAKE](https://fake.build/); please see their API documentation should you need to make any changes to the [`build.fsx`](build.fsx) file.

This library is maintained by Petabridge®. Copyright 2018.
This library is maintained by Petabridge®. Copyright 2015-2020.
5 changes: 3 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#### 0.4.0-rc1 March 04 2020 ####
* Upgraded to Akka.NET v1.4.1-rc1 and used native environment variable substitution from HOCON
#### 0.4.0-rc2 March 05 2020 ####
* [Array handling rollback and improvements](https://github.com/petabridge/akkadotnet-bootstrap/pull/78)
* Restores startup and diagnostic logging from v0.2.2
96 changes: 78 additions & 18 deletions src/Akka.Bootstrap.Docker.Tests/DockerBootstrapSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Akka.Configuration;
using FluentAssertions;
using Xunit;
using Hocon;

namespace Akka.Bootstrap.Docker.Tests
{
Expand All @@ -28,9 +29,11 @@ public void ShouldStartIfValidSeedNodesIfSupplied(string seedNodes)
{
Environment.SetEnvironmentVariable("CLUSTER_SEEDS", seedNodes, EnvironmentVariableTarget.Process);
var myConfig = ConfigurationFactory.Empty.BootstrapFromDocker();
Config expected = $"array={seedNodes.ToProperHoconArray(true)}";

myConfig.HasPath("akka.cluster.seed-nodes").Should().BeTrue();
var seeds = myConfig.GetStringList("akka.cluster.seed-nodes").Select(x => x.Trim());
seeds.Should().BeEquivalentTo(seedNodes.Split(",").Select(x => x.Trim()));
var seeds = myConfig.GetStringList("akka.cluster.seed-nodes");
seeds.Should().BeEquivalentTo(expected.GetStringList("array"));
}
finally
{
Expand All @@ -39,6 +42,46 @@ public void ShouldStartIfValidSeedNodesIfSupplied(string seedNodes)
}
}

[Theory]
[InlineData("akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141")]
[InlineData("akka.tcp://MySys@localhost:9140, \"akka.tcp://MySys@localhost:9141\"")]
[InlineData("\"akka.tcp://MySys@localhost:9140\", akka.tcp://MySys@localhost:9141")]
[InlineData("[akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141]")]
[InlineData("[\"akka.tcp://MySys@localhost:9140\", \"akka.tcp://MySys@localhost:9141\"]")]
public void ToProperHoconArray_ShouldHandleAllPossibleInput(string input)
{
Config config = $"array={input.ToProperHoconArray(true)}";
config.GetStringList("array").Should().BeEquivalentTo(new[] { "akka.tcp://MySys@localhost:9140", "akka.tcp://MySys@localhost:9141" });
}

[Theory]
[InlineData("normal", "normal")]
[InlineData("nor.mal", "nor.mal")]
[InlineData("nor:-\\mal", "\"nor:-\\mal\"")]
[InlineData("nor:-\nmal", "\"\"\"nor:-\nmal\"\"\"")]
public void ToSafeHoconString_ShouldHandleAllPossibleInput(string input, string expected)
{
input.ToSafeHoconString().Should().Be(expected);
}

[Fact]
public void GetConfig_and_FromEnvironment_ShouldBeEqual()
{
try
{
Environment.SetEnvironmentVariable("CLUSTER_IP", "10.0.0.1", EnvironmentVariableTarget.Process);

var config1 = ConfigurationFactory.Empty.FromEnvironment();
var config2 = EnvironmentVariableConfigLoader.GetConfig();
config1.Should().Equals(config2);
}
finally
{
// clean the environment variable up afterwards
Environment.SetEnvironmentVariable("CLUSTER_IP", null);
}
}

[Theory]
[InlineData("localhost")]
[InlineData("127.0.0.1")]
Expand Down Expand Up @@ -87,23 +130,40 @@ public void ShouldStartNormallyIfNotEnvironmentVariablesAreSupplied()
[Fact]
public void ShouldStartIfValidAkkaConfigurationSuppliedByEnvironmentVariables()
{
Environment.SetEnvironmentVariable("AKKA__COORDINATED_SHUTDOWN__EXIT_CLR", "on", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__ACTOR__PROVIDER", "cluster", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__HOSTNAME", "127.0.0.1", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__PUBLIC_HOSTNAME", "example.local", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__PORT", "2559", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__0", "demo", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__1", "test", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__2", "backup", EnvironmentVariableTarget.Process);
try
{
Environment.SetEnvironmentVariable("AKKA__COORDINATED_SHUTDOWN__EXIT_CLR", "on", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__ACTOR__PROVIDER", "cluster", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__HOSTNAME", "127.0.0.1", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__PUBLIC_HOSTNAME", "example.local", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__PORT", "2559", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__0", "demo", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__1", "test", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__2", "backup", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("AKKA__ARRAY", "[demo, test, backup]", EnvironmentVariableTarget.Process);

var myConfig = ConfigurationFactory.Empty.BootstrapFromDocker();

myConfig.GetBoolean("akka.coordinated-shutdown.exit-clr").Should().BeTrue();
myConfig.GetString("akka.actor.provider").Should().Be("cluster");
myConfig.GetString("akka.remote.dot-netty.tcp.hostname").Should().Be("127.0.0.1");
myConfig.GetString("akka.remote.dot-netty.tcp.public-hostname").Should().Be("example.local");
myConfig.GetInt("akka.remote.dot-netty.tcp.port").Should().Be(2559);
myConfig.GetStringList("akka.cluster.roles").Should().BeEquivalentTo(new [] { "demo", "test", "backup" });
var myConfig = ConfigurationFactory.Empty.BootstrapFromDocker();

myConfig.GetBoolean("akka.coordinated-shutdown.exit-clr").Should().BeTrue();
myConfig.GetString("akka.actor.provider").Should().Be("cluster");
myConfig.GetString("akka.remote.dot-netty.tcp.hostname").Should().Be("127.0.0.1");
myConfig.GetString("akka.remote.dot-netty.tcp.public-hostname").Should().Be("example.local");
myConfig.GetInt("akka.remote.dot-netty.tcp.port").Should().Be(2559);
myConfig.GetStringList("akka.cluster.roles").Should().BeEquivalentTo(new[] { "demo", "test", "backup" });
myConfig.GetStringList("akka.array").Should().BeEquivalentTo(new[] { "demo", "test", "backup" });
}
finally
{
Environment.SetEnvironmentVariable("AKKA__COORDINATED_SHUTDOWN__EXIT_CLR", null);
Environment.SetEnvironmentVariable("AKKA__ACTOR__PROVIDER", null);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__HOSTNAME", null);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__PUBLIC_HOSTNAME", null);
Environment.SetEnvironmentVariable("AKKA__REMOTE__DOT_NETTY__TCP__PORT", null);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__0", null);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__1", null);
Environment.SetEnvironmentVariable("AKKA__CLUSTER__ROLES__2", null);
Environment.SetEnvironmentVariable("AKKA__ARRAY", null);
}
}
}
}
8 changes: 8 additions & 0 deletions src/Akka.Bootstrap.Docker/Akka.Bootstrap.Docker.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
<DocumentationFile>bin\Release\netstandard1.6\Akka.Bootstrap.Docker.xml</DocumentationFile>
</PropertyGroup>

<ItemGroup>
<None Remove="Docker.Environment.conf" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Docker.Environment.conf" />
</ItemGroup>


<ItemGroup>
<PackageReference Include="Akka" Version="$(AkkaVersion)" />
Expand Down
10 changes: 10 additions & 0 deletions src/Akka.Bootstrap.Docker/AssemblyMarker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Akka.Bootstrap.Docker
{
internal class AssemblyMarker
{
}
}
7 changes: 7 additions & 0 deletions src/Akka.Bootstrap.Docker/Docker.Environment.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
###############################################
# Docker Environment Variable Overrides #
###############################################

akka.remote.dot-netty.tcp.public-hostname = ${?CLUSTER_IP}
akka.remote.dot-netty.tcp.port = ${?CLUSTER_PORT}
environment.seed-nodes = ${?CLUSTER_SEEDS}
56 changes: 36 additions & 20 deletions src/Akka.Bootstrap.Docker/DockerBootstrap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
// -----------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Net;
using System.Text;
using Akka.Configuration;
Expand All @@ -23,6 +18,8 @@ namespace Akka.Bootstrap.Docker
/// </summary>
public static class DockerBootstrap
{
private const string DefaultConfigResource = "Akka.Bootstrap.Docker.Docker.Environment.conf";

/// <summary>
/// Extension method intended to chain configuration derived from
/// Docker-supplied environment variables to the front of the fallback chain,
Expand All @@ -38,21 +35,40 @@ public static class DockerBootstrap
/// </example>
public static Config BootstrapFromDocker(this Config input, bool assignDefaultHostName = true)
{
return ConfigurationFactory.Empty
.FromEnvironment()
.WithFallback(
ConfigurationFactory.ParseString(
$@"
akka.remote.dot-netty.tcp {{
hostname=0.0.0.0
public-hostname={Dns.GetHostName()}
}}
"
)
)
.WithFallback(
input
);
var environmentConfig = HoconConfigurationFactory.FromResource<AssemblyMarker>(DefaultConfigResource);

if(!environmentConfig.HasPath("akka.remote.dot-netty.tcp.public-hostname") && assignDefaultHostName)
Console.WriteLine($"[Docker-Bootstrap] Environment variable CLUSTER_IP was not set." +
$"Defaulting to local hostname [{Dns.GetHostName()}] for remote addressing.");

var defaultValues = new StringBuilder();
defaultValues.AppendLine("akka.remote.dot-netty.tcp.hostname=0.0.0.0");

if (assignDefaultHostName)
defaultValues.AppendLine($"akka.remote.dot-netty.tcp.public-hostname={Dns.GetHostName()}");

if (environmentConfig.HasPath("environment.seed-nodes"))
defaultValues.AppendLine(
$"akka.cluster.seed-nodes={environmentConfig.GetString("environment.seed-nodes").ToProperHoconArray(true)}");

var finalConfig = environmentConfig
.WithEnvironmentFallback()
.WithFallback(ConfigurationFactory.ParseString(defaultValues.ToString()))
.WithFallback(input);

Console.WriteLine($"[Docker-Bootstrap] IP={finalConfig.GetString("akka.remote.dot-netty.tcp.public-hostname")}");

if(finalConfig.HasPath("akka.remote.dot-netty.tcp.port"))
Console.WriteLine($"[Docker-Bootstrap] PORT={finalConfig.GetString("akka.remote.dot-netty.tcp.port")}");
else
Console.WriteLine($"[Docker-Bootstrap] PORT=0");

if(finalConfig.HasPath("akka.cluster.seed-nodes"))
Console.WriteLine($"[Docker-Bootstrap] SEEDS={finalConfig.GetStringList("akka.cluster.seed-nodes")}");
else
Console.WriteLine($"[Docker-Bootstrap] SEEDS=[]");

return finalConfig;
}
}
}
Loading

0 comments on commit 58a5a2b

Please sign in to comment.