Add SaveToFile in the mapping (#284)

* savetofile

* fix !
This commit is contained in:
Stef Heyenrath
2019-06-17 20:34:16 +02:00
committed by GitHub
parent 561bb75f9f
commit 7a4814e335
32 changed files with 277 additions and 168 deletions

View File

@@ -39,13 +39,18 @@ namespace WireMock.Admin.Mappings
public string SetStateTo { get; set; }
/// <summary>
/// The request.
/// The request model.
/// </summary>
public RequestModel Request { get; set; }
/// <summary>
/// The response.
/// The response model.
/// </summary>
public ResponseModel Response { get; set; }
/// <summary>
/// Saves this mapping as a static mapping file.
/// </summary>
public bool? SaveToFile { get; set; }
}
}

View File

@@ -58,9 +58,9 @@ namespace WireMock.Admin.Mappings
public EncodingModel BodyEncoding { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [use transformer].
/// Use Handlebars transformer.
/// </summary>
public bool UseTransformer { get; set; }
public bool? UseTransformer { get; set; }
/// <summary>
/// Gets or sets the headers.

View File

@@ -1,6 +1,7 @@
using System;
using JetBrains.Annotations;
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Handlers;
using WireMock.Matchers.Request;
using WireMock.ResponseProviders;
@@ -60,6 +61,11 @@ namespace WireMock
/// </summary>
IResponseProvider Provider { get; }
/// <summary>
/// The FileSystemHandler.
/// </summary>
IFileSystemHandler FileSystemHandler { get; }
/// <summary>
/// Is State started ?
/// </summary>

View File

@@ -1,6 +1,7 @@
using System;
using JetBrains.Annotations;
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Handlers;
using WireMock.Matchers.Request;
using WireMock.ResponseProviders;
@@ -38,6 +39,9 @@ namespace WireMock
/// <inheritdoc cref="IMapping.Provider" />
public IResponseProvider Provider { get; }
/// <inheritdoc cref="IMapping.FileSystemHandler" />
public IFileSystemHandler FileSystemHandler { get; }
/// <inheritdoc cref="IMapping.IsStartState" />
public bool IsStartState => Scenario == null || Scenario != null && NextState != null && ExecutionConditionState == null;
@@ -50,17 +54,21 @@ namespace WireMock
/// <param name="guid">The unique identifier.</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="fileSystemHandler">The fileSystemHandler.</param>
/// <param name="requestMatcher">The request matcher.</param>
/// <param name="provider">The provider.</param>
/// <param name="priority">The priority for this mapping.</param>
/// <param name="scenario">The scenario. [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>
public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IResponseProvider provider, int priority, [CanBeNull] string scenario, [CanBeNull] string executionConditionState, [CanBeNull] string nextState)
public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path,
[NotNull] IFileSystemHandler fileSystemHandler, [NotNull] IRequestMatcher requestMatcher, [NotNull] IResponseProvider provider,
int priority, [CanBeNull] string scenario, [CanBeNull] string executionConditionState, [CanBeNull] string nextState)
{
Guid = guid;
Title = title;
Path = path;
FileSystemHandler = fileSystemHandler;
RequestMatcher = requestMatcher;
Provider = provider;
Priority = priority;
@@ -72,7 +80,7 @@ namespace WireMock
/// <inheritdoc cref="IMapping.ResponseToAsync" />
public async Task<ResponseMessage> ResponseToAsync(RequestMessage requestMessage)
{
return await Provider.ProvideResponseAsync(requestMessage);
return await Provider.ProvideResponseAsync(requestMessage, FileSystemHandler);
}
/// <inheritdoc cref="IMapping.GetRequestMatchResult" />

View File

@@ -4,5 +4,6 @@
/// The registration callback.
/// </summary>
/// <param name="mapping">The mapping.</param>
public delegate void RegistrationCallback(IMapping mapping);
/// <param name="saveToFile">Optional boolean to indicate if this mapping should be saved as static mapping file.</param>
public delegate void RegistrationCallback(IMapping mapping, bool saveToFile = false);
}

View File

