diff --git a/src/Akka.Bootstrap.Docker.Tests/DockerBootstrapSpecs.cs b/src/Akka.Bootstrap.Docker.Tests/DockerBootstrapSpecs.cs index 30f68f7..9698c58 100644 --- a/src/Akka.Bootstrap.Docker.Tests/DockerBootstrapSpecs.cs +++ b/src/Akka.Bootstrap.Docker.Tests/DockerBootstrapSpecs.cs @@ -117,6 +117,73 @@ public void ShouldStartIfValidSeedNodesIfSupplied_Hardcoded(string seedNodes, st } } + [Theory] + [InlineData("[]", new string[0])] + [InlineData( + "[akka.tcp://MySys@localhost:9140]", + new[]{"akka.tcp://MySys@localhost:9140"})] + [InlineData( + "[akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141"})] + [InlineData( + "[akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141, akka.tcp://MySys@localhost:9142]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + // The whole line is quoted + [InlineData( + "[\"akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141, akka.tcp://MySys@localhost:9142\"]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + // The whole line is quoted with arbitrary whitespaces + [InlineData( + "[ \"akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141, akka.tcp://MySys@localhost:9142 \" ]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + // Every item is quoted + [InlineData( + "[\"akka.tcp://MySys@localhost:9140\", \"akka.tcp://MySys@localhost:9141\", \"akka.tcp://MySys@localhost:9142\"]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + // Only one item is quoted + [InlineData( + "[\"akka.tcp://MySys@localhost:9140\", akka.tcp://MySys@localhost:9141, akka.tcp://MySys@localhost:9142]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + // Only one item is quoted + [InlineData( + "[akka.tcp://MySys@localhost:9140, \"akka.tcp://MySys@localhost:9141\", akka.tcp://MySys@localhost:9142]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + // Only one item is quoted + [InlineData( + "[akka.tcp://MySys@localhost:9140, akka.tcp://MySys@localhost:9141, \"akka.tcp://MySys@localhost:9142\"]", + new[]{"akka.tcp://MySys@localhost:9140", + "akka.tcp://MySys@localhost:9141", + "akka.tcp://MySys@localhost:9142"})] + public void ShouldStartIfValidSeedNodesIfSuppliedInArrayFormat(string seedNodes, string[] expected) + { + try + { + Environment.SetEnvironmentVariable("CLUSTER_SEEDS", seedNodes, EnvironmentVariableTarget.Process); + var myConfig = ConfigurationFactory.Empty.BootstrapFromDocker(); + myConfig.HasPath("akka.cluster.seed-nodes").Should().BeTrue(); + var seeds = myConfig.GetStringList("akka.cluster.seed-nodes").Select(x => x.Trim()); + seeds.Should().BeEquivalentTo(expected); + } + finally + { + // clean the environment variable up afterwards + Environment.SetEnvironmentVariable("CLUSTER_SEEDS", null); + } + } + [Fact] public void ShouldStartIfValidSeedNodesIsSuppliedInIndexedFormat() { diff --git a/src/Akka.Bootstrap.Docker/EnvironmentVariableConfigLoader.cs b/src/Akka.Bootstrap.Docker/EnvironmentVariableConfigLoader.cs index d16b975..af4314d 100644 --- a/src/Akka.Bootstrap.Docker/EnvironmentVariableConfigLoader.cs +++ b/src/Akka.Bootstrap.Docker/EnvironmentVariableConfigLoader.cs @@ -82,12 +82,29 @@ private static IEnumerable GetEnvironmentV if (isList) { value = value.Trim(); - var values = new ListParser().Parse(value).ToArray(); + + string[] values; + try + { + values = new ListParser().Parse(value).ToArray(); + } + catch (Exception e) + { + throw new ConfigurationException($"Failed to parse list value [{value}]", e); + } + if (values.Length == 1) { // if the parser only returns a single value, // we might have a quoted environment variable - values = new ListParser().Parse(values[0]).ToArray(); + try + { + values = new ListParser().Parse(values[0]).ToArray(); + } + catch (Exception e) + { + throw new ConfigurationException($"Failed to parse list value [{values[0]}]", e); + } } // always assume that string needs to be quoted diff --git a/src/Akka.Bootstrap.Docker/ListParser.cs b/src/Akka.Bootstrap.Docker/ListParser.cs index ab459f5..0987262 100644 --- a/src/Akka.Bootstrap.Docker/ListParser.cs +++ b/src/Akka.Bootstrap.Docker/ListParser.cs @@ -122,6 +122,7 @@ private void ParseToken() _state = TokenizerState.AfterComma; // consume it and go on Consume(); + ConsumeConsecutiveWhiteSpaces(); break; } @@ -133,7 +134,7 @@ private void ParseToken() Consume(); ConsumeConsecutiveWhiteSpaces(); Peek(out eol); - if (!eol || _state != TokenizerState.AfterComma || _state != TokenizerState.EndOfString) + if (!eol || (_state != TokenizerState.AfterComma && _state != TokenizerState.EndOfString)) throw new ConfigurationException( $"Closing square brackets can only appear once at the end of the environment variable value. Position: [{bracketPosition}]"); break;