diff --git a/Directory.Build.props b/Directory.Build.props
index 5569f9fd..5e41ca65 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
- 1.0.36
+ 1.0.37
diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt
index 4012570d..15575e63 100644
--- a/GitHubReleaseNotes.txt
+++ b/GitHubReleaseNotes.txt
@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes
-GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid --version 1.0.36.0
\ No newline at end of file
+GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid --version 1.0.37.0
\ No newline at end of file
diff --git a/examples/WireMock.Net.Client/Program.cs b/examples/WireMock.Net.Client/Program.cs
index 4a8dabfa..4d3eb682 100644
--- a/examples/WireMock.Net.Client/Program.cs
+++ b/examples/WireMock.Net.Client/Program.cs
@@ -3,13 +3,14 @@ using RestEase;
using System;
using System.Net.Http.Headers;
using System.Text;
+using System.Threading.Tasks;
using WireMock.Client;
namespace WireMock.Net.Client
{
class Program
{
- static void Main(string[] args)
+ static async Task Main(string[] args)
{
// Create an implementation of the IFluentMockServerAdmin and pass in the base URL for the API.
var api = RestClient.For("http://localhost:9091");
@@ -18,29 +19,29 @@ namespace WireMock.Net.Client
var value = Convert.ToBase64String(Encoding.ASCII.GetBytes("a:b"));
api.Authorization = new AuthenticationHeaderValue("Basic", value);
- var settings1 = api.GetSettingsAsync().Result;
+ var settings1 = await api.GetSettingsAsync();
Console.WriteLine($"settings1 = {JsonConvert.SerializeObject(settings1)}");
settings1.GlobalProcessingDelay = 1077;
api.PostSettingsAsync(settings1).Wait();
- var settings2 = api.GetSettingsAsync().Result;
+ var settings2 = await api.GetSettingsAsync();
Console.WriteLine($"settings2 = {JsonConvert.SerializeObject(settings2)}");
- var mappings = api.GetMappingsAsync().Result;
+ var mappings = await api.GetMappingsAsync();
Console.WriteLine($"mappings = {JsonConvert.SerializeObject(mappings)}");
try
{
var guid = Guid.Parse("11111110-a633-40e8-a244-5cb80bc0ab66");
- var mapping = api.GetMappingAsync(guid).Result;
+ var mapping = await api.GetMappingAsync(guid);
Console.WriteLine($"mapping = {JsonConvert.SerializeObject(mapping)}");
}
catch (Exception e)
{
}
- var request = api.GetRequestsAsync().Result;
+ var request = await api.GetRequestsAsync();
Console.WriteLine($"request = {JsonConvert.SerializeObject(request)}");
//var deleteRequestsAsync = api.DeleteRequestsAsync().Result;
@@ -49,15 +50,21 @@ namespace WireMock.Net.Client
//var resetRequestsAsync = api.ResetRequestsAsync().Result;
//Console.WriteLine($"ResetRequestsAsync = {resetRequestsAsync.Status}");
- var scenarioStates = api.GetScenariosAsync().Result;
+ var scenarioStates = await api.GetScenariosAsync();
Console.WriteLine($"GetScenariosAsync = {JsonConvert.SerializeObject(scenarioStates)}");
- var postFileResult = api.PostFileAsync("1.cs", "C# Hello").GetAwaiter().GetResult();
+ var postFileResult = await api.PostFileAsync("1.cs", "C# Hello");
Console.WriteLine($"postFileResult = {JsonConvert.SerializeObject(postFileResult)}");
- var getFileResult = api.GetFileAsync("1.cs").GetAwaiter().GetResult();
+ var getFileResult = await api.GetFileAsync("1.cs");
Console.WriteLine($"getFileResult = {getFileResult}");
+ var resetMappingsAsync = await api.ResetMappingsAsync();
+ Console.WriteLine($"resetMappingsAsync = {resetMappingsAsync.Status}");
+
+ var resetMappingsAndReloadStaticMappingsAsync = await api.ResetMappingsAsync(true);
+ Console.WriteLine($"resetMappingsAndReloadStaticMappingsAsync = {resetMappingsAndReloadStaticMappingsAsync.Status}");
+
Console.WriteLine("Press any key to quit");
Console.ReadKey();
}
diff --git a/examples/WireMock.Net.Client/WireMock.Net.Client.csproj b/examples/WireMock.Net.Client/WireMock.Net.Client.csproj
index f5a04dc3..2a23350b 100644
--- a/examples/WireMock.Net.Client/WireMock.Net.Client.csproj
+++ b/examples/WireMock.Net.Client/WireMock.Net.Client.csproj
@@ -2,8 +2,7 @@
Exe
- netcoreapp2.0
-
+ netcoreapp2.1
../../WireMock.Net-Logo.ico
diff --git a/examples/WireMock.Net.Console.NETCoreApp2/__admin/mappings/1.cs b/examples/WireMock.Net.Console.NETCoreApp2/__admin/mappings/1.cs
new file mode 100644
index 00000000..3310d6a2
--- /dev/null
+++ b/examples/WireMock.Net.Console.NETCoreApp2/__admin/mappings/1.cs
@@ -0,0 +1 @@
+C# Hello
\ No newline at end of file
diff --git a/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs b/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs
index 699ec4b4..012b3350 100644
--- a/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs
+++ b/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs
@@ -21,9 +21,9 @@ namespace WireMock.Net.ConsoleApplication
}
///
- public IEnumerable EnumerateFiles(string path)
+ public IEnumerable EnumerateFiles(string path, bool includeSubdirectories)
{
- return Directory.EnumerateFiles(path);
+ return includeSubdirectories ? Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) : Directory.EnumerateFiles(path);
}
///
diff --git a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
index 9c80f6cd..294a1e6d 100644
--- a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
+++ b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
@@ -46,6 +46,7 @@ namespace WireMock.Net.ConsoleApplication
StartAdminInterface = true,
ReadStaticMappings = true,
WatchStaticMappings = true,
+ WatchStaticMappingsInSubdirectories = true,
//ProxyAndRecordSettings = new ProxyAndRecordSettings
//{
// SaveMapping = true
diff --git a/src/WireMock.Net.StandAlone/StandAloneApp.cs b/src/WireMock.Net.StandAlone/StandAloneApp.cs
index b49bb88f..a1b22056 100644
--- a/src/WireMock.Net.StandAlone/StandAloneApp.cs
+++ b/src/WireMock.Net.StandAlone/StandAloneApp.cs
@@ -47,6 +47,7 @@ namespace WireMock.Net.StandAlone
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"),
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
+ WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"),
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping"),
AdminUsername = parser.GetStringValue("AdminUsername"),
AdminPassword = parser.GetStringValue("AdminPassword"),
diff --git a/src/WireMock.Net/Client/IFluentMockServerAdmin.cs b/src/WireMock.Net/Client/IFluentMockServerAdmin.cs
index bddaf37f..1328a906 100644
--- a/src/WireMock.Net/Client/IFluentMockServerAdmin.cs
+++ b/src/WireMock.Net/Client/IFluentMockServerAdmin.cs
@@ -75,8 +75,9 @@ namespace WireMock.Client
///
/// Delete (reset) all mappings.
///
+ /// A value indicating whether to reload the static mappings after the reset.
[Post("__admin/mappings/reset")]
- Task ResetMappingsAsync();
+ Task ResetMappingsAsync(bool? reloadStaticMappings = false);
///
/// Get a mapping based on the guid
diff --git a/src/WireMock.Net/Handlers/IFileSystemHandler.cs b/src/WireMock.Net/Handlers/IFileSystemHandler.cs
index d01e0469..498c5826 100644
--- a/src/WireMock.Net/Handlers/IFileSystemHandler.cs
+++ b/src/WireMock.Net/Handlers/IFileSystemHandler.cs
@@ -31,8 +31,9 @@ namespace WireMock.Handlers
/// Returns an enumerable collection of file names in a specified path.
///
/// The path.
- /// An enumerable collection of the full names (including paths) for the files in the directory specified by path.
- IEnumerable EnumerateFiles([NotNull] string path);
+ /// A value indicating whether subdirectories should also included when enumerating files.
+ /// An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.
+ IEnumerable EnumerateFiles([NotNull] string path, bool includeSubdirectories);
///
/// Read a static mapping file as text.
diff --git a/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs b/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs
index f349d9fc..57bedc64 100644
--- a/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs
+++ b/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs
@@ -46,11 +46,11 @@ namespace WireMock.Handlers
}
///
- public IEnumerable EnumerateFiles(string path)
+ public IEnumerable EnumerateFiles(string path, bool includeSubdirectories)
{
Check.NotNullOrEmpty(path, nameof(path));
- return Directory.EnumerateFiles(path);
+ return includeSubdirectories ? Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) : Directory.EnumerateFiles(path);
}
///
diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
index 36c55ab7..c83d108d 100644
--- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
@@ -39,6 +39,7 @@ namespace WireMock.Server
private const string AdminRequests = "/__admin/requests";
private const string AdminSettings = "/__admin/settings";
private const string AdminScenarios = "/__admin/scenarios";
+ private const string QueryParamReloadStaticMappings = "reloadStaticMappings";
private readonly RegexMatcher _adminRequestContentTypeJson = new ContentTypeMatcher(ContentTypeJson, true);
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
@@ -69,7 +70,7 @@ namespace WireMock.Server
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
// __admin/mappings/reset
- Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
+ Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsReset));
// __admin/mappings/{guid}
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingGet));
@@ -141,7 +142,7 @@ namespace WireMock.Server
return;
}
- foreach (string filename in _settings.FileSystemHandler.EnumerateFiles(folder).OrderBy(f => f))
+ foreach (string filename in _settings.FileSystemHandler.EnumerateFiles(folder, _settings.WatchStaticMappingsInSubdirectories == true).OrderBy(f => f))
{
_settings.Logger.Info("Reading Static MappingFile : '{0}'", filename);
@@ -173,9 +174,14 @@ namespace WireMock.Server
return;
}
- _settings.Logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
+ bool includeSubdirectories = _settings.WatchStaticMappingsInSubdirectories == true;
+ string includeSubdirectoriesText = includeSubdirectories ? " and Subdirectories" : string.Empty;
+
+ _settings.Logger.Info($"Watching folder '{folder}'{includeSubdirectoriesText} for new, updated and deleted MappingFiles.");
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", EnhancedFileSystemWatcherTimeoutMs);
+ watcher.IncludeSubdirectories = includeSubdirectories;
+
watcher.Created += (sender, args) =>
{
_settings.Logger.Info("MappingFile created : '{0}', reading file.", args.FullPath);
@@ -551,6 +557,24 @@ namespace WireMock.Server
return ResponseMessageBuilder.Create("Mappings deleted");
}
+
+ private ResponseMessage MappingsReset(RequestMessage requestMessage)
+ {
+ ResetMappings();
+
+ ResetScenarios();
+
+ string message = "Mappings reset";
+ if (requestMessage.Query.ContainsKey(QueryParamReloadStaticMappings) &&
+ bool.TryParse(requestMessage.Query[QueryParamReloadStaticMappings].ToString(), out bool reloadStaticMappings)
+ && reloadStaticMappings)
+ {
+ ReadStaticMappings();
+ message = $"{message} and static mappings reloaded";
+ }
+
+ return ResponseMessageBuilder.Create(message);
+ }
#endregion Mappings
#region Request/{guid}
diff --git a/src/WireMock.Net/Settings/FluentMockServerSettings.cs b/src/WireMock.Net/Settings/FluentMockServerSettings.cs
index 9d47cb98..072f5aca 100644
--- a/src/WireMock.Net/Settings/FluentMockServerSettings.cs
+++ b/src/WireMock.Net/Settings/FluentMockServerSettings.cs
@@ -33,6 +33,10 @@ namespace WireMock.Settings
[PublicAPI]
public bool? WatchStaticMappings { get; set; }
+ ///
+ [PublicAPI]
+ public bool? WatchStaticMappingsInSubdirectories { get; set; }
+
///
[PublicAPI]
public IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
diff --git a/src/WireMock.Net/Settings/IFluentMockServerSettings.cs b/src/WireMock.Net/Settings/IFluentMockServerSettings.cs
index f7840d15..ee10c4d1 100644
--- a/src/WireMock.Net/Settings/IFluentMockServerSettings.cs
+++ b/src/WireMock.Net/Settings/IFluentMockServerSettings.cs
@@ -42,6 +42,12 @@ namespace WireMock.Settings
[PublicAPI]
bool? WatchStaticMappings { get; set; }
+ ///
+ /// A value indicating whether subdirectories within the static mappings path should be monitored.
+ ///
+ [PublicAPI]
+ bool? WatchStaticMappingsInSubdirectories { get; set; }
+
///
/// Gets or sets if the proxy and record settings.
///
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs b/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs
index 6f07ca08..038f1d6c 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.Admin.cs
@@ -171,7 +171,7 @@ namespace WireMock.Net.Tests
var staticMappingHandlerMock = new Mock();
staticMappingHandlerMock.Setup(m => m.GetMappingFolder()).Returns("folder");
staticMappingHandlerMock.Setup(m => m.FolderExists(It.IsAny())).Returns(true);
- staticMappingHandlerMock.Setup(m => m.EnumerateFiles(It.IsAny())).Returns(new string[0]);
+ staticMappingHandlerMock.Setup(m => m.EnumerateFiles(It.IsAny(), It.IsAny())).Returns(new string[0]);
var server = FluentMockServer.Start(new FluentMockServerSettings
{
@@ -184,7 +184,7 @@ namespace WireMock.Net.Tests
// Assert and Verify
staticMappingHandlerMock.Verify(m => m.GetMappingFolder(), Times.Once);
staticMappingHandlerMock.Verify(m => m.FolderExists("folder"), Times.Once);
- staticMappingHandlerMock.Verify(m => m.EnumerateFiles("folder"), Times.Once);
+ staticMappingHandlerMock.Verify(m => m.EnumerateFiles("folder", false), Times.Once);
}
[Fact]