@@ -21,8 +21,6 @@ namespace WireMock.ResponseBuilders
/// </summary>
public class Response : IResponseBuilder
{
private readonly IFileSystemHandler _fileSystemHandler;
private readonly ResponseMessageTransformer _responseMessageTransformer;
private HttpClient _httpClientForProxy;
/// <summary>
@@ -94,9 +92,6 @@ namespace WireMock.ResponseBuilders
private Response(ResponseMessage responseMessage)
{
ResponseMessage = responseMessage;
_fileSystemHandler = new LocalFileSystemHandler();
_responseMessageTransformer = new ResponseMessageTransformer(_fileSystemHandler);
}
/// <summary>
@@ -225,18 +220,17 @@ namespace WireMock.ResponseBuilders
ResponseMessage.BodyData = new BodyData
{
BodyAsFileIsCached = cache
BodyAsFileIsCached = cache,
BodyAsFile = filename
};
if (cache && !UseTransformer)
{
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
ResponseMessage.BodyData.BodyAsBytes = _fileSystemHandler.ReadResponseBodyAsFile(filename);
}
else
{
ResponseMessage.BodyData.DetectedBodyType = BodyType.File;
ResponseMessage.BodyData.BodyAsFile = filename;
}
return this;
@@ -377,12 +371,7 @@ namespace WireMock.ResponseBuilders
return this;
}
/// <summary>
/// The provide response.
/// </summary>
/// <param name="requestMessage">The request.</param>
/// <returns>The <see cref="ResponseMessage"/>.</returns>
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IFileSystemHandler fileSystemHandler)
{
Check.NotNull(requestMessage, nameof(requestMessage));
@@ -421,10 +410,16 @@ namespace WireMock.ResponseBuilders
if (UseTransformer)
{
return _responseMessageTransformer.Transform(requestMessage, ResponseMessage);
var responseMessageTransformer = new ResponseMessageTransformer(fileSystemHandler);
return responseMessageTransformer.Transform(requestMessage, ResponseMessage);
}
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
{
ResponseMessage.BodyData.BodyAsBytes = fileSystemHandler.ReadResponseBodyAsFile(ResponseMessage.BodyData.BodyAsFile);
ResponseMessage.BodyData.BodyAsFile = null;
}
// Just return normal defined ResponseMessage
return ResponseMessage;
}
}

View File

