mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-23 01:08:49 +02:00
WatchStaticMappingsInSubdirectories (#374)
* WatchStaticMappingsInSubdirectories * 37 * IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories); * reloadStaticMappings
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>1.0.36</VersionPrefix>
|
<VersionPrefix>1.0.37</VersionPrefix>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Choose>
|
<Choose>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
https://github.com/StefH/GitHubReleaseNotes
|
https://github.com/StefH/GitHubReleaseNotes
|
||||||
|
|
||||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid --version 1.0.36.0
|
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid --version 1.0.37.0
|
||||||
@@ -3,13 +3,14 @@ using RestEase;
|
|||||||
using System;
|
using System;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using WireMock.Client;
|
using WireMock.Client;
|
||||||
|
|
||||||
namespace WireMock.Net.Client
|
namespace WireMock.Net.Client
|
||||||
{
|
{
|
||||||
class Program
|
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.
|
// Create an implementation of the IFluentMockServerAdmin and pass in the base URL for the API.
|
||||||
var api = RestClient.For<IFluentMockServerAdmin>("http://localhost:9091");
|
var api = RestClient.For<IFluentMockServerAdmin>("http://localhost:9091");
|
||||||
@@ -18,29 +19,29 @@ namespace WireMock.Net.Client
|
|||||||
var value = Convert.ToBase64String(Encoding.ASCII.GetBytes("a:b"));
|
var value = Convert.ToBase64String(Encoding.ASCII.GetBytes("a:b"));
|
||||||
api.Authorization = new AuthenticationHeaderValue("Basic", value);
|
api.Authorization = new AuthenticationHeaderValue("Basic", value);
|
||||||
|
|
||||||
var settings1 = api.GetSettingsAsync().Result;
|
var settings1 = await api.GetSettingsAsync();
|
||||||
Console.WriteLine($"settings1 = {JsonConvert.SerializeObject(settings1)}");
|
Console.WriteLine($"settings1 = {JsonConvert.SerializeObject(settings1)}");
|
||||||
|
|
||||||
settings1.GlobalProcessingDelay = 1077;
|
settings1.GlobalProcessingDelay = 1077;
|
||||||
api.PostSettingsAsync(settings1).Wait();
|
api.PostSettingsAsync(settings1).Wait();
|
||||||
|
|
||||||
var settings2 = api.GetSettingsAsync().Result;
|
var settings2 = await api.GetSettingsAsync();
|
||||||
Console.WriteLine($"settings2 = {JsonConvert.SerializeObject(settings2)}");
|
Console.WriteLine($"settings2 = {JsonConvert.SerializeObject(settings2)}");
|
||||||
|
|
||||||
var mappings = api.GetMappingsAsync().Result;
|
var mappings = await api.GetMappingsAsync();
|
||||||
Console.WriteLine($"mappings = {JsonConvert.SerializeObject(mappings)}");
|
Console.WriteLine($"mappings = {JsonConvert.SerializeObject(mappings)}");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var guid = Guid.Parse("11111110-a633-40e8-a244-5cb80bc0ab66");
|
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)}");
|
Console.WriteLine($"mapping = {JsonConvert.SerializeObject(mapping)}");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = api.GetRequestsAsync().Result;
|
var request = await api.GetRequestsAsync();
|
||||||
Console.WriteLine($"request = {JsonConvert.SerializeObject(request)}");
|
Console.WriteLine($"request = {JsonConvert.SerializeObject(request)}");
|
||||||
|
|
||||||
//var deleteRequestsAsync = api.DeleteRequestsAsync().Result;
|
//var deleteRequestsAsync = api.DeleteRequestsAsync().Result;
|
||||||
@@ -49,15 +50,21 @@ namespace WireMock.Net.Client
|
|||||||
//var resetRequestsAsync = api.ResetRequestsAsync().Result;
|
//var resetRequestsAsync = api.ResetRequestsAsync().Result;
|
||||||
//Console.WriteLine($"ResetRequestsAsync = {resetRequestsAsync.Status}");
|
//Console.WriteLine($"ResetRequestsAsync = {resetRequestsAsync.Status}");
|
||||||
|
|
||||||
var scenarioStates = api.GetScenariosAsync().Result;
|
var scenarioStates = await api.GetScenariosAsync();
|
||||||
Console.WriteLine($"GetScenariosAsync = {JsonConvert.SerializeObject(scenarioStates)}");
|
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)}");
|
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}");
|
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.WriteLine("Press any key to quit");
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<!-- <RuntimeFrameworkVersion>1.0.1</RuntimeFrameworkVersion> -->
|
|
||||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
C# Hello
|
||||||
@@ -21,9 +21,9 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IFileSystemHandler.EnumerateFiles"/>
|
/// <inheritdoc cref="IFileSystemHandler.EnumerateFiles"/>
|
||||||
public IEnumerable<string> EnumerateFiles(string path)
|
public IEnumerable<string> EnumerateFiles(string path, bool includeSubdirectories)
|
||||||
{
|
{
|
||||||
return Directory.EnumerateFiles(path);
|
return includeSubdirectories ? Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) : Directory.EnumerateFiles(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IFileSystemHandler.GetMappingFolder"/>
|
/// <inheritdoc cref="IFileSystemHandler.GetMappingFolder"/>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
StartAdminInterface = true,
|
StartAdminInterface = true,
|
||||||
ReadStaticMappings = true,
|
ReadStaticMappings = true,
|
||||||
WatchStaticMappings = true,
|
WatchStaticMappings = true,
|
||||||
|
WatchStaticMappingsInSubdirectories = true,
|
||||||
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
//{
|
//{
|
||||||
// SaveMapping = true
|
// SaveMapping = true
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace WireMock.Net.StandAlone
|
|||||||
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
||||||
ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"),
|
ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"),
|
||||||
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
||||||
|
WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"),
|
||||||
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping"),
|
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping"),
|
||||||
AdminUsername = parser.GetStringValue("AdminUsername"),
|
AdminUsername = parser.GetStringValue("AdminUsername"),
|
||||||
AdminPassword = parser.GetStringValue("AdminPassword"),
|
AdminPassword = parser.GetStringValue("AdminPassword"),
|
||||||
|
|||||||
@@ -75,8 +75,9 @@ namespace WireMock.Client
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delete (reset) all mappings.
|
/// Delete (reset) all mappings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="reloadStaticMappings">A value indicating whether to reload the static mappings after the reset.</param>
|
||||||
[Post("__admin/mappings/reset")]
|
[Post("__admin/mappings/reset")]
|
||||||
Task<StatusModel> ResetMappingsAsync();
|
Task<StatusModel> ResetMappingsAsync(bool? reloadStaticMappings = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a mapping based on the guid
|
/// Get a mapping based on the guid
|
||||||
|
|||||||
@@ -31,8 +31,9 @@ namespace WireMock.Handlers
|
|||||||
/// Returns an enumerable collection of file names in a specified path.
|
/// Returns an enumerable collection of file names in a specified path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The path.</param>
|
/// <param name="path">The path.</param>
|
||||||
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory specified by path.</returns>
|
/// <param name="includeSubdirectories">A value indicating whether subdirectories should also included when enumerating files.</param>
|
||||||
IEnumerable<string> EnumerateFiles([NotNull] string path);
|
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory (and optionally subdirectories) specified by path.</returns>
|
||||||
|
IEnumerable<string> EnumerateFiles([NotNull] string path, bool includeSubdirectories);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read a static mapping file as text.
|
/// Read a static mapping file as text.
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ namespace WireMock.Handlers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IFileSystemHandler.EnumerateFiles"/>
|
/// <inheritdoc cref="IFileSystemHandler.EnumerateFiles"/>
|
||||||
public IEnumerable<string> EnumerateFiles(string path)
|
public IEnumerable<string> EnumerateFiles(string path, bool includeSubdirectories)
|
||||||
{
|
{
|
||||||
Check.NotNullOrEmpty(path, nameof(path));
|
Check.NotNullOrEmpty(path, nameof(path));
|
||||||
|
|
||||||
return Directory.EnumerateFiles(path);
|
return includeSubdirectories ? Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) : Directory.EnumerateFiles(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IFileSystemHandler.GetMappingFolder"/>
|
/// <inheritdoc cref="IFileSystemHandler.GetMappingFolder"/>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace WireMock.Server
|
|||||||
private const string AdminRequests = "/__admin/requests";
|
private const string AdminRequests = "/__admin/requests";
|
||||||
private const string AdminSettings = "/__admin/settings";
|
private const string AdminSettings = "/__admin/settings";
|
||||||
private const string AdminScenarios = "/__admin/scenarios";
|
private const string AdminScenarios = "/__admin/scenarios";
|
||||||
|
private const string QueryParamReloadStaticMappings = "reloadStaticMappings";
|
||||||
|
|
||||||
private readonly RegexMatcher _adminRequestContentTypeJson = new ContentTypeMatcher(ContentTypeJson, true);
|
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})$");
|
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));
|
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
|
||||||
|
|
||||||
// __admin/mappings/reset
|
// __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}
|
// __admin/mappings/{guid}
|
||||||
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingGet));
|
Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingGet));
|
||||||
@@ -141,7 +142,7 @@ namespace WireMock.Server
|
|||||||
return;
|
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);
|
_settings.Logger.Info("Reading Static MappingFile : '{0}'", filename);
|
||||||
|
|
||||||
@@ -173,9 +174,14 @@ namespace WireMock.Server
|
|||||||
return;
|
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);
|
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", EnhancedFileSystemWatcherTimeoutMs);
|
||||||
|
watcher.IncludeSubdirectories = includeSubdirectories;
|
||||||
|
|
||||||
watcher.Created += (sender, args) =>
|
watcher.Created += (sender, args) =>
|
||||||
{
|
{
|
||||||
_settings.Logger.Info("MappingFile created : '{0}', reading file.", args.FullPath);
|
_settings.Logger.Info("MappingFile created : '{0}', reading file.", args.FullPath);
|
||||||
@@ -551,6 +557,24 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
return ResponseMessageBuilder.Create("Mappings deleted");
|
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
|
#endregion Mappings
|
||||||
|
|
||||||
#region Request/{guid}
|
#region Request/{guid}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ namespace WireMock.Settings
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool? WatchStaticMappings { get; set; }
|
public bool? WatchStaticMappings { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IFluentMockServerSettings.WatchStaticMappingsInSubdirectories"/>
|
||||||
|
[PublicAPI]
|
||||||
|
public bool? WatchStaticMappingsInSubdirectories { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IFluentMockServerSettings.ProxyAndRecordSettings"/>
|
/// <inheritdoc cref="IFluentMockServerSettings.ProxyAndRecordSettings"/>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
public IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ namespace WireMock.Settings
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
bool? WatchStaticMappings { get; set; }
|
bool? WatchStaticMappings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A value indicating whether subdirectories within the static mappings path should be monitored.
|
||||||
|
/// </summary>
|
||||||
|
[PublicAPI]
|
||||||
|
bool? WatchStaticMappingsInSubdirectories { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets if the proxy and record settings.
|
/// Gets or sets if the proxy and record settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ namespace WireMock.Net.Tests
|
|||||||
var staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
var staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
||||||
staticMappingHandlerMock.Setup(m => m.GetMappingFolder()).Returns("folder");
|
staticMappingHandlerMock.Setup(m => m.GetMappingFolder()).Returns("folder");
|
||||||
staticMappingHandlerMock.Setup(m => m.FolderExists(It.IsAny<string>())).Returns(true);
|
staticMappingHandlerMock.Setup(m => m.FolderExists(It.IsAny<string>())).Returns(true);
|
||||||
staticMappingHandlerMock.Setup(m => m.EnumerateFiles(It.IsAny<string>())).Returns(new string[0]);
|
staticMappingHandlerMock.Setup(m => m.EnumerateFiles(It.IsAny<string>(), It.IsAny<bool>())).Returns(new string[0]);
|
||||||
|
|
||||||
var server = FluentMockServer.Start(new FluentMockServerSettings
|
var server = FluentMockServer.Start(new FluentMockServerSettings
|
||||||
{
|
{
|
||||||
@@ -184,7 +184,7 @@ namespace WireMock.Net.Tests
|
|||||||
// Assert and Verify
|
// Assert and Verify
|
||||||
staticMappingHandlerMock.Verify(m => m.GetMappingFolder(), Times.Once);
|
staticMappingHandlerMock.Verify(m => m.GetMappingFolder(), Times.Once);
|
||||||
staticMappingHandlerMock.Verify(m => m.FolderExists("folder"), 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]
|
[Fact]
|
||||||
|
|||||||
Reference in New Issue
Block a user