mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-01 15:13:33 +02:00
EnhancedFileSystemWatcher (#86)
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
"UseTransformer": false,
|
"UseTransformer": false,
|
||||||
"Headers": {
|
"Headers": {
|
||||||
"Date": "Wed, 25 Oct 2017 18:57:40 GMT",
|
"Date": "Wed, 27 Oct 2017 18:57:40 GMT",
|
||||||
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
|
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
|
||||||
"Referrer-Policy": "no-referrer",
|
"Referrer-Policy": "no-referrer",
|
||||||
"Connection": "close"
|
"Connection": "close"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
Urls = new[] { url1, url2, url3 },
|
Urls = new[] { url1, url2, url3 },
|
||||||
StartAdminInterface = true,
|
StartAdminInterface = true,
|
||||||
ReadStaticMappings = true,
|
ReadStaticMappings = true,
|
||||||
|
WatchStaticMappings = true,
|
||||||
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
//ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
//{
|
//{
|
||||||
// SaveMapping = true
|
// SaveMapping = true
|
||||||
|
|||||||
@@ -43,6 +43,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"),
|
||||||
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping", true),
|
AllowPartialMapping = parser.GetBoolValue("AllowPartialMapping", true),
|
||||||
AdminUsername = parser.GetStringValue("AdminUsername"),
|
AdminUsername = parser.GetStringValue("AdminUsername"),
|
||||||
AdminPassword = parser.GetStringValue("AdminPassword"),
|
AdminPassword = parser.GetStringValue("AdminPassword"),
|
||||||
|
|||||||
@@ -10,29 +10,20 @@ namespace WireMock.Admin.Mappings
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the unique identifier.
|
/// Gets or sets the unique identifier.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
|
||||||
/// The unique identifier.
|
|
||||||
/// </value>
|
|
||||||
public Guid? Guid { get; set; }
|
public Guid? Guid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the unique title.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The unique title.
|
/// The unique title.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the priority.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The priority.
|
/// The priority.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public int? Priority { get; set; }
|
public int? Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Scenario.
|
/// The Scenario.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Scenario { get; set; }
|
public string Scenario { get; set; }
|
||||||
|
|
||||||
@@ -48,19 +39,13 @@ namespace WireMock.Admin.Mappings
|
|||||||
public object SetStateTo { get; set; }
|
public object SetStateTo { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the request.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The request.
|
/// The request.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public RequestModel Request { get; set; }
|
public RequestModel Request { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the response.
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// The response.
|
/// The response.
|
||||||
/// </value>
|
/// </summary>
|
||||||
public ResponseModel Response { get; set; }
|
public ResponseModel Response { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,11 @@ namespace WireMock
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Title { get; }
|
public string Title { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The full filename path for this mapping (only defined for static mappings).
|
||||||
|
/// </summary>
|
||||||
|
public string Path { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the priority.
|
/// Gets the priority.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -63,17 +68,19 @@ namespace WireMock
|
|||||||
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="guid">The unique identifier.</param>
|
/// <param name="guid">The unique identifier.</param>
|
||||||
/// <param name="title">The unique title (can be null_.</param>
|
/// <param name="title">The unique title (can be null).</param>
|
||||||
|
/// <param name="path">The full file path from this mapping title (can be null).</param>
|
||||||
/// <param name="requestMatcher">The request matcher.</param>
|
/// <param name="requestMatcher">The request matcher.</param>
|
||||||
/// <param name="provider">The provider.</param>
|
/// <param name="provider">The provider.</param>
|
||||||
/// <param name="priority">The priority for this mapping.</param>
|
/// <param name="priority">The priority for this mapping.</param>
|
||||||
/// <param name="scenario">The scenario. [Optional]</param>
|
/// <param name="scenario">The scenario. [Optional]</param>
|
||||||
/// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>
|
/// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>
|
||||||
/// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</param>
|
/// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</param>
|
||||||
public Mapping(Guid guid, [CanBeNull] string title, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] object executionConditionState, [CanBeNull] object nextState)
|
public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] object executionConditionState, [CanBeNull] object nextState)
|
||||||
{
|
{
|
||||||
Guid = guid;
|
Guid = guid;
|
||||||
Title = title;
|
Title = title;
|
||||||
|
Path = path;
|
||||||
RequestMatcher = requestMatcher;
|
RequestMatcher = requestMatcher;
|
||||||
Provider = provider;
|
Provider = provider;
|
||||||
Priority = priority;
|
Priority = priority;
|
||||||
|
|||||||
@@ -43,46 +43,7 @@ namespace WireMock.Server
|
|||||||
NullValueHandling = NullValueHandling.Ignore,
|
NullValueHandling = NullValueHandling.Ignore,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
#region InitAdmin
|
||||||
/// Reads the static mappings from a folder.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
|
||||||
[PublicAPI]
|
|
||||||
public void ReadStaticMappings([CanBeNull] string folder = null)
|
|
||||||
{
|
|
||||||
if (folder == null)
|
|
||||||
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
|
||||||
|
|
||||||
if (!Directory.Exists(folder))
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
|
||||||
{
|
|
||||||
ReadStaticMapping(filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reads the static mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">The filename.</param>
|
|
||||||
[PublicAPI]
|
|
||||||
public void ReadStaticMapping([NotNull] string filename)
|
|
||||||
{
|
|
||||||
Check.NotNull(filename, nameof(filename));
|
|
||||||
|
|
||||||
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(filename);
|
|
||||||
|
|
||||||
if (Guid.TryParse(filenameWithoutExtension, out var guidFromFilename))
|
|
||||||
{
|
|
||||||
DeserializeAndAddMapping(File.ReadAllText(filename), guidFromFilename);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DeserializeAndAddMapping(File.ReadAllText(filename));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitAdmin()
|
private void InitAdmin()
|
||||||
{
|
{
|
||||||
// __admin/settings
|
// __admin/settings
|
||||||
@@ -129,6 +90,96 @@ namespace WireMock.Server
|
|||||||
// __admin/scenarios/reset
|
// __admin/scenarios/reset
|
||||||
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(ScenariosReset));
|
Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvider(ScenariosReset));
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region StaticMappings
|
||||||
|
/// <summary>
|
||||||
|
/// Reads the static mappings from a folder.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void ReadStaticMappings([CanBeNull] string folder = null)
|
||||||
|
{
|
||||||
|
if (folder == null)
|
||||||
|
{
|
||||||
|
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
||||||
|
{
|
||||||
|
ReadStaticMappingAndAddOrUpdate(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Watches the static mappings for changes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void WatchStaticMappings([CanBeNull] string folder = null)
|
||||||
|
{
|
||||||
|
if (folder == null)
|
||||||
|
{
|
||||||
|
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 500);
|
||||||
|
watcher.Created += (sender, args) =>
|
||||||
|
{
|
||||||
|
ReadStaticMappingAndAddOrUpdate(args.FullPath);
|
||||||
|
};
|
||||||
|
watcher.Changed += (sender, args) =>
|
||||||
|
{
|
||||||
|
ReadStaticMappingAndAddOrUpdate(args.FullPath);
|
||||||
|
};
|
||||||
|
watcher.Deleted += (sender, args) =>
|
||||||
|
{
|
||||||
|
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);
|
||||||
|
|
||||||
|
if (Guid.TryParse(filenameWithoutExtension, out var guidFromFilename))
|
||||||
|
{
|
||||||
|
DeleteMapping(guidFromFilename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeleteMapping(args.FullPath);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
watcher.EnableRaisingEvents = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a static mapping file and adds or updates the mapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path.</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void ReadStaticMappingAndAddOrUpdate([NotNull] string path)
|
||||||
|
{
|
||||||
|
Check.NotNull(path, nameof(path));
|
||||||
|
|
||||||
|
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||||
|
|
||||||
|
if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
|
||||||
|
{
|
||||||
|
DeserializeAndAddOrUpdateMapping(FileHelper.ReadAllText(path), guidFromFilename, path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeserializeAndAddOrUpdateMapping(FileHelper.ReadAllText(path), null, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Proxy and Record
|
#region Proxy and Record
|
||||||
private HttpClient _httpClientForProxy;
|
private HttpClient _httpClientForProxy;
|
||||||
@@ -185,7 +236,7 @@ namespace WireMock.Server
|
|||||||
|
|
||||||
var response = Response.Create(responseMessage);
|
var response = Response.Create(responseMessage);
|
||||||
|
|
||||||
return new Mapping(Guid.NewGuid(), string.Empty, request, response, 0, null, null, null);
|
return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -228,7 +279,9 @@ namespace WireMock.Server
|
|||||||
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
|
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
|
||||||
|
|
||||||
if (mapping == null)
|
if (mapping == null)
|
||||||
|
{
|
||||||
return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };
|
return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };
|
||||||
|
}
|
||||||
|
|
||||||
var model = MappingConverter.ToMappingModel(mapping);
|
var model = MappingConverter.ToMappingModel(mapping);
|
||||||
|
|
||||||
@@ -238,23 +291,8 @@ namespace WireMock.Server
|
|||||||
private ResponseMessage MappingPut(RequestMessage requestMessage)
|
private ResponseMessage MappingPut(RequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
||||||
var mappingModel = JsonConvert.DeserializeObject<MappingModel>(requestMessage.Body);
|
|
||||||
|
|
||||||
if (mappingModel.Request == null)
|
DeserializeAndAddOrUpdateMapping(requestMessage.Body, guid);
|
||||||
return new ResponseMessage { StatusCode = 400, Body = "Request missing" };
|
|
||||||
|
|
||||||
if (mappingModel.Response == null)
|
|
||||||
return new ResponseMessage { StatusCode = 400, Body = "Response missing" };
|
|
||||||
|
|
||||||
var requestBuilder = InitRequestBuilder(mappingModel.Request);
|
|
||||||
var responseBuilder = InitResponseBuilder(mappingModel.Response);
|
|
||||||
|
|
||||||
IRespondWithAProvider respondProvider = Given(requestBuilder).WithGuid(guid);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(mappingModel.Title))
|
|
||||||
respondProvider = respondProvider.WithTitle(mappingModel.Title);
|
|
||||||
|
|
||||||
respondProvider.RespondWith(responseBuilder);
|
|
||||||
|
|
||||||
return new ResponseMessage { Body = "Mapping added or updated" };
|
return new ResponseMessage { Body = "Mapping added or updated" };
|
||||||
}
|
}
|
||||||
@@ -264,7 +302,9 @@ namespace WireMock.Server
|
|||||||
Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
|
Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
|
||||||
|
|
||||||
if (DeleteMapping(guid))
|
if (DeleteMapping(guid))
|
||||||
|
{
|
||||||
return new ResponseMessage { Body = "Mapping removed" };
|
return new ResponseMessage { Body = "Mapping removed" };
|
||||||
|
}
|
||||||
|
|
||||||
return new ResponseMessage { Body = "Mapping not found" };
|
return new ResponseMessage { Body = "Mapping not found" };
|
||||||
}
|
}
|
||||||
@@ -285,7 +325,9 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||||
if (!Directory.Exists(folder))
|
if (!Directory.Exists(folder))
|
||||||
|
{
|
||||||
Directory.CreateDirectory(folder);
|
Directory.CreateDirectory(folder);
|
||||||
|
}
|
||||||
|
|
||||||
var model = MappingConverter.ToMappingModel(mapping);
|
var model = MappingConverter.ToMappingModel(mapping);
|
||||||
string json = JsonConvert.SerializeObject(model, _settings);
|
string json = JsonConvert.SerializeObject(model, _settings);
|
||||||
@@ -315,7 +357,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
DeserializeAndAddMapping(requestMessage.Body);
|
DeserializeAndAddOrUpdateMapping(requestMessage.Body);
|
||||||
}
|
}
|
||||||
catch (ArgumentException a)
|
catch (ArgumentException a)
|
||||||
{
|
{
|
||||||
@@ -329,7 +371,7 @@ namespace WireMock.Server
|
|||||||
return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };
|
return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeserializeAndAddMapping(string json, Guid? guid = null)
|
private void DeserializeAndAddOrUpdateMapping(string json, Guid? guid = null, string path = null)
|
||||||
{
|
{
|
||||||
var mappingModel = JsonConvert.DeserializeObject<MappingModel>(json);
|
var mappingModel = JsonConvert.DeserializeObject<MappingModel>(json);
|
||||||
|
|
||||||
@@ -351,11 +393,20 @@ namespace WireMock.Server
|
|||||||
respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
|
respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
respondProvider = respondProvider.WithPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(mappingModel.Title))
|
if (!string.IsNullOrEmpty(mappingModel.Title))
|
||||||
|
{
|
||||||
respondProvider = respondProvider.WithTitle(mappingModel.Title);
|
respondProvider = respondProvider.WithTitle(mappingModel.Title);
|
||||||
|
}
|
||||||
|
|
||||||
if (mappingModel.Priority != null)
|
if (mappingModel.Priority != null)
|
||||||
|
{
|
||||||
respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
|
respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
|
||||||
|
}
|
||||||
|
|
||||||
if (mappingModel.Scenario != null)
|
if (mappingModel.Scenario != null)
|
||||||
{
|
{
|
||||||
@@ -688,7 +739,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
Body = JsonConvert.SerializeObject(result, _settings),
|
Body = JsonConvert.SerializeObject(result, _settings),
|
||||||
StatusCode = 200,
|
StatusCode = 200,
|
||||||
Headers = new Dictionary<string, WireMockList<string>> { { "Content-Type", new WireMockList<string>("application/json") } }
|
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>("application/json") } }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using WireMock.RequestBuilders;
|
|||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
using WireMock.Owin;
|
using WireMock.Owin;
|
||||||
|
using WireMock.Serialization;
|
||||||
|
|
||||||
namespace WireMock.Server
|
namespace WireMock.Server
|
||||||
{
|
{
|
||||||
@@ -202,6 +203,11 @@ namespace WireMock.Server
|
|||||||
ReadStaticMappings();
|
ReadStaticMappings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (settings.WatchStaticMappings == true)
|
||||||
|
{
|
||||||
|
WatchStaticMappings();
|
||||||
|
}
|
||||||
|
|
||||||
if (settings.ProxyAndRecordSettings != null)
|
if (settings.ProxyAndRecordSettings != null)
|
||||||
{
|
{
|
||||||
InitProxyAndRecord(settings.ProxyAndRecordSettings);
|
InitProxyAndRecord(settings.ProxyAndRecordSettings);
|
||||||
@@ -274,7 +280,18 @@ namespace WireMock.Server
|
|||||||
public bool DeleteMapping(Guid guid)
|
public bool DeleteMapping(Guid guid)
|
||||||
{
|
{
|
||||||
// Check a mapping exists with the same GUID, if so, remove it.
|
// Check a mapping exists with the same GUID, if so, remove it.
|
||||||
var existingMapping = _options.Mappings.FirstOrDefault(m => m.Guid == guid);
|
return DeleteMapping(m => m.Guid == guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DeleteMapping(string path)
|
||||||
|
{
|
||||||
|
// Check a mapping exists with the same path, if so, remove it.
|
||||||
|
return DeleteMapping(m => string.Equals(m.Path, path, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool DeleteMapping(Func<Mapping, bool> predicate)
|
||||||
|
{
|
||||||
|
var existingMapping = _options.Mappings.FirstOrDefault(predicate);
|
||||||
if (existingMapping != null)
|
if (existingMapping != null)
|
||||||
{
|
{
|
||||||
_options.Mappings.Remove(existingMapping);
|
_options.Mappings.Remove(existingMapping);
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ namespace WireMock.Server
|
|||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||||
IRespondWithAProvider WithTitle(string title);
|
IRespondWithAProvider WithTitle(string title);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Define the full filepath for this mapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The full filepath.</param>
|
||||||
|
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||||
|
IRespondWithAProvider WithPath(string path);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Define a unique identifier for this mapping.
|
/// Define a unique identifier for this mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -11,18 +11,11 @@ namespace WireMock.Server
|
|||||||
private int _priority;
|
private int _priority;
|
||||||
private Guid? _guid;
|
private Guid? _guid;
|
||||||
private string _title;
|
private string _title;
|
||||||
|
private string _path;
|
||||||
private object _executionConditionState;
|
private object _executionConditionState;
|
||||||
private object _nextState;
|
private object _nextState;
|
||||||
private string _scenario;
|
private string _scenario;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _registration callback.
|
|
||||||
/// </summary>
|
|
||||||
private readonly RegistrationCallback _registrationCallback;
|
private readonly RegistrationCallback _registrationCallback;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The _request matcher.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IRequestMatcher _requestMatcher;
|
private readonly IRequestMatcher _requestMatcher;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -39,30 +32,20 @@ namespace WireMock.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The respond with.
|
/// The respond with.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="provider">
|
/// <param name="provider">The provider.</param>
|
||||||
/// The provider.
|
|
||||||
/// </param>
|
|
||||||
public void RespondWith(IResponseProvider provider)
|
public void RespondWith(IResponseProvider provider)
|
||||||
{
|
{
|
||||||
var mappingGuid = _guid ?? Guid.NewGuid();
|
var mappingGuid = _guid ?? Guid.NewGuid();
|
||||||
_registrationCallback(new Mapping(mappingGuid, _title, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState));
|
_registrationCallback(new Mapping(mappingGuid, _title, _path, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>
|
||||||
/// Define a unique identifier for this mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="guid">The unique identifier.</param>
|
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
public IRespondWithAProvider WithGuid(string guid)
|
public IRespondWithAProvider WithGuid(string guid)
|
||||||
{
|
{
|
||||||
return WithGuid(Guid.Parse(guid));
|
return WithGuid(Guid.Parse(guid));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>
|
||||||
/// Define a unique identifier for this mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="guid">The unique identifier.</param>
|
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
public IRespondWithAProvider WithGuid(Guid guid)
|
public IRespondWithAProvider WithGuid(Guid guid)
|
||||||
{
|
{
|
||||||
_guid = guid;
|
_guid = guid;
|
||||||
@@ -70,11 +53,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithTitle"/>
|
||||||
/// Define a unique identifier for this mapping.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="title">The unique identifier.</param>
|
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
public IRespondWithAProvider WithTitle(string title)
|
public IRespondWithAProvider WithTitle(string title)
|
||||||
{
|
{
|
||||||
_title = title;
|
_title = title;
|
||||||
@@ -82,11 +61,15 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <see cref="IRespondWithAProvider.WithPath"/>
|
||||||
/// Define the priority for this mapping.
|
public IRespondWithAProvider WithPath(string path)
|
||||||
/// </summary>
|
{
|
||||||
/// <param name="priority">The priority.</param>
|
_path = path;
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.AtPriority"/>
|
||||||
public IRespondWithAProvider AtPriority(int priority)
|
public IRespondWithAProvider AtPriority(int priority)
|
||||||
{
|
{
|
||||||
_priority = priority;
|
_priority = priority;
|
||||||
@@ -94,6 +77,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.InScenario(string)"/>
|
||||||
public IRespondWithAProvider InScenario(string scenario)
|
public IRespondWithAProvider InScenario(string scenario)
|
||||||
{
|
{
|
||||||
_scenario = scenario;
|
_scenario = scenario;
|
||||||
@@ -101,6 +85,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.WhenStateIs"/>
|
||||||
public IRespondWithAProvider WhenStateIs(object state)
|
public IRespondWithAProvider WhenStateIs(object state)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_scenario))
|
if (string.IsNullOrEmpty(_scenario))
|
||||||
@@ -118,6 +103,7 @@ namespace WireMock.Server
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <see cref="IRespondWithAProvider.WillSetStateTo"/>
|
||||||
public IRespondWithAProvider WillSetStateTo(object state)
|
public IRespondWithAProvider WillSetStateTo(object state)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_scenario))
|
if (string.IsNullOrEmpty(_scenario))
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ namespace WireMock.Settings
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public bool? ReadStaticMappings { get; set; }
|
public bool? ReadStaticMappings { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IFluentMockServerSettings.WatchStaticMappings"/>
|
||||||
|
[PublicAPI]
|
||||||
|
public bool? WatchStaticMappings { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="IFluentMockServerSettings.ProxyAndRecordSettings"/>
|
/// <inheritdoc cref="IFluentMockServerSettings.ProxyAndRecordSettings"/>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
public IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ namespace WireMock.Settings
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool? ReadStaticMappings { get; set; }
|
bool? ReadStaticMappings { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Watch the static mapping files + folder for changes when running.
|
||||||
|
/// </summary>
|
||||||
|
bool? WatchStaticMappings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets if the proxy and record settings.
|
/// Gets or sets if the proxy and record settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
29
src/WireMock.Net/Util/FileHelper.cs
Normal file
29
src/WireMock.Net/Util/FileHelper.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
internal static class FileHelper
|
||||||
|
{
|
||||||
|
private const int NumberOfRetries = 3;
|
||||||
|
private const int DelayOnRetry = 500;
|
||||||
|
|
||||||
|
public static string ReadAllText(string path)
|
||||||
|
{
|
||||||
|
for (int i = 1; i <= NumberOfRetries; ++i)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return File.ReadAllText(path);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// You may check error code to filter some exceptions, not every error can be recovered.
|
||||||
|
Thread.Sleep(DelayOnRetry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
|
<PackageReference Include="JetBrains.Annotations" Version="11.1.0">
|
||||||
<PrivateAssets>All</PrivateAssets>
|
<PrivateAssets>All</PrivateAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Handlebars.Net" Version="1.9.0" />
|
<PackageReference Include="Handlebars.Net" Version="1.9.0" />
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
|
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||||
<PackageReference Include="RestEase" Version="1.4.4" />
|
<PackageReference Include="RestEase" Version="1.4.4" />
|
||||||
|
<PackageReference Include="EnhancedFileSystemWatcher" Version="1.0.0" />
|
||||||
<!--<PackageReference Include="OpenSSL.X509Certificate2.Provider" Version="1.0.2" />-->
|
<!--<PackageReference Include="OpenSSL.X509Certificate2.Provider" Version="1.0.2" />-->
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace WireMock.Net.Tests
|
|||||||
_server = FluentMockServer.Start();
|
_server = FluentMockServer.Start();
|
||||||
|
|
||||||
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", "documentdb_root.json");
|
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", "documentdb_root.json");
|
||||||
_server.ReadStaticMapping(folder);
|
_server.ReadStaticMappingAndAddOrUpdate(folder);
|
||||||
|
|
||||||
var mappings = _server.Mappings.ToArray();
|
var mappings = _server.Mappings.ToArray();
|
||||||
Check.That(mappings).HasSize(1);
|
Check.That(mappings).HasSize(1);
|
||||||
@@ -65,7 +65,7 @@ namespace WireMock.Net.Tests
|
|||||||
|
|
||||||
_server = FluentMockServer.Start();
|
_server = FluentMockServer.Start();
|
||||||
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
|
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
|
||||||
_server.ReadStaticMapping(folder);
|
_server.ReadStaticMappingAndAddOrUpdate(folder);
|
||||||
|
|
||||||
var mappings = _server.Mappings.ToArray();
|
var mappings = _server.Mappings.ToArray();
|
||||||
Check.That(mappings).HasSize(1);
|
Check.That(mappings).HasSize(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user