@@ -27,7 +27,11 @@ namespace WireMock
response.BodyData = new BodyData
{
DetectedBodyType = BodyType.Json,
BodyAsJson = new StatusModel { Status = message, Guid = guid }
BodyAsJson = new StatusModel
{
Guid = guid,
Status = message
}
};
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Validation;
using WireMock.Handlers;
namespace WireMock.ResponseProviders
{
@@ -9,14 +8,12 @@ namespace WireMock.ResponseProviders
{
private readonly Func<RequestMessage, Task<ResponseMessage>> _responseMessageFunc;
public DynamicAsyncResponseProvider([NotNull] Func<RequestMessage, Task<ResponseMessage>> responseMessageFunc)
public DynamicAsyncResponseProvider(Func<RequestMessage, Task<ResponseMessage>> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
_responseMessageFunc = responseMessageFunc;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IFileSystemHandler fileSystemHandler)
{
return _responseMessageFunc(requestMessage);
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Validation;
using WireMock.Handlers;
namespace WireMock.ResponseProviders
{
@@ -9,14 +8,12 @@ namespace WireMock.ResponseProviders
{
private readonly Func<RequestMessage, ResponseMessage> _responseMessageFunc;
public DynamicResponseProvider([NotNull] Func<RequestMessage, ResponseMessage> responseMessageFunc)
public DynamicResponseProvider(Func<RequestMessage, ResponseMessage> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
_responseMessageFunc = responseMessageFunc;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IFileSystemHandler fileSystemHandler)
{
return Task.FromResult(_responseMessageFunc(requestMessage));
}

View File

@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Handlers;
namespace WireMock.ResponseProviders
{
@@ -12,7 +13,8 @@ namespace WireMock.ResponseProviders
/// The provide response.
/// </summary>
/// <param name="requestMessage">The request.</param>
/// <param name="fileSystemHandler">The fileSystemHandler.</param>
/// <returns>The <see cref="ResponseMessage"/>.</returns>
Task<ResponseMessage> ProvideResponseAsync([NotNull] RequestMessage requestMessage);
Task<ResponseMessage> ProvideResponseAsync([NotNull] RequestMessage requestMessage, [NotNull] IFileSystemHandler fileSystemHandler);
}
}

View File

@@ -1,26 +1,22 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Handlers;
using WireMock.Settings;
using WireMock.Validation;
namespace WireMock.ResponseProviders
{
internal class ProxyAsyncResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> _responseMessageFunc;
private readonly IProxyAndRecordSettings _settings;
private readonly Func<RequestMessage, IFluentMockServerSettings, Task<ResponseMessage>> _responseMessageFunc;
private readonly IFluentMockServerSettings _settings;
public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> responseMessageFunc, [NotNull] IProxyAndRecordSettings settings)
public ProxyAsyncResponseProvider(Func<RequestMessage, IFluentMockServerSettings, Task<ResponseMessage>> responseMessageFunc, IFluentMockServerSettings settings)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
Check.NotNull(settings, nameof(settings));
_responseMessageFunc = responseMessageFunc;
_settings = settings;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IFileSystemHandler fileSystemHandler)
{
return _responseMessageFunc(requestMessage, _settings);
}

View File

@@ -28,7 +28,7 @@ namespace WireMock.Serialization
{
Guid = mapping.Guid,
Title = mapping.Title,
Priority = mapping.Priority,
Priority = mapping.Priority != 0 ? mapping.Priority : (int?) null,
Scenario = mapping.Scenario,
WhenStateIs = mapping.ExecutionConditionState,
SetStateTo = mapping.NextState,
@@ -66,7 +66,7 @@ namespace WireMock.Serialization
Params = paramsMatchers != null && paramsMatchers.Any() ? paramsMatchers.Select(pm => new ParamModel
{
Name = pm.Key,
IgnoreCase = pm.IgnoreCase,
IgnoreCase = pm.IgnoreCase == true ? true : (bool?) null,
Matchers = MatcherMapper.Map(pm.Matchers)
}).ToList() : null,
@@ -92,7 +92,7 @@ namespace WireMock.Serialization
mappingModel.Response.BodyAsBytes = null;
mappingModel.Response.BodyAsFile = null;
mappingModel.Response.BodyAsFileIsCached = null;
mappingModel.Response.UseTransformer = false;
mappingModel.Response.UseTransformer = null;
mappingModel.Response.BodyEncoding = null;
mappingModel.Response.ProxyUrl = response.ProxyUrl;
}
@@ -101,7 +101,10 @@ namespace WireMock.Serialization
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
mappingModel.Response.Headers = Map(response.ResponseMessage.Headers);
mappingModel.Response.UseTransformer = response.UseTransformer;
if (response.UseTransformer)
{
mappingModel.Response.UseTransformer = response.UseTransformer;
}
if (response.ResponseMessage.BodyData != null)
{
@@ -113,7 +116,10 @@ namespace WireMock.Serialization
case BodyType.Json:
mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyData.BodyAsJson;
mappingModel.Response.BodyAsJsonIndented = response.ResponseMessage.BodyData.BodyAsJsonIndented;
if (response.ResponseMessage.BodyData.BodyAsJsonIndented == true)
{
mappingModel.Response.BodyAsJsonIndented = response.ResponseMessage.BodyData.BodyAsJsonIndented;
}
break;
case BodyType.Bytes:

View File

@@ -43,7 +43,7 @@ namespace WireMock.Server
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__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 _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/requests\/([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 JsonSerializerSettings _settings = new JsonSerializerSettings
private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore
@@ -242,23 +242,23 @@ namespace WireMock.Server
respondProvider.AtPriority(ProxyPriority);
}
respondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings.ProxyAndRecordSettings));
respondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
}
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings settings)
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IFluentMockServerSettings settings)
{
var requestUri = new Uri(requestMessage.Url);
var proxyUri = new Uri(settings.Url);
var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
if (settings.SaveMapping)
if (settings.ProxyAndRecordSettings.SaveMapping)
{
var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { });
var mapping = ToMapping(requestMessage, responseMessage, settings.ProxyAndRecordSettings.BlackListedHeaders ?? new string[] { });
_options.Mappings.TryAdd(mapping.Guid, mapping);
if (settings.SaveMappingToFile)
if (settings.ProxyAndRecordSettings.SaveMappingToFile)
{
SaveMappingToFile(mapping);
}
@@ -302,7 +302,7 @@ namespace WireMock.Server
var response = Response.Create(responseMessage);
return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);
return new Mapping(Guid.NewGuid(), string.Empty, null, _fileSystemHandler, request, response, 0, null, null, null);
}
#endregion
@@ -407,7 +407,7 @@ namespace WireMock.Server
_logger.Info("Saving Mapping file {0}", filename);
_fileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, _settings));
_fileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, _jsonSerializerSettings));
}
private static string SanitizeFileName(string name, char replaceChar = '_')
@@ -471,7 +471,7 @@ namespace WireMock.Server
var responseBuilder = InitResponseBuilder(mappingModel.Response);
var respondProvider = Given(requestBuilder);
var respondProvider = Given(requestBuilder, mappingModel.SaveToFile == true);
if (guid != null)
{
@@ -722,7 +722,7 @@ namespace WireMock.Server
responseBuilder = responseBuilder.WithDelay(responseModel.Delay.Value);
}
if (responseModel.UseTransformer)
if (responseModel.UseTransformer == true)
{
responseBuilder = responseBuilder.WithTransformer();
}
@@ -793,7 +793,7 @@ namespace WireMock.Server
BodyData = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings)
BodyAsString = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _jsonSerializerSettings)
},
StatusCode = 200,
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>(ContentTypeJson) } }

