diff --git a/.appveyor.yml b/.appveyor.yml
index 66b036c..8295fc9 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -21,7 +21,7 @@ artifacts:
environment:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_CLI_TELEMETRY_OPTOUT: 1
- ProjectList: Steeltoe.Extensions.Configuration.CloudFoundryBase Steeltoe.Extensions.Configuration.PlaceholderBase Steeltoe.Extensions.Configuration.ConfigServerBase Steeltoe.Extensions.Configuration.CloudFoundryCore Steeltoe.Extensions.Configuration.CloudFoundryAutofac Steeltoe.Extensions.Configuration.PlaceholderCore Steeltoe.Extensions.Configuration.ConfigServerCore Steeltoe.Extensions.Configuration.ConfigServerAutofac
+ ProjectList: Steeltoe.Extensions.Configuration.RandomValueBase Steeltoe.Extensions.Configuration.CloudFoundryBase Steeltoe.Extensions.Configuration.PlaceholderBase Steeltoe.Extensions.Configuration.ConfigServerBase Steeltoe.Extensions.Configuration.CloudFoundryCore Steeltoe.Extensions.Configuration.CloudFoundryAutofac Steeltoe.Extensions.Configuration.PlaceholderCore Steeltoe.Extensions.Configuration.ConfigServerCore Steeltoe.Extensions.Configuration.ConfigServerAutofac
PackageReferencesToUpdate: SteeltoeConfigVersion
github_access_token:
secure: ko4J3M/czguVI9AbVdkv5qZuj3Wuzts5nkz/6cypneFkQGWJXDs8Akg7xOEMu8qU
diff --git a/Configuration.sln b/Configuration.sln
index 865c3ba..c414d7c 100644
--- a/Configuration.sln
+++ b/Configuration.sln
@@ -57,6 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Configu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Configuration.PlaceholderCore.Test", "test\Steeltoe.Extensions.Configuration.PlaceholderCore.Test\Steeltoe.Extensions.Configuration.PlaceholderCore.Test.csproj", "{65B05CBE-D2DD-485D-8B5B-931185F432F8}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Configuration.RandomValueBase", "src\Steeltoe.Extensions.Configuration.RandomValueBase\Steeltoe.Extensions.Configuration.RandomValueBase.csproj", "{A512025B-72F4-4D72-8504-0FDCB2EEE4AD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steeltoe.Extensions.Configuration.RandomValueBase.Test", "test\Steeltoe.Extensions.Configuration.RandomValuesBase.Test\Steeltoe.Extensions.Configuration.RandomValueBase.Test.csproj", "{CF0D5CE0-ADAF-44B7-9AF9-C1C5644FC0B3}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -131,6 +135,14 @@ Global
{65B05CBE-D2DD-485D-8B5B-931185F432F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65B05CBE-D2DD-485D-8B5B-931185F432F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65B05CBE-D2DD-485D-8B5B-931185F432F8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A512025B-72F4-4D72-8504-0FDCB2EEE4AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A512025B-72F4-4D72-8504-0FDCB2EEE4AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A512025B-72F4-4D72-8504-0FDCB2EEE4AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A512025B-72F4-4D72-8504-0FDCB2EEE4AD}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CF0D5CE0-ADAF-44B7-9AF9-C1C5644FC0B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CF0D5CE0-ADAF-44B7-9AF9-C1C5644FC0B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CF0D5CE0-ADAF-44B7-9AF9-C1C5644FC0B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CF0D5CE0-ADAF-44B7-9AF9-C1C5644FC0B3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -153,6 +165,8 @@ Global
{9F52A57F-8133-434E-A42B-CB9859001042} = {17EC73D7-89DD-4A26-BC01-F34900140409}
{D0154ED3-B274-4C3F-BB05-9EB838184BAD} = {8C0E6601-CC7E-4A02-91B1-1E2BF93DBF9E}
{65B05CBE-D2DD-485D-8B5B-931185F432F8} = {17EC73D7-89DD-4A26-BC01-F34900140409}
+ {A512025B-72F4-4D72-8504-0FDCB2EEE4AD} = {8C0E6601-CC7E-4A02-91B1-1E2BF93DBF9E}
+ {CF0D5CE0-ADAF-44B7-9AF9-C1C5644FC0B3} = {17EC73D7-89DD-4A26-BC01-F34900140409}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FF622C8D-0862-46BD-806B-1624BEC226E5}
diff --git a/src/Steeltoe.Extensions.Configuration.CloudFoundryBase/AbstractServiceOptions.cs b/src/Steeltoe.Extensions.Configuration.CloudFoundryBase/AbstractServiceOptions.cs
index 2ef621e..de8acbf 100644
--- a/src/Steeltoe.Extensions.Configuration.CloudFoundryBase/AbstractServiceOptions.cs
+++ b/src/Steeltoe.Extensions.Configuration.CloudFoundryBase/AbstractServiceOptions.cs
@@ -49,7 +49,6 @@ namespace Steeltoe.Extensions.Configuration.CloudFoundry
{
section.Bind(this);
}
-
}
internal IConfigurationSection FindServiceSection(IConfigurationSection section, string serviceName)
diff --git a/src/Steeltoe.Extensions.Configuration.RandomValueBase/Properties/AssemblyInfo.cs b/src/Steeltoe.Extensions.Configuration.RandomValueBase/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..40422c9
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.RandomValueBase/Properties/AssemblyInfo.cs
@@ -0,0 +1,17 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("Steeltoe.Extensions.Configuration.RandomValueBase.Test")]
\ No newline at end of file
diff --git a/src/Steeltoe.Extensions.Configuration.RandomValueBase/README.md b/src/Steeltoe.Extensions.Configuration.RandomValueBase/README.md
new file mode 100644
index 0000000..3111018
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.RandomValueBase/README.md
@@ -0,0 +1,4 @@
+# Configuration Random Value Generator .NET Configuration Provider
+
+This project contains a Random Value configuration provider.
+For more information on how to use this component see the online [Steeltoe documentation](https://steeltoe.io/).
\ No newline at end of file
diff --git a/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueExtensions.cs b/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueExtensions.cs
new file mode 100644
index 0000000..6675b6c
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueExtensions.cs
@@ -0,0 +1,72 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+
+namespace Steeltoe.Extensions.Configuration.RandomValue
+{
+ public static class RandomValueExtensions
+ {
+ ///
+ /// Add a random value configuration source to the .
+ ///
+ /// the configuration builder
+ /// the logger factory to use
+ /// builder
+ public static IConfigurationBuilder AddRandomValueSource(this IConfigurationBuilder builder, ILoggerFactory loggerFactory = null)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ var resolver = new RandomValueSource(loggerFactory);
+ builder.Add(resolver);
+
+ return builder;
+ }
+
+ ///
+ /// Add a random value configuration source to the .
+ ///
+ /// the configuration builder
+ /// the prefix used for random key values, default 'random:'
+ /// the logger factory to use
+ /// builder
+ public static IConfigurationBuilder AddRandomValueSource(this IConfigurationBuilder builder, string prefix, ILoggerFactory loggerFactory = null)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ if (string.IsNullOrEmpty(prefix))
+ {
+ throw new ArgumentException(nameof(prefix));
+ }
+
+ if (!prefix.EndsWith(":"))
+ {
+ prefix = prefix + ":";
+ }
+
+ var resolver = new RandomValueSource(prefix, loggerFactory);
+ builder.Add(resolver);
+
+ return builder;
+ }
+ }
+}
diff --git a/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueProvider.cs b/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueProvider.cs
new file mode 100644
index 0000000..c8a67c8
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueProvider.cs
@@ -0,0 +1,189 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+
+namespace Steeltoe.Extensions.Configuration
+{
+ ///
+ /// Configuration provider that provides random values.
+ /// Note: This code was inspired by the Spring Boot equivalent class.
+ ///
+ public class RandomValueProvider : ConfigurationProvider
+ {
+ internal ILogger _logger;
+ internal Random _random;
+ internal string _prefix;
+
+ ///
+ /// Initializes a new instance of the class.
+ /// The new placeholder resolver wraps the provided configuration
+ ///
+ /// key prefix to use to match random number keys
+ /// the logger factory to use
+ public RandomValueProvider(string prefix, ILoggerFactory logFactory = null)
+ {
+ _prefix = prefix ?? throw new ArgumentNullException(nameof(prefix));
+ _logger = logFactory?.CreateLogger();
+ _random = new System.Random();
+ }
+
+ ///
+ /// Tries to get a configuration value for the specified key. If the key starts with the
+ /// configured prefix (default random:), then the key will be parsed and the appropriate
+ /// random value will be generated.
+ ///
+ /// The key which should start with prefix
+ /// The random value returned
+ /// True if a value for the specified key was found, otherwise false.
+ public override bool TryGet(string key, out string value)
+ {
+ value = null;
+ if (!key.StartsWith(_prefix))
+ {
+ return false;
+ }
+
+ value = GetRandomValue(key.Substring(_prefix.Length));
+ _logger?.LogDebug("Generated random value {value} for '{key}'", value, key);
+ return true;
+ }
+
+ ///
+ /// Sets a configuration value for the specified key. Currently ignored.
+ ///
+ /// The key.
+ /// The value.
+ public override void Set(string key, string value)
+ {
+ }
+
+ ///
+ /// Creates a new underlying Random number generator.
+ ///
+ public override void Load()
+ {
+ _random = new Random();
+ }
+
+ ///
+ /// Returns an empty list.
+ ///
+ /// The child keys returned by the preceding providers for the same parent path.
+ /// The parent path.
+ /// The child keys.
+ public override IEnumerable GetChildKeys(IEnumerable earlierKeys, string parentPath)
+ {
+ return new List();
+ }
+
+ internal string GetRandomValue(string type)
+ {
+ // random:int
+ if (type.Equals("int"))
+ {
+ return _random.Next().ToString();
+ }
+
+ // random:long
+ if (type.Equals("long"))
+ {
+ return GetLong().ToString();
+ }
+
+ // random:int(10), random:int(10,20), random:int[10], random:int[10,20]
+ string range = GetRange(type, "int");
+ if (range != null)
+ {
+ return GetNextIntInRange(range).ToString();
+ }
+
+ // random:long(10), random:long(10,20), random:long[10], random:long[10,20]
+ range = GetRange(type, "long");
+ if (range != null)
+ {
+ return GetNextLongInRange(range).ToString();
+ }
+
+ // random:uuid
+ if (type.Equals("uuid"))
+ {
+ return Guid.NewGuid().ToString();
+ }
+
+ return GetRandomBytes();
+ }
+
+ internal long GetLong()
+ {
+ return ((long)_random.Next() << 32) + _random.Next();
+ }
+
+ internal string GetRange(string type, string prefix)
+ {
+ if (type.StartsWith(prefix))
+ {
+ int startIndex = prefix.Length + 1;
+ if (type.Length > startIndex)
+ {
+ return type.Substring(startIndex, type.Length - 1 - startIndex);
+ }
+ }
+
+ return null;
+ }
+
+ internal int GetNextIntInRange(string range)
+ {
+ string[] tokens = range.Split(',');
+ int start = 0;
+ int.TryParse(tokens[0], out start);
+ if (tokens.Length == 1)
+ {
+ return _random.Next(start);
+ }
+
+ int max = 0;
+ int.TryParse(tokens[1], out max);
+ return _random.Next(start, max);
+ }
+
+ internal long GetNextLongInRange(string range)
+ {
+ string[] tokens = range.Split(',');
+ long start = 0;
+ long.TryParse(tokens[0], out start);
+ if (tokens.Length == 1)
+ {
+ return Math.Abs(GetLong() % start);
+ }
+
+ long lowerBound = start;
+ long upperBound = 0;
+ long.TryParse(tokens[1], out upperBound);
+ upperBound = upperBound - lowerBound;
+ return lowerBound + Math.Abs(GetLong() % upperBound);
+ }
+
+ internal string GetRandomBytes()
+ {
+ byte[] bytes = new byte[16];
+ _random.NextBytes(bytes);
+ return BitConverter.ToString(bytes).Replace("-", string.Empty);
+ }
+ }
+}
diff --git a/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueSource.cs b/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueSource.cs
new file mode 100644
index 0000000..be862fa
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.RandomValueBase/RandomValueSource.cs
@@ -0,0 +1,59 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+
+namespace Steeltoe.Extensions.Configuration
+{
+ ///
+ /// Configuration source used in creating a that generates random numbers
+ ///
+ public class RandomValueSource : IConfigurationSource
+ {
+ public const string PREFIX = "random:";
+ internal ILoggerFactory _loggerFactory;
+ internal string _prefix;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// the logger factory to use
+ public RandomValueSource(ILoggerFactory logFactory = null)
+ : this(PREFIX, logFactory)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// key prefix to use to match random number keys. Should end with the configuration seperator
+ /// the logger factory to use
+ public RandomValueSource(string prefix, ILoggerFactory logFactory = null)
+ {
+ _loggerFactory = logFactory;
+ _prefix = prefix;
+ }
+
+ ///
+ /// Builds a from the sources.
+ ///
+ /// the provided builder
+ /// the random number provider
+ public IConfigurationProvider Build(IConfigurationBuilder builder)
+ {
+ return new RandomValueProvider(_prefix, _loggerFactory);
+ }
+ }
+}
diff --git a/src/Steeltoe.Extensions.Configuration.RandomValueBase/Steeltoe.Extensions.Configuration.RandomValueBase.csproj b/src/Steeltoe.Extensions.Configuration.RandomValueBase/Steeltoe.Extensions.Configuration.RandomValueBase.csproj
new file mode 100644
index 0000000..45b176b
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.RandomValueBase/Steeltoe.Extensions.Configuration.RandomValueBase.csproj
@@ -0,0 +1,37 @@
+
+
+
+ Random Value Provider - Base Package
+ $(SteeltoeVersion)
+ $(VersionSuffix)
+ Pivotal;dtillman
+ netstandard2.0
+ Steeltoe.Extensions.Configuration.RandomValueBase
+ Steeltoe.Extensions.Configuration.RandomValueBase
+ Configuration;Random Values
+ https://steeltoe.io/images/transparent.png
+ https://steeltoe.io
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+ bin\$(Configuration)\$(TargetFramework)\Steeltoe.Extensions.Configuration.RandomValueBase.xml
+
+
+
+
+
+ All
+
+
+
+
+ SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591
+
+
+
+ stylecop.json
+ Always
+
+
+
+
diff --git a/src/Steeltoe.Extensions.Configuration.SpringBootBase/Properties/AssemblyInfo.cs b/src/Steeltoe.Extensions.Configuration.SpringBootBase/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..adf9d7e
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.SpringBootBase/Properties/AssemblyInfo.cs
@@ -0,0 +1,18 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System.Runtime.CompilerServices;
+
+[assembly: InternalsVisibleTo("Steeltoe.Extensions.Configuration.SpringBootBase.Test")]
+[assembly: InternalsVisibleTo("Steeltoe.Extensions.Configuration.SpringBootCore.Test")]
\ No newline at end of file
diff --git a/src/Steeltoe.Extensions.Configuration.SpringBootBase/README.md b/src/Steeltoe.Extensions.Configuration.SpringBootBase/README.md
new file mode 100644
index 0000000..250d9cd
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.SpringBootBase/README.md
@@ -0,0 +1,4 @@
+# Configuration Random number generator .NET Configuration Provider
+
+This project contains a Random number configuration provider.
+For more information on how to use this component see the online [Steeltoe documentation](https://steeltoe.io/).
\ No newline at end of file
diff --git a/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberExtensions.cs b/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberExtensions.cs
new file mode 100644
index 0000000..9c67ffc
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberExtensions.cs
@@ -0,0 +1,74 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+
+namespace Steeltoe.Extensions.Configuration.RandomNumber
+{
+ public static class RandomNumberExtensions
+ {
+ ///
+ /// Add a Random number generator configuration source to the .
+ /// You can use keys like 'random.int', 'random.long', 'random.string', 'random.uuid', etc.
+ ///
+ /// the configuration builder
+ /// the logger factory to use
+ /// builder
+ public static IConfigurationBuilder AddRandomNumberGenerator(this IConfigurationBuilder builder, ILoggerFactory loggerFactory = null)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ var resolver = new RandomNumberSource(loggerFactory);
+ builder.Add(resolver);
+
+ return builder;
+ }
+
+ ///
+ /// Add a Random number generator configuration source to the .
+ /// You can use keys like 'random.int', 'random.long', 'random.string', 'random.uuid', etc.
+ ///
+ /// the configuration builder
+ /// the prefix to use in generating random values
+ /// the logger factory to use
+ /// builder
+ public static IConfigurationBuilder AddRandomNumberGenerator(this IConfigurationBuilder builder, string prefix, ILoggerFactory loggerFactory = null)
+ {
+ if (builder == null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ if (string.IsNullOrEmpty(prefix))
+ {
+ throw new ArgumentException(nameof(prefix));
+ }
+
+ if (!prefix.EndsWith(":"))
+ {
+ prefix = prefix + ":";
+ }
+
+ var resolver = new RandomNumberSource(prefix, loggerFactory);
+ builder.Add(resolver);
+
+ return builder;
+ }
+ }
+}
diff --git a/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberProvider.cs b/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberProvider.cs
new file mode 100644
index 0000000..6386001
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberProvider.cs
@@ -0,0 +1,186 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Primitives;
+using System;
+using System.Collections.Generic;
+
+namespace Steeltoe.Extensions.Configuration
+{
+ ///
+ /// Configuration provider that provides random numbers
+ ///
+ public class RandomNumberProvider : ConfigurationProvider
+ {
+ internal ILogger _logger;
+ internal Random _random;
+ internal string _prefix;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// key prefix to use to match random number keys
+ /// the logger factory to use
+ public RandomNumberProvider(string prefix, ILoggerFactory logFactory = null)
+ {
+ _prefix = prefix ?? throw new ArgumentNullException(nameof(prefix));
+ _logger = logFactory?.CreateLogger();
+ _random = new System.Random();
+ }
+
+ ///
+ /// Will generate a random value depending on the key thats provided
+ ///
+ /// The key to match on
+ /// The value.
+ /// True if a value for the specified key was found, otherwise false.
+ public override bool TryGet(string key, out string value)
+ {
+ value = null;
+ if (!key.StartsWith(_prefix))
+ {
+ return false;
+ }
+
+ value = GetRandomValue(key.Substring(_prefix.Length));
+ _logger?.LogDebug("Generated random value {value} for '{key}'", value, key);
+ return true;
+ }
+
+ ///
+ /// Sets a configuration value for the specified key. Currently ignored.
+ ///
+ /// The key.
+ /// The value.
+ public override void Set(string key, string value)
+ {
+ }
+
+ ///
+ /// Simply creates a new underlying Random number generator.
+ ///
+ public override void Load()
+ {
+ _random = new Random();
+ }
+
+ ///
+ /// Returns an empty list.
+ ///
+ /// The child keys returned by the preceding providers for the same parent path.
+ /// The parent path.
+ /// The child keys.
+ public override IEnumerable GetChildKeys(IEnumerable earlierKeys, string parentPath)
+ {
+ return new List();
+ }
+
+ internal string GetRandomValue(string type)
+ {
+ // random:int
+ if (type.Equals("int"))
+ {
+ return _random.Next().ToString();
+ }
+
+ // random:long
+ if (type.Equals("long"))
+ {
+ return GetLong().ToString();
+ }
+
+ // random:int(10), random:int(10,20), random:int[10], random:int[10,20]
+ string range = GetRange(type, "int");
+ if (range != null)
+ {
+ return GetNextIntInRange(range).ToString();
+ }
+
+ // random:long(10), random:long(10,20), random:long[10], random:long[10,20]
+ range = GetRange(type, "long");
+ if (range != null)
+ {
+ return GetNextLongInRange(range).ToString();
+ }
+
+ // random:uuid
+ if (type.Equals("uuid"))
+ {
+ return Guid.NewGuid().ToString();
+ }
+
+ return GetRandomBytes();
+ }
+
+ internal long GetLong()
+ {
+ return ((long)_random.Next() << 32) + _random.Next();
+ }
+
+ internal string GetRange(string type, string prefix)
+ {
+ if (type.StartsWith(prefix))
+ {
+ int startIndex = prefix.Length + 1;
+ if (type.Length > startIndex)
+ {
+ return type.Substring(startIndex, type.Length - 1 - startIndex);
+ }
+ }
+
+ return null;
+ }
+
+ internal int GetNextIntInRange(string range)
+ {
+ string[] tokens = range.Split(',');
+ int start = 0;
+ int.TryParse(tokens[0], out start);
+ if (tokens.Length == 1)
+ {
+ return _random.Next(start);
+ }
+
+ int max = 0;
+ int.TryParse(tokens[1], out max);
+ return _random.Next(start, max);
+ }
+
+ internal long GetNextLongInRange(string range)
+ {
+ string[] tokens = range.Split(',');
+ long start = 0;
+ long.TryParse(tokens[0], out start);
+ if (tokens.Length == 1)
+ {
+ return Math.Abs(GetLong() % start);
+ }
+
+ long lowerBound = start;
+ long upperBound = 0;
+ long.TryParse(tokens[1], out upperBound);
+ upperBound = upperBound - lowerBound;
+ return lowerBound + Math.Abs(GetLong() % upperBound);
+ }
+
+ internal string GetRandomBytes()
+ {
+ byte[] bytes = new byte[16];
+ _random.NextBytes(bytes);
+ return BitConverter.ToString(bytes).Replace("-", string.Empty);
+ }
+ }
+}
diff --git a/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberSource.cs b/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberSource.cs
new file mode 100644
index 0000000..b5de5c3
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.SpringBootBase/RandomNumberSource.cs
@@ -0,0 +1,61 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+
+namespace Steeltoe.Extensions.Configuration
+{
+ ///
+ /// Configuration source used in creating a that generates random numbers
+ ///
+ public class RandomNumberSource : IConfigurationSource
+ {
+ public const string PREFIX = "random:";
+ internal ILoggerFactory _loggerFactory;
+ internal string _prefix;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// the logger factory to use
+ public RandomNumberSource(ILoggerFactory logFactory = null)
+ : this(PREFIX, logFactory)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// key prefix to use to match random number keys. Should end with the configuration seperator
+ /// the logger factory to use
+ public RandomNumberSource(string prefix, ILoggerFactory logFactory = null)
+ {
+ _loggerFactory = logFactory;
+ _prefix = prefix;
+ }
+
+ ///
+ /// Builds a from the sources.
+ ///
+ /// the provided builder
+ /// the random number provider
+ public IConfigurationProvider Build(IConfigurationBuilder builder)
+ {
+ return new RandomNumberProvider(_prefix, _loggerFactory);
+ }
+ }
+}
diff --git a/src/Steeltoe.Extensions.Configuration.SpringBootBase/Steeltoe.Extensions.Configuration.SpringBootBase.csproj b/src/Steeltoe.Extensions.Configuration.SpringBootBase/Steeltoe.Extensions.Configuration.SpringBootBase.csproj
new file mode 100644
index 0000000..122372b
--- /dev/null
+++ b/src/Steeltoe.Extensions.Configuration.SpringBootBase/Steeltoe.Extensions.Configuration.SpringBootBase.csproj
@@ -0,0 +1,36 @@
+
+
+
+ Spring Boot Properties Compatability - Base Package
+ $(SteeltoeVersion)
+ $(VersionSuffix)
+ Pivotal;dtillman
+ netstandard2.0
+ Steeltoe.Extensions.Configuration.SpringBootBase
+ Steeltoe.Extensions.Configuration.SpringBootBase
+ Configuration;Spring Boot Properties;Compatability
+ https://steeltoe.io/images/transparent.png
+ https://steeltoe.io
+ https://www.apache.org/licenses/LICENSE-2.0
+
+
+ bin\$(Configuration)\$(TargetFramework)\Steeltoe.Extensions.Configuration.PlaceholderBase.xml
+
+
+
+
+ All
+
+
+
+
+ SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591
+
+
+
+ stylecop.json
+ Always
+
+
+
+
diff --git a/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueExtensionsTest.cs b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueExtensionsTest.cs
new file mode 100644
index 0000000..4e15761
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueExtensionsTest.cs
@@ -0,0 +1,181 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.RandomValue.Test
+{
+ public class RandomValueExtensionsTest
+ {
+ [Fact]
+ public void AddRandomValueSource_ThrowsIfConfigBuilderNull()
+ {
+ // Arrange
+ IConfigurationBuilder configurationBuilder = null;
+
+ // Act and Assert
+ var ex = Assert.Throws(() => RandomValueExtensions.AddRandomValueSource(configurationBuilder));
+ }
+
+ [Fact]
+ public void AddRandomValueSource_ThrowsIfPrefixNull()
+ {
+ // Arrange
+ string prefix = null;
+
+ // Act and Assert
+ var ex = Assert.Throws(() => RandomValueExtensions.AddRandomValueSource(new ConfigurationBuilder(), prefix));
+ }
+
+ [Fact]
+ public void AddRandomValueSource_Ignores()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["foo:bar"];
+ Assert.Equal("value", value);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_String()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:string"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_Uuid()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:uuid"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_RandomInt()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:int"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_RandomIntRange()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:int[4,10]"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_RandomIntMax()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:int(10)"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_RandomLong()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:long"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_RandomLongRange()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:long[4,10]"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void AddRandomValueSource_RandomLongMax()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomValueSource()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:long(10)"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueProviderTest.cs b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueProviderTest.cs
new file mode 100644
index 0000000..4eec2b9
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueProviderTest.cs
@@ -0,0 +1,109 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.RandomValue.Test
+{
+ public class RandomValueProviderTest
+ {
+ [Fact]
+ public void Constructor__ThrowsIfPrefixNull()
+ {
+ // Act and Assert
+ var ex = Assert.Throws(() => new RandomValueProvider(null, null));
+ }
+
+ [Fact]
+ public void TryGet_Ignores()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("foo:bar", out string value);
+ Assert.Null(value);
+ }
+
+ [Fact]
+ public void TryGet_String()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:string", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_Uuid()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:uuid", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_RandomInt()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:int", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_RandomIntRange()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:int[4,10]", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void TryGet_RandomIntMax()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:int(10)", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+
+ [Fact]
+ public void TryGet_RandomLong()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:long", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_RandomLongRange()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:long[4,10]", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void TryGet_RandomLongMax()
+ {
+ var prov = new RandomValueProvider("random:");
+ prov.TryGet("random:long(10)", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueSourceTest.cs b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueSourceTest.cs
new file mode 100644
index 0000000..41f28cd
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/RandomValueSourceTest.cs
@@ -0,0 +1,51 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.RandomValue.Test
+{
+ public class RandomValueSourceTest
+ {
+ [Fact]
+ public void Constructors__InitializesDefaults()
+ {
+ ILoggerFactory factory = new LoggerFactory();
+
+ var source = new RandomValueSource(factory);
+ Assert.Equal(factory, source._loggerFactory);
+ Assert.NotNull(source._prefix);
+ Assert.Equal(RandomValueSource.PREFIX, source._prefix);
+
+ source = new RandomValueSource("foobar:", factory);
+ Assert.Equal(factory, source._loggerFactory);
+ Assert.NotNull(source._prefix);
+ Assert.Equal("foobar:", source._prefix);
+ }
+
+ [Fact]
+ public void Build__ReturnsProvider()
+ {
+ // Arrange
+ ILoggerFactory factory = new LoggerFactory();
+
+ // Act and Assert
+ var source = new RandomValueSource();
+ var provider = source.Build(new ConfigurationBuilder());
+ Assert.IsType(provider);
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/Steeltoe.Extensions.Configuration.RandomValueBase.Test.csproj b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/Steeltoe.Extensions.Configuration.RandomValueBase.Test.csproj
new file mode 100644
index 0000000..e8d7764
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/Steeltoe.Extensions.Configuration.RandomValueBase.Test.csproj
@@ -0,0 +1,36 @@
+
+
+
+ netcoreapp2.0;netcoreapp2.1;net461
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ All
+
+
+
+ SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591
+
+
+
+ stylecop.json
+ Always
+
+
+
diff --git a/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/xunit.runner.json b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/xunit.runner.json
new file mode 100644
index 0000000..4c62fd7
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.RandomValuesBase.Test/xunit.runner.json
@@ -0,0 +1,4 @@
+{
+ "maxParallelThreads": 1,
+ "parallelizeTestCollections": false
+}
\ No newline at end of file
diff --git a/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberExtensionsTest.cs b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberExtensionsTest.cs
new file mode 100644
index 0000000..29daa31
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberExtensionsTest.cs
@@ -0,0 +1,181 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.RandomNumber.Test
+{
+ public class RandomNumberExtensionsTest
+ {
+ [Fact]
+ public void AddRandomNumberGenerator_ThrowsIfConfigBuilderNull()
+ {
+ // Arrange
+ IConfigurationBuilder configurationBuilder = null;
+
+ // Act and Assert
+ var ex = Assert.Throws(() => RandomNumberExtensions.AddRandomNumberGenerator(configurationBuilder));
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_ThrowsIfPrefixNull()
+ {
+ // Arrange
+ string prefix = null;
+
+ // Act and Assert
+ var ex = Assert.Throws(() => RandomNumberExtensions.AddRandomNumberGenerator(new ConfigurationBuilder(), prefix));
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_Ignores()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["foo:bar"];
+ Assert.Equal("value", value);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_String()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:string"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_Uuid()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:uuid"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_RandomInt()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:int"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_RandomIntRange()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:int[4,10]"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_RandomIntMax()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:int(10)"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_RandomLong()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:long"];
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_RandomLongRange()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:long[4,10]"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void AddRandomNumberGenerator_RandomLongMax()
+ {
+ var builder = new ConfigurationBuilder()
+ .AddRandomNumberGenerator()
+ .AddInMemoryCollection(new Dictionary()
+ {
+ { "foo:bar", "value" }
+ });
+ var config = builder.Build();
+ var value = config["random:long(10)"];
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberProviderTest.cs b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberProviderTest.cs
new file mode 100644
index 0000000..f51de2b
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberProviderTest.cs
@@ -0,0 +1,119 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Hosting.Internal;
+using Microsoft.AspNetCore.TestHost;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Threading;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.RandomNumber.Test
+{
+ public class RandomNumberProviderTest
+ {
+ [Fact]
+ public void Constructor__ThrowsIfPrefixNull()
+ {
+ // Act and Assert
+ var ex = Assert.Throws(() => new RandomNumberProvider(null, null));
+ }
+
+ [Fact]
+ public void TryGet_Ignores()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("foo:bar", out string value);
+ Assert.Null(value);
+ }
+
+ [Fact]
+ public void TryGet_String()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:string", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_Uuid()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:uuid", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_RandomInt()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:int", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_RandomIntRange()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:int[4,10]", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void TryGet_RandomIntMax()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:int(10)", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+
+ [Fact]
+ public void TryGet_RandomLong()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:long", out string value);
+ Assert.NotNull(value);
+ }
+
+ [Fact]
+ public void TryGet_RandomLongRange()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:long[4,10]", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 4, 10);
+ }
+
+ [Fact]
+ public void TryGet_RandomLongMax()
+ {
+ var prov = new RandomNumberProvider("random:");
+ prov.TryGet("random:long(10)", out string value);
+ Assert.NotNull(value);
+ int val = int.Parse(value);
+ Assert.InRange(val, 0, 10);
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberSourceTest.cs b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberSourceTest.cs
new file mode 100644
index 0000000..e4825a7
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/RandomNumberSourceTest.cs
@@ -0,0 +1,58 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Memory;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.RandomNumber.Test
+{
+ public class RandomNumberSourceTest
+ {
+
+ [Fact]
+ public void Constructors__InitializesDefaults()
+ {
+
+ ILoggerFactory factory = new LoggerFactory();
+
+ var source = new RandomNumberSource(factory);
+ Assert.Equal(factory, source._loggerFactory);
+ Assert.NotNull(source._prefix);
+ Assert.Equal(RandomNumberSource.PREFIX, source._prefix);
+
+ source = new RandomNumberSource("foobar:", factory);
+ Assert.Equal(factory, source._loggerFactory);
+ Assert.NotNull(source._prefix);
+ Assert.Equal("foobar:", source._prefix);
+ }
+
+ [Fact]
+ public void Build__ReturnsProvider()
+ {
+ // Arrange
+ ILoggerFactory factory = new LoggerFactory();
+
+ // Act and Assert
+ var source = new RandomNumberSource();
+ var provider = source.Build(new ConfigurationBuilder());
+ Assert.IsType(provider);
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/Steeltoe.Extensions.Configuration.SpringBootBase.Test.csproj b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/Steeltoe.Extensions.Configuration.SpringBootBase.Test.csproj
new file mode 100644
index 0000000..f4d039a
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/Steeltoe.Extensions.Configuration.SpringBootBase.Test.csproj
@@ -0,0 +1,34 @@
+
+
+
+ netcoreapp2.0;netcoreapp2.1;net461
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+ All
+
+
+
+ SA1101;SA1124;SA1201;SA1309;SA1310;SA1401;SA1600;SA1652;1591
+
+
+
+ stylecop.json
+ Always
+
+
+
diff --git a/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/TestHelpers.cs b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/TestHelpers.cs
new file mode 100644
index 0000000..d5c1f44
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/TestHelpers.cs
@@ -0,0 +1,48 @@
+// Copyright 2017 the original author or authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System.IO;
+using Xunit;
+
+namespace Steeltoe.Extensions.Configuration.Placeholder.Test
+{
+ public class TestHelpers
+ {
+ public static string CreateTempFile(string contents)
+ {
+ var tempFile = Path.GetTempFileName();
+ File.WriteAllText(tempFile, contents);
+ return tempFile;
+ }
+
+ public static Stream StringToStream(string str)
+ {
+ var memStream = new MemoryStream();
+ var textWriter = new StreamWriter(memStream);
+ textWriter.Write(str);
+ textWriter.Flush();
+ memStream.Seek(0, SeekOrigin.Begin);
+
+ return memStream;
+ }
+
+ public static string StreamToString(Stream stream)
+ {
+ stream.Seek(0, SeekOrigin.Begin);
+ var reader = new StreamReader(stream);
+
+ return reader.ReadToEnd();
+ }
+ }
+}
diff --git a/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/xunit.runner.json b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/xunit.runner.json
new file mode 100644
index 0000000..4c62fd7
--- /dev/null
+++ b/test/Steeltoe.Extensions.Configuration.SpringBootBase.Test/xunit.runner.json
@@ -0,0 +1,4 @@
+{
+ "maxParallelThreads": 1,
+ "parallelizeTestCollections": false
+}
\ No newline at end of file