Update the logic for ProxyAndRecord (#747)

* .

* set

* .

* .

* .

* .

* prio

* appsettings

* TinyMapperUtils

* set

* p

* nullable

* .

* ,

* fs

* .

* .

* --PreferProxyMapping
This commit is contained in:
Stef Heyenrath
2022-04-21 17:58:44 +02:00
committed by GitHub
parent 9d54994747
commit 2e5bfc41d5
30 changed files with 1900 additions and 1531 deletions

View File

@@ -10,6 +10,7 @@ using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
using Stef.Validation;
using WireMock.Constants;
namespace WireMock.Server
{

File diff suppressed because it is too large Load Diff

View File

@@ -20,511 +20,512 @@ using WireMock.ResponseProviders;
using WireMock.Serialization;
using WireMock.Settings;
namespace WireMock.Server
namespace WireMock.Server;
/// <summary>
/// The fluent mock server.
/// </summary>
public partial class WireMockServer : IWireMockServer
{
private const int ServerStartDelayInMs = 100;
private readonly WireMockServerSettings _settings;
private readonly IOwinSelfHost _httpServer;
private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
private readonly MappingConverter _mappingConverter;
private readonly MatcherMapper _matcherMapper;
private readonly MappingToFileSaver _mappingToFileSaver;
/// <inheritdoc cref="IWireMockServer.IsStarted" />
[PublicAPI]
public bool IsStarted => _httpServer != null && _httpServer.IsStarted;
/// <inheritdoc />
[PublicAPI]
public List<int> Ports { get; }
/// <inheritdoc />
[PublicAPI]
public int Port => Ports?.FirstOrDefault() ?? default(int);
/// <inheritdoc />
[PublicAPI]
public string[] Urls { get; }
/// <inheritdoc />
[PublicAPI]
public string Url => Urls?.FirstOrDefault();
/// <summary>
/// The fluent mock server.
/// Gets the mappings.
/// </summary>
public partial class WireMockServer : IWireMockServer
[PublicAPI]
public IEnumerable<IMapping> Mappings => _options.Mappings.Values.ToArray();
/// <inheritdoc cref="IWireMockServer.MappingModels" />
[PublicAPI]
public IEnumerable<MappingModel> MappingModels => ToMappingModels();
/// <summary>
/// Gets the scenarios.
/// </summary>
[PublicAPI]
public ConcurrentDictionary<string, ScenarioState> Scenarios => new ConcurrentDictionary<string, ScenarioState>(_options.Scenarios);
#region IDisposable Members
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
private const int ServerStartDelayInMs = 100;
Dispose(true);
GC.SuppressFinalize(this);
}
private readonly WireMockServerSettings _settings;
private readonly IOwinSelfHost _httpServer;
private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
private readonly MappingConverter _mappingConverter;
private readonly MatcherMapper _matcherMapper;
private readonly MappingToFileSaver _mappingToFileSaver;
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
DisposeEnhancedFileSystemWatcher();
_httpServer?.StopAsync();
}
#endregion
/// <inheritdoc cref="IWireMockServer.IsStarted" />
[PublicAPI]
public bool IsStarted => _httpServer != null && _httpServer.IsStarted;
#region Start/Stop
/// <summary>
/// Starts this WireMockServer with the specified settings.
/// </summary>
/// <param name="settings">The WireMockServerSettings.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start([NotNull] WireMockServerSettings settings)
{
Guard.NotNull(settings, nameof(settings));
/// <inheritdoc />
[PublicAPI]
public List<int> Ports { get; }
return new WireMockServer(settings);
}
/// <inheritdoc />
[PublicAPI]
public int Port => Ports?.FirstOrDefault() ?? default(int);
/// <inheritdoc />
[PublicAPI]
public string[] Urls { get; }
/// <inheritdoc />
[PublicAPI]
public string Url => Urls?.FirstOrDefault();
/// <summary>
/// Gets the mappings.
/// </summary>
[PublicAPI]
public IEnumerable<IMapping> Mappings => _options.Mappings.Values.ToArray();
/// <inheritdoc cref="IWireMockServer.MappingModels" />
[PublicAPI]
public IEnumerable<MappingModel> MappingModels => ToMappingModels();
/// <summary>
/// Gets the scenarios.
/// </summary>
[PublicAPI]
public ConcurrentDictionary<string, ScenarioState> Scenarios => new ConcurrentDictionary<string, ScenarioState>(_options.Scenarios);
#region IDisposable Members
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
/// <summary>
/// Start this WireMockServer.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
{
return new WireMockServer(new WireMockServerSettings
{
Dispose(true);
GC.SuppressFinalize(this);
Port = port,
UseSSL = ssl
});
}
/// <summary>
/// Start this WireMockServer.
/// </summary>
/// <param name="urls">The urls to listen on.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start(params string[] urls)
{
Guard.NotNullOrEmpty(urls, nameof(urls));
return new WireMockServer(new WireMockServerSettings
{
Urls = urls
});
}
/// <summary>
/// Start this WireMockServer with the admin interface.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer StartWithAdminInterface(int? port = 0, bool ssl = false)
{
return new WireMockServer(new WireMockServerSettings
{
Port = port,
UseSSL = ssl,
StartAdminInterface = true
});
}
/// <summary>
/// Start this WireMockServer with the admin interface.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer StartWithAdminInterface(params string[] urls)
{
Guard.NotNullOrEmpty(urls, nameof(urls));
return new WireMockServer(new WireMockServerSettings
{
Urls = urls,
StartAdminInterface = true
});
}
/// <summary>
/// Start this WireMockServer with the admin interface and read static mappings.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
{
Guard.NotNullOrEmpty(urls, nameof(urls));
return new WireMockServer(new WireMockServerSettings
{
Urls = urls,
StartAdminInterface = true,
ReadStaticMappings = true
});
}
/// <summary>
/// Initializes a new instance of the <see cref="WireMockServer"/> class.
/// </summary>
/// <param name="settings">The settings.</param>
/// <exception cref="WireMockException">
/// Service start failed with error: {_httpServer.RunningException.Message}
/// or
/// Service start failed with error: {startTask.Exception.Message}
/// </exception>
/// <exception cref="TimeoutException">Service start timed out after {TimeSpan.FromMilliseconds(settings.StartTimeout)}</exception>
protected WireMockServer(WireMockServerSettings settings)
{
_settings = settings;
// Set default values if not provided
_settings.Logger = settings.Logger ?? new WireMockNullLogger();
_settings.FileSystemHandler = settings.FileSystemHandler ?? new LocalFileSystemHandler();
_settings.Logger.Info("By Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
_settings.Logger.Debug("Server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
HostUrlOptions urlOptions;
if (settings.Urls != null)
{
urlOptions = new HostUrlOptions
{
Urls = settings.Urls
};
}
else
{
urlOptions = new HostUrlOptions
{
UseSSL = settings.UseSSL == true,
Port = settings.Port
};
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
DisposeEnhancedFileSystemWatcher();
_httpServer?.StopAsync();
}
#endregion
_options.FileSystemHandler = _settings.FileSystemHandler;
_options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
_options.Logger = _settings.Logger;
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
_options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
#region Start/Stop
/// <summary>
/// Starts this WireMockServer with the specified settings.
/// </summary>
/// <param name="settings">The WireMockServerSettings.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start([NotNull] WireMockServerSettings settings)
if (settings.CustomCertificateDefined)
{
Guard.NotNull(settings, nameof(settings));
return new WireMockServer(settings);
_options.X509StoreName = settings.CertificateSettings.X509StoreName;
_options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation;
_options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName;
_options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath;
_options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword;
}
/// <summary>
/// Start this WireMockServer.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
{
return new WireMockServer(new WireMockServerSettings
{
Port = port,
UseSSL = ssl
});
}
/// <summary>
/// Start this WireMockServer.
/// </summary>
/// <param name="urls">The urls to listen on.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start(params string[] urls)
{
Guard.NotNullOrEmpty(urls, nameof(urls));
return new WireMockServer(new WireMockServerSettings
{
Urls = urls
});
}
/// <summary>
/// Start this WireMockServer with the admin interface.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer StartWithAdminInterface(int? port = 0, bool ssl = false)
{
return new WireMockServer(new WireMockServerSettings
{
Port = port,
UseSSL = ssl,
StartAdminInterface = true
});
}
/// <summary>
/// Start this WireMockServer with the admin interface.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer StartWithAdminInterface(params string[] urls)
{
Guard.NotNullOrEmpty(urls, nameof(urls));
return new WireMockServer(new WireMockServerSettings
{
Urls = urls,
StartAdminInterface = true
});
}
/// <summary>
/// Start this WireMockServer with the admin interface and read static mappings.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
{
Guard.NotNullOrEmpty(urls, nameof(urls));
return new WireMockServer(new WireMockServerSettings
{
Urls = urls,
StartAdminInterface = true,
ReadStaticMappings = true
});
}
/// <summary>
/// Initializes a new instance of the <see cref="WireMockServer"/> class.
/// </summary>
/// <param name="settings">The settings.</param>
/// <exception cref="WireMockException">
/// Service start failed with error: {_httpServer.RunningException.Message}
/// or
/// Service start failed with error: {startTask.Exception.Message}
/// </exception>
/// <exception cref="TimeoutException">Service start timed out after {TimeSpan.FromMilliseconds(settings.StartTimeout)}</exception>
protected WireMockServer(WireMockServerSettings settings)
{
_settings = settings;
// Set default values if not provided
_settings.Logger = settings.Logger ?? new WireMockNullLogger();
_settings.FileSystemHandler = settings.FileSystemHandler ?? new LocalFileSystemHandler();
_settings.Logger.Info("By Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
_settings.Logger.Debug("Server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
HostUrlOptions urlOptions;
if (settings.Urls != null)
{
urlOptions = new HostUrlOptions
{
Urls = settings.Urls
};
}
else
{
urlOptions = new HostUrlOptions
{
UseSSL = settings.UseSSL == true,
Port = settings.Port
};
}
_options.FileSystemHandler = _settings.FileSystemHandler;
_options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
_options.Logger = _settings.Logger;
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
_options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
if (settings.CustomCertificateDefined)
{
_options.X509StoreName = settings.CertificateSettings.X509StoreName;
_options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation;
_options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName;
_options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath;
_options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword;
}
_matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper);
_mappingToFileSaver = new MappingToFileSaver(_settings, _mappingConverter);
_matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper);
_mappingToFileSaver = new MappingToFileSaver(_settings, _mappingConverter);
#if USE_ASPNETCORE
_options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration;
_options.CorsPolicyOptions = _settings.CorsPolicyOptions;
_options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration;
_options.CorsPolicyOptions = _settings.CorsPolicyOptions;
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
#else
_httpServer = new OwinSelfHost(_options, urlOptions);
_httpServer = new OwinSelfHost(_options, urlOptions);
#endif
var startTask = _httpServer.StartAsync();
var startTask = _httpServer.StartAsync();
using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))
using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))
{
while (!_httpServer.IsStarted)
{
while (!_httpServer.IsStarted)
// Throw exception if service start fails
if (_httpServer.RunningException != null)
{
// Throw exception if service start fails
if (_httpServer.RunningException != null)
throw new WireMockException($"Service start failed with error: {_httpServer.RunningException.Message}", _httpServer.RunningException);
}
if (ctsStartTimeout.IsCancellationRequested)
{
// In case of an aggregate exception, throw the exception.
if (startTask.Exception != null)
{
throw new WireMockException($"Service start failed with error: {_httpServer.RunningException.Message}", _httpServer.RunningException);
throw new WireMockException($"Service start failed with error: {startTask.Exception.Message}", startTask.Exception);
}
if (ctsStartTimeout.IsCancellationRequested)
{
// In case of an aggregate exception, throw the exception.
if (startTask.Exception != null)
{
throw new WireMockException($"Service start failed with error: {startTask.Exception.Message}", startTask.Exception);
}
// Else throw TimeoutException
throw new TimeoutException($"Service start timed out after {TimeSpan.FromMilliseconds(settings.StartTimeout)}");
}
ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelayInMs);
// Else throw TimeoutException
throw new TimeoutException($"Service start timed out after {TimeSpan.FromMilliseconds(settings.StartTimeout)}");
}
Urls = _httpServer.Urls.ToArray();
Ports = _httpServer.Ports;
ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelayInMs);
}
if (settings.AllowBodyForAllHttpMethods == true)
{
_options.AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods;
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to True");
}
if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true)
{
_options.AllowOnlyDefinedHttpStatusCodeInResponse = _settings.AllowOnlyDefinedHttpStatusCodeInResponse;
_settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True");
}
if (settings.AllowPartialMapping == true)
{
AllowPartialMapping();
}
if (settings.StartAdminInterface == true)
{
if (!string.IsNullOrEmpty(settings.AdminUsername) && !string.IsNullOrEmpty(settings.AdminPassword))
{
SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword);
}
if (!string.IsNullOrEmpty(settings.AdminAzureADTenant) && !string.IsNullOrEmpty(settings.AdminAzureADAudience))
{
SetAzureADAuthentication(settings.AdminAzureADTenant, settings.AdminAzureADAudience);
}
InitAdmin();
}
if (settings.ReadStaticMappings == true)
{
ReadStaticMappings();
}
if (settings.WatchStaticMappings == true)
{
WatchStaticMappings();
}
if (settings.ProxyAndRecordSettings != null)
{
InitProxyAndRecord(settings);
}
if (settings.RequestLogExpirationDuration != null)
{
SetRequestLogExpirationDuration(settings.RequestLogExpirationDuration);
}
if (settings.MaxRequestLogCount != null)
{
SetMaxRequestLogCount(settings.MaxRequestLogCount);
}
Urls = _httpServer.Urls.ToArray();
Ports = _httpServer.Ports;
}
/// <inheritdoc cref="IWireMockServer.Stop" />
[PublicAPI]
public void Stop()
{
var result = _httpServer?.StopAsync();
result?.Wait(); // wait for stop to actually happen
}
#endregion
InitSettings(settings);
}
/// <inheritdoc cref="IWireMockServer.AddCatchAllMapping" />
[PublicAPI]
public void AddCatchAllMapping()
/// <inheritdoc cref="IWireMockServer.Stop" />
[PublicAPI]
public void Stop()
{
var result = _httpServer?.StopAsync();
result?.Wait(); // wait for stop to actually happen
}
#endregion
/// <inheritdoc cref="IWireMockServer.AddCatchAllMapping" />
[PublicAPI]
public void AddCatchAllMapping()
{
Given(Request.Create().WithPath("/*").UsingAnyMethod())
.WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
.AtPriority(1000)
.RespondWith(new DynamicResponseProvider(request => ResponseMessageBuilder.Create("No matching mapping found", 404)));
}
/// <inheritdoc cref="IWireMockServer.Reset" />
[PublicAPI]
public void Reset()
{
ResetLogEntries();
ResetMappings();
}
/// <inheritdoc cref="IWireMockServer.ResetMappings" />
[PublicAPI]
public void ResetMappings()
{
foreach (var nonAdmin in _options.Mappings.ToArray().Where(m => !m.Value.IsAdminInterface))
{
Given(Request.Create().WithPath("/*").UsingAnyMethod())
.WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
.AtPriority(1000)
.RespondWith(new DynamicResponseProvider(request => ResponseMessageBuilder.Create("No matching mapping found", 404)));
_options.Mappings.TryRemove(nonAdmin.Key, out _);
}
}
/// <inheritdoc cref="IWireMockServer.DeleteMapping" />
[PublicAPI]
public bool DeleteMapping(Guid guid)
{
// Check a mapping exists with the same GUID, if so, remove it.
if (_options.Mappings.ContainsKey(guid))
{
return _options.Mappings.TryRemove(guid, out _);
}
/// <inheritdoc cref="IWireMockServer.Reset" />
[PublicAPI]
public void Reset()
{
ResetLogEntries();
return false;
}
ResetMappings();
}
private bool DeleteMapping(string path)
{
// Check a mapping exists with the same path, if so, remove it.
var mapping = _options.Mappings.ToArray().FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase));
return DeleteMapping(mapping.Key);
}
/// <inheritdoc cref="IWireMockServer.ResetMappings" />
[PublicAPI]
public void ResetMappings()
{
foreach (var nonAdmin in _options.Mappings.ToArray().Where(m => !m.Value.IsAdminInterface))
{
_options.Mappings.TryRemove(nonAdmin.Key, out _);
}
}
/// <inheritdoc cref="IWireMockServer.AddGlobalProcessingDelay" />
[PublicAPI]
public void AddGlobalProcessingDelay(TimeSpan delay)
{
_options.RequestProcessingDelay = delay;
}
/// <inheritdoc cref="IWireMockServer.DeleteMapping" />
[PublicAPI]
public bool DeleteMapping(Guid guid)
{
// Check a mapping exists with the same GUID, if so, remove it.
if (_options.Mappings.ContainsKey(guid))
{
return _options.Mappings.TryRemove(guid, out _);
}
/// <inheritdoc cref="IWireMockServer.AllowPartialMapping" />
[PublicAPI]
public void AllowPartialMapping(bool allow = true)
{
_settings.Logger.Info("AllowPartialMapping is set to {0}", allow);
_options.AllowPartialMapping = allow;
}
return false;
}
private bool DeleteMapping(string path)
{
// Check a mapping exists with the same path, if so, remove it.
var mapping = _options.Mappings.ToArray().FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase));
return DeleteMapping(mapping.Key);
}
/// <inheritdoc cref="IWireMockServer.AddGlobalProcessingDelay" />
[PublicAPI]
public void AddGlobalProcessingDelay(TimeSpan delay)
{
_options.RequestProcessingDelay = delay;
}
/// <inheritdoc cref="IWireMockServer.AllowPartialMapping" />
[PublicAPI]
public void AllowPartialMapping(bool allow = true)
{
_settings.Logger.Info("AllowPartialMapping is set to {0}", allow);
_options.AllowPartialMapping = allow;
}
/// <inheritdoc cref="IWireMockServer.SetAzureADAuthentication(string, string)" />
[PublicAPI]
public void SetAzureADAuthentication([NotNull] string tenant, [NotNull] string audience)
{
Guard.NotNull(tenant, nameof(tenant));
Guard.NotNull(audience, nameof(audience));
/// <inheritdoc cref="IWireMockServer.SetAzureADAuthentication(string, string)" />
[PublicAPI]
public void SetAzureADAuthentication([NotNull] string tenant, [NotNull] string audience)
{
Guard.NotNull(tenant, nameof(tenant));
Guard.NotNull(audience, nameof(audience));
#if NETSTANDARD1_3
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
#else
_options.AuthenticationMatcher = new AzureADAuthenticationMatcher(tenant, audience);
_options.AuthenticationMatcher = new AzureADAuthenticationMatcher(tenant, audience);
#endif
}
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication(string, string)" />
[PublicAPI]
public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
{
Guard.NotNull(username, nameof(username));
Guard.NotNull(password, nameof(password));
_options.AuthenticationMatcher = new BasicAuthenticationMatcher(username, password);
}
/// <inheritdoc cref="IWireMockServer.RemoveAuthentication" />
[PublicAPI]
public void RemoveAuthentication()
{
_options.AuthenticationMatcher = null;
}
/// <inheritdoc cref="IWireMockServer.SetMaxRequestLogCount" />
[PublicAPI]
public void SetMaxRequestLogCount([CanBeNull] int? maxRequestLogCount)
{
_options.MaxRequestLogCount = maxRequestLogCount;
}
/// <inheritdoc cref="IWireMockServer.SetRequestLogExpirationDuration" />
[PublicAPI]
public void SetRequestLogExpirationDuration([CanBeNull] int? requestLogExpirationDuration)
{
_options.RequestLogExpirationDuration = requestLogExpirationDuration;
}
/// <inheritdoc cref="IWireMockServer.ResetScenarios" />
[PublicAPI]
public void ResetScenarios()
{
_options.Scenarios.Clear();
}
/// <inheritdoc cref="IWireMockServer.WithMapping(MappingModel[])" />
[PublicAPI]
public IWireMockServer WithMapping(params MappingModel[] mappings)
{
foreach (var mapping in mappings)
{
ConvertMappingAndRegisterAsRespondProvider(mapping, mapping.Guid ?? Guid.NewGuid());
}
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication(string, string)" />
[PublicAPI]
public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
{
Guard.NotNull(username, nameof(username));
Guard.NotNull(password, nameof(password));
return this;
}
_options.AuthenticationMatcher = new BasicAuthenticationMatcher(username, password);
/// <inheritdoc cref="IWireMockServer.WithMapping(string)" />
[PublicAPI]
public IWireMockServer WithMapping(string mappings)
{
var mappingModels = DeserializeJsonToArray<MappingModel>(mappings);
foreach (var mappingModel in mappingModels)
{
ConvertMappingAndRegisterAsRespondProvider(mappingModel, mappingModel.Guid ?? Guid.NewGuid());
}
/// <inheritdoc cref="IWireMockServer.RemoveAuthentication" />
[PublicAPI]
public void RemoveAuthentication()
return this;
}
/// <summary>
/// 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, bool saveToFile = false)
{
return new RespondWithAProvider(RegisterMapping, requestMatcher, _settings, saveToFile);
}
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))
{
_options.AuthenticationMatcher = null;
_options.Mappings[mapping.Guid] = mapping;
}
else
{
_options.Mappings.TryAdd(mapping.Guid, mapping);
}
/// <inheritdoc cref="IWireMockServer.SetMaxRequestLogCount" />
[PublicAPI]
public void SetMaxRequestLogCount([CanBeNull] int? maxRequestLogCount)
if (saveToFile)
{
_options.MaxRequestLogCount = maxRequestLogCount;
_mappingToFileSaver.SaveMappingToFile(mapping);
}
}
private void InitSettings(WireMockServerSettings settings)
{
if (settings.AllowBodyForAllHttpMethods == true)
{
_options.AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods;
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to True");
}
/// <inheritdoc cref="IWireMockServer.SetRequestLogExpirationDuration" />
[PublicAPI]
public void SetRequestLogExpirationDuration([CanBeNull] int? requestLogExpirationDuration)
if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true)
{
_options.RequestLogExpirationDuration = requestLogExpirationDuration;
_options.AllowOnlyDefinedHttpStatusCodeInResponse = _settings.AllowOnlyDefinedHttpStatusCodeInResponse;
_settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True");
}
/// <inheritdoc cref="IWireMockServer.ResetScenarios" />
[PublicAPI]
public void ResetScenarios()
if (settings.AllowPartialMapping == true)
{
_options.Scenarios.Clear();
AllowPartialMapping();
}
/// <inheritdoc cref="IWireMockServer.WithMapping(MappingModel[])" />
[PublicAPI]
public IWireMockServer WithMapping(params MappingModel[] mappings)
if (settings.StartAdminInterface == true)
{
foreach (var mapping in mappings)
if (!string.IsNullOrEmpty(settings.AdminUsername) && !string.IsNullOrEmpty(settings.AdminPassword))
{
ConvertMappingAndRegisterAsRespondProvider(mapping, mapping.Guid ?? Guid.NewGuid());
SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword);
}
return this;
if (!string.IsNullOrEmpty(settings.AdminAzureADTenant) && !string.IsNullOrEmpty(settings.AdminAzureADAudience))
{
SetAzureADAuthentication(settings.AdminAzureADTenant, settings.AdminAzureADAudience);
}
InitAdmin();
}
/// <inheritdoc cref="IWireMockServer.WithMapping(string)" />
[PublicAPI]
public IWireMockServer WithMapping(string mappings)
if (settings.ReadStaticMappings == true)
{
var mappingModels = DeserializeJsonToArray<MappingModel>(mappings);
foreach (var mappingModel in mappingModels)
{
ConvertMappingAndRegisterAsRespondProvider(mappingModel, mappingModel.Guid ?? Guid.NewGuid());
}
return this;
ReadStaticMappings();
}
/// <summary>
/// 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, bool saveToFile = false)
if (settings.WatchStaticMappings == true)
{
return new RespondWithAProvider(RegisterMapping, requestMatcher, _settings, saveToFile);
WatchStaticMappings();
}
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))
{
_options.Mappings[mapping.Guid] = mapping;
}
else
{
_options.Mappings.TryAdd(mapping.Guid, mapping);
}
InitProxyAndRecord(settings);
if (saveToFile)
{
_mappingToFileSaver.SaveMappingToFile(mapping);
}
if (settings.RequestLogExpirationDuration != null)
{
SetRequestLogExpirationDuration(settings.RequestLogExpirationDuration);
}
if (settings.MaxRequestLogCount != null)
{
SetMaxRequestLogCount(settings.MaxRequestLogCount);
}
}
}