View File

@@ -203,7 +203,7 @@ namespace WireMock.Server
Urls = new[] { $"{(settings.UseSSL == true ? "https" : "http")}://localhost:{port}" };
}
_options.FileSystemHandler = settings.FileSystemHandler;
_options.FileSystemHandler = _fileSystemHandler;
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
_options.Logger = _logger;
@@ -430,14 +430,15 @@ namespace WireMock.Server
/// The given.
/// </summary>
/// <param name="requestMatcher">The request matcher.</param>
/// <param name="saveToFile">Optional boolean to indicate if this mapping should be saved as static mapping file.</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
[PublicAPI]
public IRespondWithAProvider Given(IRequestMatcher requestMatcher)
public IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false)
{
return new RespondWithAProvider(RegisterMapping, requestMatcher);
return new RespondWithAProvider(RegisterMapping, requestMatcher, _fileSystemHandler, saveToFile);
}
private void RegisterMapping(IMapping mapping)
private void RegisterMapping(IMapping mapping, bool saveToFile)
{
// Check a mapping exists with the same Guid, if so, replace it.
if (_options.Mappings.ContainsKey(mapping.Guid))
@@ -448,6 +449,11 @@ namespace WireMock.Server
{
_options.Mappings.TryAdd(mapping.Guid, mapping);
}
if (saveToFile)
{
SaveMappingToFile(mapping);
}
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using WireMock.Handlers;
using WireMock.Matchers.Request;
using WireMock.ResponseProviders;
@@ -17,6 +18,8 @@ namespace WireMock.Server
private string _scenario;
private readonly RegistrationCallback _registrationCallback;
private readonly IRequestMatcher _requestMatcher;
private readonly IFileSystemHandler _fileSystemHandler;
private readonly bool _saveToFile;
public Guid Guid { get; private set; } = Guid.NewGuid();
@@ -25,10 +28,14 @@ namespace WireMock.Server
/// </summary>
/// <param name="registrationCallback">The registration callback.</param>
/// <param name="requestMatcher">The request matcher.</param>
public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher)
/// <param name="fileSystemHandler">The fileSystemHandler.</param>
/// <param name="saveToFile">Optional boolean to indicate if this mapping should be saved as static mapping file.</param>
public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher, IFileSystemHandler fileSystemHandler, bool saveToFile = false)
{
_registrationCallback = registrationCallback;
_requestMatcher = requestMatcher;
_fileSystemHandler = fileSystemHandler;
_saveToFile = saveToFile;
}
/// <summary>
@@ -37,7 +44,7 @@ namespace WireMock.Server
/// <param name="provider">The provider.</param>
public void RespondWith(IResponseProvider provider)
{
_registrationCallback(new Mapping(Guid, _title, _path, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState));
_registrationCallback(new Mapping(Guid, _title, _path, _fileSystemHandler, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState), _saveToFile);
}
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>

View File

@@ -82,6 +82,6 @@ namespace WireMock.Settings
/// <inheritdoc cref="IFluentMockServerSettings.FileSystemHandler"/>
[PublicAPI]
[JsonIgnore]
public IFileSystemHandler FileSystemHandler { get; set; } = new LocalFileSystemHandler();
public IFileSystemHandler FileSystemHandler { get; set; }
}
}