mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-27 19:27:42 +02:00
Create WireMock.Net.ProtoBuf project (#1350)
* Create WireMock.Net.ProtoBuf project * ok * Update Directory.Build.props Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace WireMock.Extensions;
|
||||
|
||||
internal static class StringExtensions
|
||||
{
|
||||
// See https://andrewlock.net/why-is-string-gethashcode-different-each-time-i-run-my-program-in-net-core/
|
||||
public static string GetDeterministicHashCodeAsString(this string str)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash1 = (5381 << 16) + 5381;
|
||||
int hash2 = hash1;
|
||||
|
||||
for (int i = 0; i < str.Length; i += 2)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ str[i];
|
||||
if (i == str.Length - 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
|
||||
}
|
||||
|
||||
int result = hash1 + hash2 * 1566083941;
|
||||
|
||||
return result.ToString(CultureInfo.InvariantCulture).Replace('-', '_');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock;
|
||||
|
||||
/// <summary>
|
||||
/// The IMapping interface.
|
||||
/// </summary>
|
||||
public interface IMapping
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier.
|
||||
/// </summary>
|
||||
Guid Guid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The datetime when this mapping was created or updated.
|
||||
/// </summary>
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the TimeSettings (Start, End and TTL).
|
||||
/// </summary>
|
||||
ITimeSettings? TimeSettings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique title.
|
||||
/// </summary>
|
||||
string? Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the description.
|
||||
/// </summary>
|
||||
string? Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The full filename path for this mapping (only defined for static mappings).
|
||||
/// </summary>
|
||||
string? Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the priority. (A low value means higher priority.)
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Scenario.
|
||||
/// </summary>
|
||||
string? Scenario { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Execution state condition for the current mapping.
|
||||
/// </summary>
|
||||
string? ExecutionConditionState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The next state which will be signaled after the current mapping execution.
|
||||
/// In case the value is null, state will not be changed.
|
||||
/// </summary>
|
||||
string? NextState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of times this match should be matched before the state will be changed to the next state.
|
||||
/// </summary>
|
||||
int? TimesInSameState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The RequestMatcher.
|
||||
/// </summary>
|
||||
IRequestMatcher RequestMatcher { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The ResponseProvider.
|
||||
/// </summary>
|
||||
IResponseProvider Provider { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The WireMockServerSettings.
|
||||
/// </summary>
|
||||
WireMockServerSettings Settings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the state is started or manually set to a value.
|
||||
/// </summary>
|
||||
bool IsStartState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping is an Admin Interface.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping is an Admin Interface; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsAdminInterface { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping is a Proxy Mapping.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping is a Proxy Mapping; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool IsProxy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this mapping to be logged.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this mapping to be logged; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
bool LogMapping { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
IWebhook[]? Webhooks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Use Fire and Forget for the defined webhook(s). [Optional]
|
||||
/// </summary>
|
||||
bool? UseWebhooksFireAndForget { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Data Object which can be used when WithTransformer is used.
|
||||
/// e.g. lookup an path in this object using
|
||||
/// <example>
|
||||
/// lookup data "1"
|
||||
/// </example>
|
||||
/// </summary>
|
||||
object? Data { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The probability when this request should be matched. Value is between 0 and 1. [Optional]
|
||||
/// </summary>
|
||||
double? Probability { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
|
||||
/// </summary>
|
||||
IdOrTexts? ProtoDefinition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ProvideResponseAsync
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IRequestMessage requestMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RequestMatchResult based on the RequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <param name="nextState">The Next State.</param>
|
||||
/// <returns>The <see cref="IRequestMatchResult"/>.</returns>
|
||||
IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState);
|
||||
|
||||
/// <summary>
|
||||
/// Define the scenario.
|
||||
/// </summary>
|
||||
/// <param name="scenario">The scenario.</param>
|
||||
/// <returns>The <see cref="IMapping"/>.</returns>
|
||||
IMapping WithScenario(string scenario);
|
||||
|
||||
/// <summary>
|
||||
/// Define the probability when this request should be matched. [Optional]
|
||||
/// </summary>
|
||||
/// <param name="probability">The probability.</param>
|
||||
/// <returns>The <see cref="IMapping"/>.</returns>
|
||||
IMapping WithProbability(double probability);
|
||||
|
||||
/// <summary>
|
||||
/// Define a Grpc ProtoDefinition which is used for this mapping (request and response).
|
||||
/// </summary>
|
||||
/// <param name="protoDefinition">The proto definitions as id or text.</param>
|
||||
/// <returns>The <see cref="IMapping"/>.</returns>
|
||||
IMapping WithProtoDefinition(IdOrTexts protoDefinition);
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if PROTOBUF
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ProtoBufJsonConverter;
|
||||
using ProtoBufJsonConverter.Models;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// Grpc ProtoBuf Matcher
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IProtoBufMatcher"/>
|
||||
public class ProtoBufMatcher : IProtoBufMatcher
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(ProtoBufMatcher);
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Func to define the proto definition as id or texts.
|
||||
/// </summary>
|
||||
public Func<IdOrTexts> ProtoDefinition { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
||||
/// </summary>
|
||||
public string MessageType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Matcher to use (optional).
|
||||
/// </summary>
|
||||
public IObjectMatcher? Matcher { get; }
|
||||
|
||||
private static readonly Converter ProtoBufToJsonConverter = SingletonFactory<Converter>.GetInstance();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ProtoBufMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="protoDefinition">The proto definition as id or text.</param>
|
||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||
/// <param name="matcher">The optional jsonMatcher to use to match the ProtoBuf as (json) object.</param>
|
||||
public ProtoBufMatcher(
|
||||
Func<IdOrTexts> protoDefinition,
|
||||
string messageType,
|
||||
MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch,
|
||||
IObjectMatcher? matcher = null
|
||||
)
|
||||
{
|
||||
ProtoDefinition = Guard.NotNull(protoDefinition);
|
||||
MessageType = Guard.NotNullOrWhiteSpace(messageType);
|
||||
Matcher = matcher;
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<MatchResult> IsMatchAsync(byte[]? input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = new MatchResult();
|
||||
|
||||
if (input != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var instance = await DecodeAsync(input, true, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
result = Matcher?.IsMatch(instance) ?? new MatchResult(MatchScores.Perfect);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
result = new MatchResult(MatchScores.Mismatch, e);
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, result);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<object?> DecodeAsync(byte[]? input, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return DecodeAsync(input, false, cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return "NotImplemented";
|
||||
}
|
||||
|
||||
private async Task<object?> DecodeAsync(byte[]? input, bool throwException, CancellationToken cancellationToken)
|
||||
{
|
||||
if (input == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var protoDefinitions = ProtoDefinition().Texts;
|
||||
|
||||
var resolver = new WireMockProtoFileResolver(protoDefinitions);
|
||||
var request = new ConvertToObjectRequest(protoDefinitions[0], MessageType, input)
|
||||
.WithProtoFileResolver(resolver);
|
||||
|
||||
try
|
||||
{
|
||||
return await ProtoBufToJsonConverter.ConvertAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (throwException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request body Grpc ProtoBuf matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageProtoBufMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The ProtoBufMatcher.
|
||||
/// </summary>
|
||||
public IProtoBufMatcher? Matcher { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageProtoBufMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||
/// <param name="protoDefinition">The Func to define the proto definitions as id or text.</param>
|
||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||
/// <param name="matcher">The optional matcher to use to match the ProtoBuf as (json) object.</param>
|
||||
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, Func<IdOrTexts> protoDefinition, string messageType, IObjectMatcher? matcher = null)
|
||||
{
|
||||
#if PROTOBUF
|
||||
Matcher = new ProtoBufMatcher(protoDefinition, messageType, matchBehaviour, matcher);
|
||||
#else
|
||||
throw new System.NotSupportedException("The ProtoBufMatcher can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var (score, exception) = GetMatchResult(requestMessage).Expand();
|
||||
return requestMatchResult.AddScore(GetType(), score, exception);
|
||||
}
|
||||
|
||||
private MatchResult GetMatchResult(IRequestMessage requestMessage)
|
||||
{
|
||||
return Matcher?.IsMatchAsync(requestMessage.BodyAsBytes).GetAwaiter().GetResult() ?? default;
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AnyOfTypes;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Models.GraphQL;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// GraphQLSchemaDetails
|
||||
/// </summary>
|
||||
public class GraphQLSchemaDetails
|
||||
{
|
||||
/// <summary>
|
||||
/// The GraphQL schema as a string.
|
||||
/// </summary>
|
||||
public string? SchemaAsString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The GraphQL schema as a StringPattern.
|
||||
/// </summary>
|
||||
public StringPattern? SchemaAsStringPattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The GraphQL schema as a <seealso cref="ISchemaData"/>.
|
||||
/// </summary>
|
||||
public ISchemaData? SchemaAsISchemaData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The GraphQL Schema.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public AnyOf<string, StringPattern, ISchemaData>? Schema
|
||||
{
|
||||
get
|
||||
{
|
||||
if (SchemaAsString != null)
|
||||
{
|
||||
return SchemaAsString;
|
||||
}
|
||||
|
||||
if (SchemaAsStringPattern != null)
|
||||
{
|
||||
return SchemaAsStringPattern;
|
||||
}
|
||||
|
||||
if (SchemaAsISchemaData != null)
|
||||
{
|
||||
return new AnyOf<string, StringPattern, ISchemaData>(SchemaAsISchemaData);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The custom Scalars to define for this schema.
|
||||
/// </summary>
|
||||
public IDictionary<string, Type>? CustomScalars { get; set; }
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A placeholder class for Proto Definitions.
|
||||
/// </summary>
|
||||
public class ProtoDefinitionData
|
||||
{
|
||||
private readonly IDictionary<string, string> _filenameMappedToProtoDefinition;
|
||||
|
||||
internal ProtoDefinitionData(IDictionary<string, string> filenameMappedToProtoDefinition)
|
||||
{
|
||||
_filenameMappedToProtoDefinition = filenameMappedToProtoDefinition;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all the ProtoDefinitions.
|
||||
/// Note: the main ProtoDefinition will be the first one in the list.
|
||||
/// </summary>
|
||||
/// <param name="mainProtoFilename">The main ProtoDefinition filename.</param>
|
||||
public IReadOnlyList<string> ToList(string mainProtoFilename)
|
||||
{
|
||||
Guard.NotNullOrEmpty(mainProtoFilename);
|
||||
|
||||
if (!_filenameMappedToProtoDefinition.TryGetValue(mainProtoFilename, out var mainProtoDefinition))
|
||||
{
|
||||
throw new KeyNotFoundException($"The ProtoDefinition with filename '{mainProtoFilename}' was not found.");
|
||||
}
|
||||
|
||||
var list = new List<string> { mainProtoDefinition };
|
||||
list.AddRange(_filenameMappedToProtoDefinition.Where(kvp => kvp.Key != mainProtoFilename).Select(kvp => kvp.Value));
|
||||
return list;
|
||||
}
|
||||
}
|
||||
@@ -177,11 +177,10 @@ namespace WireMock.Owin.Mappers
|
||||
var jsonBody = JsonConvert.SerializeObject(bodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
return (bodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||
|
||||
#if PROTOBUF
|
||||
case BodyType.ProtoBuf:
|
||||
var protoDefinitions = bodyData.ProtoDefinition?.Invoke().Texts;
|
||||
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinitions, bodyData.ProtoBufMessageType, bodyData.BodyAsJson).ConfigureAwait(false);
|
||||
#endif
|
||||
var protoBufUtils = TypeLoader.LoadStaticInstance<IProtoBufUtils>();
|
||||
return await protoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinitions, bodyData.ProtoBufMessageType, bodyData.BodyAsJson).ConfigureAwait(false);
|
||||
|
||||
case BodyType.Bytes:
|
||||
return bodyData.BodyAsBytes;
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return WithBodyAsProtoBuf([protoDefinition], messageType, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return WithBodyAsProtoBuf([protoDefinition], messageType, matcher, matchBehaviour);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new IdOrTexts(null, protoDefinitions), messageType));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new IdOrTexts(null, protoDefinitions), messageType, matcher));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsProtoBuf(string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, ProtoDefinitionFunc(), messageType));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsProtoBuf(string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, ProtoDefinitionFunc(), messageType, matcher));
|
||||
}
|
||||
|
||||
private Func<IdOrTexts> ProtoDefinitionFunc()
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
if (Mapping.ProtoDefinition == null)
|
||||
{
|
||||
throw new InvalidOperationException($"No ProtoDefinition defined on mapping '{Mapping.Guid}'. Please use the WireMockServerSettings to define ProtoDefinitions.");
|
||||
}
|
||||
|
||||
return Mapping.ProtoDefinition.Value;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,7 @@ public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
{
|
||||
private readonly IList<IRequestMatcher> _requestMatchers;
|
||||
|
||||
/// <summary>
|
||||
/// The link back to the Mapping.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public IMapping Mapping { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
@@ -73,6 +71,7 @@ public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
|
||||
return _requestMatchers.OfType<T>().FirstOrDefault(func);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder Add<T>(T requestMatcher) where T : IRequestMatcher
|
||||
{
|
||||
foreach (var existing in _requestMatchers.OfType<T>().ToArray())
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the BodyDestinationFormat
|
||||
/// </summary>
|
||||
public static class BodyDestinationFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// Same as source (no conversion)
|
||||
/// </summary>
|
||||
public const string SameAsSource = "SameAsSource";
|
||||
|
||||
/// <summary>
|
||||
/// Convert to string
|
||||
/// </summary>
|
||||
public const string String = "String";
|
||||
|
||||
/// <summary>
|
||||
/// Convert to bytes
|
||||
/// </summary>
|
||||
public const string Bytes = "Bytes";
|
||||
|
||||
/// <summary>
|
||||
/// Convert to Json object
|
||||
/// </summary>
|
||||
public const string Json = "Json";
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JsonConverter.Abstractions;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The BodyResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface IBodyResponseBuilder : IFaultResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a string.
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody(string body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a callback function.
|
||||
/// </summary>
|
||||
/// <param name="bodyFactory">The delegate to build the body.</param>
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on an async callback function.
|
||||
/// </summary>
|
||||
/// <param name="bodyFactory">The async delegate to build the body.</param>
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody(Func<IRequestMessage, Task<string>> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on an async callback function.
|
||||
/// </summary>
|
||||
/// <param name="bodyFactory">The async delegate to build the body.</param>
|
||||
/// <param name="timeout">The timeout to wait on new items in the queue. Default value is <c>1</c> hour.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithSseBody(Func<IRequestMessage, IBlockingQueue<string?>, Task> bodyFactory, TimeSpan? timeout = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a bytearray.
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a object (which will be converted to a JSON string).
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <param name="indented">Define whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a object (which will be converted to a JSON string).
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="indented">Define whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsJson(object body, bool indented);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyAsJson : Create a ... response based on a callback function.
|
||||
/// </summary>
|
||||
/// <param name="bodyFactory">The delegate to build the body.</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsJson(Func<IRequestMessage, object> bodyFactory, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyAsJson : Create a ... response based on a async callback function.
|
||||
/// </summary>
|
||||
/// <param name="bodyFactory">The async delegate to build the body.</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsJson(Func<IRequestMessage, Task<object>> bodyFactory, Encoding? encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyFromFile : Create a ... response based on a File.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk every time the response is created.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyFromFile(string filename, bool cache = true);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a object (which will be converted to a JSON string using the <see cref="IJsonConverter"/>).
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="jsonConverter">The <see cref="IJsonConverter"/>.</param>
|
||||
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody(object body, IJsonConverter jsonConverter, JsonConverterOptions? options = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a object (which will be converted to a JSON string using the <see cref="IJsonConverter"/>).
|
||||
/// </summary>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="encoding">The body encoding, can be <c>null</c>.</param>
|
||||
/// <param name="jsonConverter">The <see cref="IJsonConverter"/>.</param>
|
||||
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter jsonConverter, JsonConverterOptions? options = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
|
||||
/// </summary>
|
||||
/// <param name="protoDefinition">The proto definition as text.</param>
|
||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||
/// <param name="value">The object to convert to protobuf byte[].</param>
|
||||
/// <param name="jsonConverter">The <see cref="IJsonConverter"/> [optional]. Default value is NewtonsoftJsonConverter.</param>
|
||||
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsProtoBuf(
|
||||
string protoDefinition,
|
||||
string messageType,
|
||||
object value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
JsonConverterOptions? options = null
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on proto definitions, message type and the value.
|
||||
/// </summary>
|
||||
/// <param name="protoDefinitions">The proto definition as text.</param>
|
||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||
/// <param name="value">The object to convert to protobuf byte[].</param>
|
||||
/// <param name="jsonConverter">The <see cref="IJsonConverter"/> [optional]. Default value is NewtonsoftJsonConverter.</param>
|
||||
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsProtoBuf(
|
||||
IReadOnlyList<string> protoDefinitions,
|
||||
string messageType,
|
||||
object value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
JsonConverterOptions? options = null
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
|
||||
/// </summary>
|
||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||
/// <param name="value">The object to convert to protobuf byte[].</param>
|
||||
/// <param name="jsonConverter">The <see cref="IJsonConverter"/> [optional]. Default value is NewtonsoftJsonConverter.</param>
|
||||
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyAsProtoBuf(
|
||||
string messageType,
|
||||
object value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
JsonConverterOptions? options = null
|
||||
);
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.ResponseProviders;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The CallbackResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface ICallbackResponseBuilder : IResponseProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The callback builder
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
[PublicAPI]
|
||||
IResponseBuilder WithCallback(Func<IRequestMessage, ResponseMessage> callbackHandler);
|
||||
|
||||
/// <summary>
|
||||
/// The async callback builder
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
[PublicAPI]
|
||||
IResponseBuilder WithCallback(Func<IRequestMessage, Task<ResponseMessage>> callbackHandler);
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The DelayResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface IDelayResponseBuilder : ICallbackResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The delay defined as a <see cref="TimeSpan"/>.
|
||||
/// </summary>
|
||||
/// <param name="delay">The TimeSpan to delay.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithDelay(TimeSpan delay);
|
||||
|
||||
/// <summary>
|
||||
/// The delay defined as milliseconds.
|
||||
/// </summary>
|
||||
/// <param name="milliseconds">The milliseconds to delay.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithDelay(int milliseconds);
|
||||
|
||||
/// <summary>
|
||||
/// Introduce random delay
|
||||
/// </summary>
|
||||
/// <param name="minimumMilliseconds">Minimum milliseconds to delay</param>
|
||||
/// <param name="maximumMilliseconds">Maximum milliseconds to delay</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithRandomDelay(int minimumMilliseconds = 0, int maximumMilliseconds = 60_000);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The FaultRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IFaultResponseBuilder : ITransformResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithBody : Create a fault response.
|
||||
/// </summary>
|
||||
/// <param name="faultType">The FaultType.</param>
|
||||
/// <param name="percentage">The percentage when this fault should occur. When null, it's always a fault.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithFault(FaultType faultType, double? percentage = null);
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The HeadersResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface IHeadersResponseBuilder : IBodyResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The WithHeader.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithHeader(string name, params string[] values);
|
||||
|
||||
/// <summary>
|
||||
/// The WithHeaders.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithHeaders(IDictionary<string, string> headers);
|
||||
|
||||
/// <summary>
|
||||
/// The WithHeaders.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithHeaders(IDictionary<string, string[]> headers);
|
||||
|
||||
/// <summary>
|
||||
/// The WithHeaders.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithHeaders(IDictionary<string, WireMockList<string>> headers);
|
||||
|
||||
/// <summary>
|
||||
/// The WithTrailingHeader.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithTrailingHeader(string name, params string[] values);
|
||||
|
||||
/// <summary>
|
||||
/// The WithTrailingHeaders.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithTrailingHeaders(IDictionary<string, string> headers);
|
||||
|
||||
/// <summary>
|
||||
/// The WithTrailingHeaders.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithTrailingHeaders(IDictionary<string, string[]> headers);
|
||||
|
||||
/// <summary>
|
||||
/// The WithTrailingHeaders.
|
||||
/// </summary>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithTrailingHeaders(IDictionary<string, WireMockList<string>> headers);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The ProxyResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface IProxyResponseBuilder : IStatusCodeResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithProxy URL using Client X509Certificate2.
|
||||
/// </summary>
|
||||
/// <param name="proxyUrl">The proxy url.</param>
|
||||
/// <param name="clientX509Certificate2ThumbprintOrSubjectName">The X509Certificate2 file to use for client authentication.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithProxy(string proxyUrl, string? clientX509Certificate2ThumbprintOrSubjectName = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithProxy using <see cref="ProxyAndRecordSettings"/>.
|
||||
/// </summary>
|
||||
/// <param name="settings">The ProxyAndRecordSettings.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithProxy(ProxyAndRecordSettings settings);
|
||||
|
||||
/// <summary>
|
||||
/// WithProxy using <see cref="X509Certificate2"/>.
|
||||
/// </summary>
|
||||
/// <param name="proxyUrl">The proxy url.</param>
|
||||
/// <param name="certificate">The X509Certificate2.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithProxy(string proxyUrl, X509Certificate2 certificate);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The ResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface IResponseBuilder : IProxyResponseBuilder
|
||||
{
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Net;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The StatusCodeResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface IStatusCodeResponseBuilder : IHeadersResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The with status code.
|
||||
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="WireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithStatusCode(int code);
|
||||
|
||||
/// <summary>
|
||||
/// The with status code.
|
||||
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="WireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithStatusCode(string code);
|
||||
|
||||
/// <summary>
|
||||
/// The with status code.
|
||||
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="WireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithStatusCode(HttpStatusCode code);
|
||||
|
||||
/// <summary>
|
||||
/// The with Success status code (200).
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithSuccess();
|
||||
|
||||
/// <summary>
|
||||
/// The with NotFound status code (404).
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithNotFound();
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.ResponseBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The TransformResponseBuilder interface.
|
||||
/// </summary>
|
||||
public interface ITransformResponseBuilder : IDelayResponseBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Use the Handlebars.Net ResponseMessage transformer.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IResponseBuilder"/>.
|
||||
/// </returns>
|
||||
IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile);
|
||||
|
||||
/// <summary>
|
||||
/// Use the Handlebars.Net ResponseMessage transformer.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IResponseBuilder"/>.
|
||||
/// </returns>
|
||||
IResponseBuilder WithTransformer(ReplaceNodeOptions options);
|
||||
|
||||
/// <summary>
|
||||
/// Use a specific ResponseMessage transformer.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IResponseBuilder"/>.
|
||||
/// </returns>
|
||||
IResponseBuilder WithTransformer(TransformerType transformerType = TransformerType.Handlebars, bool transformContentFromBodyAsFile = false, ReplaceNodeOptions options = ReplaceNodeOptions.EvaluateAndTryToConvert);
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JsonConverter.Abstractions;
|
||||
using Stef.Validation;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
@@ -235,72 +233,4 @@ public partial class Response
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithBodyAsProtoBuf(
|
||||
string protoDefinition,
|
||||
string messageType,
|
||||
object value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
JsonConverterOptions? options = null
|
||||
)
|
||||
{
|
||||
return WithBodyAsProtoBuf([protoDefinition], messageType, value, jsonConverter, options);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithBodyAsProtoBuf(
|
||||
IReadOnlyList<string> protoDefinitions,
|
||||
string messageType,
|
||||
object value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
JsonConverterOptions? options = null
|
||||
)
|
||||
{
|
||||
Guard.NotNullOrEmpty(protoDefinitions);
|
||||
Guard.NotNullOrWhiteSpace(messageType);
|
||||
Guard.NotNull(value);
|
||||
|
||||
#if !PROTOBUF
|
||||
throw new NotSupportedException("The WithBodyAsProtoBuf method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
||||
#else
|
||||
ResponseMessage.BodyDestination = null;
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.ProtoBuf,
|
||||
BodyAsJson = value,
|
||||
ProtoDefinition = () => new IdOrTexts(null, protoDefinitions),
|
||||
ProtoBufMessageType = messageType
|
||||
};
|
||||
|
||||
return this;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithBodyAsProtoBuf(
|
||||
string messageType,
|
||||
object value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
JsonConverterOptions? options = null
|
||||
)
|
||||
{
|
||||
Guard.NotNullOrWhiteSpace(messageType);
|
||||
Guard.NotNull(value);
|
||||
|
||||
#if !PROTOBUF
|
||||
throw new NotSupportedException("The WithBodyAsProtoBuf method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
||||
#else
|
||||
ResponseMessage.BodyDestination = null;
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.ProtoBuf,
|
||||
BodyAsJson = value,
|
||||
ProtoDefinition = () => Mapping.ProtoDefinition ?? throw new WireMockException("ProtoDefinition cannot be resolved. You probably forgot to call .WithProtoDefinition(...) on the mapping."),
|
||||
ProtoBufMessageType = messageType
|
||||
};
|
||||
|
||||
return this;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -13,13 +13,13 @@ public partial class Response
|
||||
/// A delegate to execute to generate the response.
|
||||
/// </summary>
|
||||
[MemberNotNullWhen(true, nameof(WithCallbackUsed))]
|
||||
public Func<IRequestMessage, ResponseMessage>? Callback { get; private set; }
|
||||
public Func<IRequestMessage, IResponseMessage>? Callback { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// A delegate to execute to generate the response async.
|
||||
/// </summary>
|
||||
[MemberNotNullWhen(true, nameof(WithCallbackUsed))]
|
||||
public Func<IRequestMessage, Task<ResponseMessage>>? CallbackAsync { get; private set; }
|
||||
public Func<IRequestMessage, Task<IResponseMessage>>? CallbackAsync { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the method WithCallback(...) is used.
|
||||
@@ -27,7 +27,7 @@ public partial class Response
|
||||
public bool WithCallbackUsed { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithCallback(Func<IRequestMessage, ResponseMessage> callbackHandler)
|
||||
public IResponseBuilder WithCallback(Func<IRequestMessage, IResponseMessage> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler);
|
||||
|
||||
@@ -35,14 +35,14 @@ public partial class Response
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IResponseBuilder WithCallback(Func<IRequestMessage, Task<ResponseMessage>> callbackHandler)
|
||||
public IResponseBuilder WithCallback(Func<IRequestMessage, Task<IResponseMessage>> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler);
|
||||
|
||||
return WithCallbackInternal(true, callbackHandler);
|
||||
}
|
||||
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<IRequestMessage, ResponseMessage> callbackHandler)
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<IRequestMessage, IResponseMessage> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler);
|
||||
|
||||
@@ -52,7 +52,7 @@ public partial class Response
|
||||
return this;
|
||||
}
|
||||
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<IRequestMessage, Task<ResponseMessage>> callbackHandler)
|
||||
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<IRequestMessage, Task<IResponseMessage>> callbackHandler)
|
||||
{
|
||||
Guard.NotNull(callbackHandler);
|
||||
|
||||
|
||||
@@ -28,9 +28,7 @@ public partial class Response : IResponseBuilder
|
||||
|
||||
private TimeSpan? _delay;
|
||||
|
||||
/// <summary>
|
||||
/// The link back to the mapping.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
public IMapping Mapping { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
@@ -81,10 +79,8 @@ public partial class Response : IResponseBuilder
|
||||
/// </summary>
|
||||
public ReplaceNodeOptions TransformerReplaceNodeOptions { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the response message.
|
||||
/// </summary>
|
||||
public ResponseMessage ResponseMessage { get; }
|
||||
/// <inheritdoc />
|
||||
public IResponseMessage ResponseMessage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates this instance.
|
||||
@@ -226,7 +222,7 @@ public partial class Response : IResponseBuilder
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
ResponseMessage responseMessage;
|
||||
IResponseMessage responseMessage;
|
||||
if (!WithCallbackUsed)
|
||||
{
|
||||
responseMessage = ResponseMessage;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// Copyright © WireMock.Net and mock4net by Alexandre Victoor
|
||||
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.ResponseProviders;
|
||||
|
||||
/// <summary>
|
||||
/// The Response Provider interface.
|
||||
/// </summary>
|
||||
public interface IResponseProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// The provide response.
|
||||
/// </summary>
|
||||
/// <param name="mapping">The used mapping.</param>
|
||||
/// <param name="requestMessage">The request.</param>
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IMapping mapping, IRequestMessage requestMessage, WireMockServerSettings settings);
|
||||
}
|
||||
@@ -126,12 +126,10 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
}
|
||||
}
|
||||
|
||||
#if PROTOBUF
|
||||
if (requestMessageProtoBufMatcher?.Matcher != null)
|
||||
{
|
||||
sb.AppendLine(" // .WithBodyAsProtoBuf() is not yet supported");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (requestMessageBodyMatcher?.Matchers != null)
|
||||
{
|
||||
@@ -188,7 +186,7 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
sb.AppendLine($" .WithStatusCode({(int)httpStatusCode})");
|
||||
}
|
||||
|
||||
if (response.ResponseMessage.Headers is { })
|
||||
if (response.ResponseMessage.Headers != null)
|
||||
{
|
||||
foreach (var header in response.ResponseMessage.Headers)
|
||||
{
|
||||
@@ -196,7 +194,7 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
}
|
||||
}
|
||||
|
||||
if (response.ResponseMessage.TrailingHeaders is { })
|
||||
if (response.ResponseMessage.TrailingHeaders != null)
|
||||
{
|
||||
foreach (var header in response.ResponseMessage.TrailingHeaders)
|
||||
{
|
||||
@@ -400,13 +398,11 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
{
|
||||
void AfterMap(MatcherModel matcherModel)
|
||||
{
|
||||
#if PROTOBUF
|
||||
// In case the ProtoDefinition is defined at the Mapping level, clear the Pattern at the Matcher level
|
||||
if (bodyMatchers?.OfType<ProtoBufMatcher>().Any() == true && mappingModel.ProtoDefinition != null)
|
||||
if (bodyMatchers?.OfType<IProtoBufMatcher>().Any() == true && mappingModel.ProtoDefinition != null)
|
||||
{
|
||||
matcherModel.Pattern = null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mappingModel.Request.Body = new BodyModel();
|
||||
|
||||
@@ -80,10 +80,9 @@ internal class MatcherMapper
|
||||
case "MimePartMatcher":
|
||||
return CreateMimePartMatcher(matchBehaviour, matcherModel);
|
||||
|
||||
#if PROTOBUF
|
||||
case nameof(ProtoBufMatcher):
|
||||
case "ProtoBufMatcher":
|
||||
return CreateProtoBufMatcher(matchBehaviour, stringPatterns.GetPatterns(), matcherModel);
|
||||
#endif
|
||||
|
||||
case nameof(RegexMatcher):
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, useRegexExtended, matchOperator);
|
||||
|
||||
@@ -210,7 +209,7 @@ internal class MatcherMapper
|
||||
break;
|
||||
|
||||
#if PROTOBUF
|
||||
case ProtoBufMatcher protoBufMatcher:
|
||||
case IProtoBufMatcher protoBufMatcher:
|
||||
protoBufMatcher.ProtoDefinition().Value(id => model.Pattern = id, texts =>
|
||||
{
|
||||
if (texts.Count == 1)
|
||||
@@ -286,17 +285,15 @@ internal class MatcherMapper
|
||||
return TypeLoader.LoadNewInstance<IMimePartMatcher>(matchBehaviour, contentTypeMatcher, contentDispositionMatcher, contentTransferEncodingMatcher, contentMatcher);
|
||||
}
|
||||
|
||||
#if PROTOBUF
|
||||
private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, IReadOnlyList<string> protoDefinitions, MatcherModel matcher)
|
||||
private IProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, IReadOnlyList<string> protoDefinitions, MatcherModel matcher)
|
||||
{
|
||||
var objectMatcher = Map(matcher.ContentMatcher) as IObjectMatcher;
|
||||
|
||||
return new ProtoBufMatcher(
|
||||
() => ProtoDefinitionHelper.GetIdOrTexts(_settings, protoDefinitions.ToArray()),
|
||||
return TypeLoader.LoadNewInstance<IProtoBufMatcher>(
|
||||
() => ProtoDefinitionUtils.GetIdOrTexts(_settings, protoDefinitions.ToArray()),
|
||||
matcher.ProtoBufMessageType!,
|
||||
matchBehaviour ?? MatchBehaviour.AcceptOnMatch,
|
||||
objectMatcher
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -356,12 +356,9 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
{
|
||||
Guard.NotNull(protoDefinitionOrId);
|
||||
|
||||
#if PROTOBUF
|
||||
ProtoDefinition = ProtoDefinitionHelper.GetIdOrTexts(_settings, protoDefinitionOrId);
|
||||
ProtoDefinition = ProtoDefinitionUtils.GetIdOrTexts(_settings, protoDefinitionOrId);
|
||||
|
||||
return this;
|
||||
#else
|
||||
throw new NotSupportedException("The WithProtoDefinition method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -241,13 +241,13 @@ public partial class WireMockServer
|
||||
if (requestModel.Body?.Matcher != null)
|
||||
{
|
||||
var bodyMatcher = _matcherMapper.Map(requestModel.Body.Matcher)!;
|
||||
#if PROTOBUF
|
||||
|
||||
// If the BodyMatcher is a ProtoBufMatcher, and if ProtoDefinition is defined on Mapping-level, set the ProtoDefinition from that Mapping.
|
||||
if (bodyMatcher is ProtoBufMatcher protoBufMatcher && mappingModel?.ProtoDefinition != null)
|
||||
if (bodyMatcher is IProtoBufMatcher protoBufMatcher && mappingModel?.ProtoDefinition != null)
|
||||
{
|
||||
protoBufMatcher.ProtoDefinition = () => ProtoDefinitionHelper.GetIdOrTexts(_settings, mappingModel.ProtoDefinition);
|
||||
protoBufMatcher.ProtoDefinition = () => ProtoDefinitionUtils.GetIdOrTexts(_settings, mappingModel.ProtoDefinition);
|
||||
}
|
||||
#endif
|
||||
|
||||
requestBuilder = requestBuilder.WithBody(bodyMatcher);
|
||||
}
|
||||
else if (requestModel.Body?.Matchers != null)
|
||||
@@ -368,18 +368,19 @@ public partial class WireMockServer
|
||||
{
|
||||
if (responseModel.ProtoBufMessageType != null)
|
||||
{
|
||||
var protoBufUtils = TypeLoader.LoadStaticInstance<IProtoBufUtils>();
|
||||
|
||||
if (responseModel.ProtoDefinition != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBodyAsProtoBuf(responseModel.ProtoDefinition, responseModel.ProtoBufMessageType, responseModel.BodyAsJson);
|
||||
responseBuilder = protoBufUtils.UpdateResponseBuilder(responseBuilder, responseModel.ProtoBufMessageType, responseModel.BodyAsJson, responseModel.ProtoDefinition);
|
||||
}
|
||||
else if (responseModel.ProtoDefinitions != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBodyAsProtoBuf(responseModel.ProtoDefinitions, responseModel.ProtoBufMessageType, responseModel.BodyAsJson);
|
||||
responseBuilder = protoBufUtils.UpdateResponseBuilder(responseBuilder, responseModel.ProtoBufMessageType, responseModel.BodyAsJson, responseModel.ProtoDefinitions);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ProtoDefinition(s) is/are defined at Mapping/Server level
|
||||
responseBuilder = responseBuilder.WithBodyAsProtoBuf(responseModel.ProtoBufMessageType, responseModel.BodyAsJson);
|
||||
responseBuilder = protoBufUtils.UpdateResponseBuilder(responseBuilder, responseModel.ProtoBufMessageType, responseModel.BodyAsJson);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using HandlebarsDotNet.Helpers.Enums;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// HandlebarsSettings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public class HandlebarsSettings
|
||||
{
|
||||
internal static readonly Category[] DefaultAllowedHandlebarsHelpers =
|
||||
[
|
||||
Category.Boolean,
|
||||
Category.Constants,
|
||||
Category.DateTime,
|
||||
Category.Enumerable,
|
||||
Category.Humanizer,
|
||||
Category.JsonPath,
|
||||
Category.Math,
|
||||
Category.Object,
|
||||
Category.Random,
|
||||
Category.Regex,
|
||||
Category.String,
|
||||
Category.Url,
|
||||
Category.Xeger,
|
||||
Category.XPath,
|
||||
Category.Xslt
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Defines the allowed custom HandlebarsHelpers which can be used. Possible values are:
|
||||
/// - <see cref="CustomHandlebarsHelpers.None"/> (Default)
|
||||
/// - <see cref="CustomHandlebarsHelpers.File"/>
|
||||
/// - <see cref="CustomHandlebarsHelpers.All"/>
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public CustomHandlebarsHelpers AllowedCustomHandlebarsHelpers { get; set; } = CustomHandlebarsHelpers.None;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the allowed HandlebarHelpers which can be used.
|
||||
///
|
||||
/// By default, all categories except <see cref="Category.DynamicLinq"/> and <see cref="Category.Environment"/> are registered.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public Category[] AllowedHandlebarsHelpers { get; set; } = DefaultAllowedHandlebarsHelpers;
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// HttpClientSettings
|
||||
/// </summary>
|
||||
public abstract class HttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
public string? ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
public WebProxySettings? WebProxySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="X509Certificate2"/> to use.
|
||||
/// </summary>
|
||||
public X509Certificate2? Certificate { get; set; }
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// ProxyAndRecordSettings
|
||||
/// </summary>
|
||||
public class ProxyAndRecordSettings : HttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Default prefix value for saved mapping file
|
||||
/// </summary>
|
||||
public const string DefaultPrefixForSavedMappingFile = "Proxy Mapping for ";
|
||||
|
||||
/// <summary>
|
||||
/// The URL to proxy.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string Url { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Save the mapping for each request/response to the internal Mappings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool SaveMapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Save the mapping for each request/response also to a file. (Note that SaveMapping must also be set to true.)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool SaveMappingToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
||||
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
||||
///
|
||||
/// Deprecated : use SaveMappingSettings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string SaveMappingForStatusCodePattern
|
||||
{
|
||||
set
|
||||
{
|
||||
if (SaveMappingSettings is null)
|
||||
{
|
||||
SaveMappingSettings = new ProxySaveMappingSettings();
|
||||
}
|
||||
|
||||
SaveMappingSettings.StatusCodePattern = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Additional SaveMappingSettings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ProxySaveMappingSettings? SaveMappingSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines a list from headers which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string[]? ExcludedHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines a list of params which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string[]? ExcludedParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines a list of cookies which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string[]? ExcludedCookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Replace Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ProxyUrlReplaceSettings? ReplaceSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prefer the Proxy Mapping over the saved Mapping (in case SaveMapping is set to <c>true</c>).
|
||||
/// </summary>
|
||||
//[PublicAPI]
|
||||
//public bool PreferProxyMapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When SaveMapping is set to <c>true</c>, this setting can be used to control the behavior of the generated request matchers for the new mapping.
|
||||
/// - <c>false</c>, the default matchers will be used.
|
||||
/// - <c>true</c>, the defined mappings in the request wil be used for the new mapping.
|
||||
///
|
||||
/// Default value is false.
|
||||
/// </summary>
|
||||
public bool UseDefinedRequestMatchers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Append a unique GUID to the filename from the saved mapping file.
|
||||
/// </summary>
|
||||
public bool AppendGuidToSavedMappingFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set prefix for saved mapping file.
|
||||
/// </summary>
|
||||
public string PrefixForSavedMappingFile { get; set; } = DefaultPrefixForSavedMappingFile;
|
||||
|
||||
/// <summary>
|
||||
/// Proxy all Api calls, irrespective of any condition
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool ProxyAll { get; set; }
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// Represents settings for saving a proxy mapping with a non-nullable value and a specific match behaviour.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The non-nullable type of the value associated with the proxy save mapping setting.</typeparam>
|
||||
public class ProxySaveMappingSetting<T> where T : notnull
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the match behaviour for the proxy save mapping setting.
|
||||
/// </summary>
|
||||
/// <value>The match behaviour which determines how matches are evaluated.</value>
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the non-nullable value associated with the proxy save mapping setting.
|
||||
/// </summary>
|
||||
/// <value>The value of type <typeparamref name="T"/>.</value>
|
||||
public T Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ProxySaveMappingSetting{T}"/> class with specified non-nullable value and match behaviour.
|
||||
/// </summary>
|
||||
/// <param name="value">The non-nullable value of type <typeparamref name="T"/>.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour (optional, default is <c>MatchBehaviour.AcceptOnMatch</c>.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown if the <paramref name="value"/> is null.</exception>
|
||||
public ProxySaveMappingSetting(T value, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
Value = Guard.NotNull(value);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a non-nullable value of type <typeparamref name="T"/> to a <see cref="ProxySaveMappingSetting{T}"/> implicitly.
|
||||
/// </summary>
|
||||
/// <param name="value">The non-nullable value to convert.</param>
|
||||
public static implicit operator ProxySaveMappingSetting<T>(T value) => new(value);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="ProxySaveMappingSetting{T}"/> to its underlying non-nullable value of type <typeparamref name="T"/> implicitly.
|
||||
/// </summary>
|
||||
/// <param name="instance">The <see cref="ProxySaveMappingSetting{T}"/> to convert.</param>
|
||||
public static implicit operator T(ProxySaveMappingSetting<T> instance) => instance.Value;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// ProxySaveMappingSettings
|
||||
/// </summary>
|
||||
public class ProxySaveMappingSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Only save request/response to the internal Mappings if the status code is included in this pattern. (Note that SaveMapping must also be set to true.)
|
||||
/// The pattern can contain a single value like "200", but also ranges like "2xx", "100,300,600" or "100-299,6xx" are supported.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ProxySaveMappingSetting<string>? StatusCodePattern { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// Only save these Http Methods. (Note that SaveMapping must also be set to true.)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ProxySaveMappingSetting<string[]>? HttpMethods { get; set; }
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// Defines an old path param and a new path param to be replaced when proxying.
|
||||
/// </summary>
|
||||
public class ProxyUrlReplaceSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The old path value to be replaced by the new path value
|
||||
/// </summary>
|
||||
public string OldValue { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The new path value to replace the old value with
|
||||
/// </summary>
|
||||
public string NewValue { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the case should be ignored when replacing.
|
||||
/// </summary>
|
||||
public bool IgnoreCase { get; set; }
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// WebProxySettings
|
||||
/// </summary>
|
||||
public class WebProxySettings
|
||||
{
|
||||
/// <summary>
|
||||
/// A string instance that contains the address of the proxy server.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string Address { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// The username associated with the credentials.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The password for the username associated with the credentials.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? Password { get; set; }
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// WebhookSettings
|
||||
/// </summary>
|
||||
public class WebhookSettings : HttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes an action after the transformation of the request body.
|
||||
/// </summary>
|
||||
/// <param name="mapping">The mapping used for the request.</param>
|
||||
/// <param name="requestUrl">The request Url.</param>
|
||||
/// <param name="bodyData">The body data of the request. [Optional]</param>
|
||||
/// <param name="headers">The headers of the request. [Optional]</param>
|
||||
public virtual void PostTransform(IMapping mapping, string requestUrl, IBodyData? bodyData = null, IDictionary<string, WireMockList<string>>? headers = null)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
|
||||
///
|
||||
/// X509StoreName and X509StoreLocation should be defined
|
||||
/// OR
|
||||
/// X509CertificateFilePath should be defined
|
||||
/// OR
|
||||
/// X509Certificate should be defined
|
||||
/// </summary>
|
||||
public class WireMockCertificateSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// X.509 certificate StoreName (AddressBook, AuthRoot, CertificateAuthority, My, Root, TrustedPeople or TrustedPublisher)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? X509StoreName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X.509 certificate StoreLocation (CurrentUser or LocalMachine)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? X509StoreLocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X.509 certificate Thumbprint or SubjectName (if not defined, the 'host' is used)
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? X509StoreThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X.509 certificate FilePath
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? X509CertificateFilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A X.509 certificate instance.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public X509Certificate2? X509Certificate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X.509 certificate Password
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? X509CertificatePassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// X509StoreName and X509StoreLocation should be defined
|
||||
/// OR
|
||||
/// X509CertificateFilePath should be defined
|
||||
/// OR
|
||||
/// X509Certificate should be defined
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool IsDefined =>
|
||||
!string.IsNullOrEmpty(X509StoreName) && !string.IsNullOrEmpty(X509StoreLocation) ||
|
||||
!string.IsNullOrEmpty(X509CertificateFilePath) ||
|
||||
X509Certificate != null;
|
||||
}
|
||||
@@ -1,340 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using HandlebarsDotNet;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RegularExpressions;
|
||||
using WireMock.Types;
|
||||
using System.Globalization;
|
||||
using WireMock.Models;
|
||||
#if USE_ASPNETCORE
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// WireMockServerSettings
|
||||
/// </summary>
|
||||
public class WireMockServerSettings
|
||||
{
|
||||
internal const int DefaultStartTimeout = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the http port.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public int? Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the use SSL.
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
[PublicAPI]
|
||||
public bool? UseSSL { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines on which scheme (http/https) to host. (This overrides the <c>UseSSL</c> value).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public HostingScheme? HostingScheme { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets to use HTTP 2 (used for Grpc).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? UseHttp2 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to start admin interface.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? StartAdminInterface { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the static mappings should be read at startup.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? ReadStaticMappings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Watch the static mapping files + folder for changes when running.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? WatchStaticMappings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A value indicating whether subdirectories within the static mappings path should be monitored.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? WatchStaticMappingsInSubdirectories { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the proxy and record settings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ProxyAndRecordSettings? ProxyAndRecordSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the urls.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string[]? Urls { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// StartTimeout
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public int StartTimeout { get; set; } = DefaultStartTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// Allow Partial Mapping (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? AllowPartialMapping { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The username needed for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? AdminUsername { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The password needed for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? AdminPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AzureAD Tenant needed for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? AdminAzureADTenant { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AzureAD Audience / Resource for __admin access.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? AdminAzureADAudience { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The RequestLog expiration in hours (optional).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public int? RequestLogExpirationDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The MaxRequestLog count (optional).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public int? MaxRequestLogCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which is called (with the IAppBuilder or IApplicationBuilder) before the internal WireMockMiddleware is initialized. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<object>? PreWireMockMiddlewareInit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<object>? PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <summary>
|
||||
/// Action which is called with IServiceCollection when ASP.NET Core DI is being configured. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<IServiceCollection>? AdditionalServiceRegistration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Policies to use when using CORS. By default CORS is disabled. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public CorsPolicyOptions? CorsPolicyOptions { get; set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The IWireMockLogger which logs Debug, Info, Warning or Error
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public IWireMockLogger Logger { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to read and write static mapping files.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public IFileSystemHandler FileSystemHandler { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Action which can be used to add additional Handlebars registrations. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<IHandlebars, IFileSystemHandler>? HandlebarsRegistrationCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? AllowCSharpCodeMatcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow a Body for all HTTP Methods. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow only a HttpStatus Code in the response which is defined. (default set to <c>false</c>).
|
||||
/// - false : also null, 0, empty or invalid HttpStatus codes are allowed.
|
||||
/// - true : only codes defined in <see cref="System.Net.HttpStatusCode"/> are allowed.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to disable Json deserialization when processing requests. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? DisableJsonBodyParsing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Disable support for GZip and Deflate request body decompression. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? DisableRequestBodyDecompressing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to disable FormUrlEncoded deserializing when processing requests. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? DisableDeserializeFormUrlEncoded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Handle all requests synchronously. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? HandleRequestsSynchronously { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
|
||||
///
|
||||
/// X509StoreName and X509StoreLocation should be defined
|
||||
/// OR
|
||||
/// X509CertificateFilePath should be defined
|
||||
/// OR
|
||||
/// X509Certificate should be defined
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public WireMockCertificateSettings? CertificateSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines if custom CertificateSettings are defined
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool CustomCertificateDefined => CertificateSettings?.IsDefined == true;
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <summary>
|
||||
/// Client certificate mode for the server
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public ClientCertificateMode ClientCertificateMode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether to accept any client certificate
|
||||
/// </summary>
|
||||
public bool AcceptAnyClientCertificate { get; set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Defines the global IWebhookSettings to use.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public WebhookSettings? WebhookSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use the <see cref="RegexExtended"/> instead of the default <see cref="Regex"/> (default set to <c>true</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? UseRegexExtended { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Save unmatched requests to a file using the <see cref="IFileSystemHandler"/> (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? SaveUnmatchedRequests { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Don't save the response-string in the LogEntry when WithBody(Func{IRequestMessage, string}) or WithBody(Func{IRequestMessage, Task{string}}) is used. (default set to <c>false</c>).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public bool? DoNotSaveDynamicResponseInLogEntry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// See <seealso cref="QueryParameterMultipleValueSupport"/>.
|
||||
///
|
||||
/// Default value = "All".
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public QueryParameterMultipleValueSupport? QueryParameterMultipleValueSupport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Custom matcher mappings for static mappings
|
||||
/// </summary>
|
||||
[PublicAPI, JsonIgnore]
|
||||
public IDictionary<string, Func<MatcherModel, IMatcher>>? CustomMatcherMappings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="JsonSerializerSettings"/> used when the JSON response is generated.
|
||||
/// </summary>
|
||||
[PublicAPI, JsonIgnore]
|
||||
public JsonSerializerSettings? JsonSerializerSettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Culture to use.
|
||||
/// Currently used for:
|
||||
/// - Handlebars Transformer
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public CultureInfo Culture { get; set; } = CultureInfo.CurrentCulture;
|
||||
|
||||
/// <summary>
|
||||
/// A list of Grpc ProtoDefinitions which can be used.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public Dictionary<string, string[]>? ProtoDefinitions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of GraphQL Schemas which can be used.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public Dictionary<string, GraphQLSchemaDetails>? GraphQLSchemas { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The admin path to use for accessing the Admin REST interface.
|
||||
/// If not set <c>__/admin</c> is used.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string? AdminPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the additional Handlebars Settings.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public HandlebarsSettings? HandlebarsSettings { get; set; }
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.IO;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal static class FilePathUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Robust handling of the user defined path.
|
||||
/// Also supports Unix and Windows platforms
|
||||
/// </summary>
|
||||
/// <param name="path">The path to clean</param>
|
||||
public static string? CleanPath(string? path)
|
||||
{
|
||||
return path?.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes leading directory separator chars from the filepath, which could break Path.Combine
|
||||
/// </summary>
|
||||
/// <param name="path">The path to remove the loading DirectorySeparatorChars</param>
|
||||
public static string? RemoveLeadingDirectorySeparators(string? path)
|
||||
{
|
||||
return path?.TrimStart(Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combine two paths
|
||||
/// </summary>
|
||||
/// <param name="root">The root path</param>
|
||||
/// <param name="path">The path</param>
|
||||
public static string Combine(string root, string? path)
|
||||
{
|
||||
Guard.NotNull(root);
|
||||
|
||||
var result = RemoveLeadingDirectorySeparators(path);
|
||||
return result == null ? root : Path.Combine(root, result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a relative path from one path to another.
|
||||
/// </summary>
|
||||
/// <param name="relativeTo">The source path the result should be relative to. This path is always considered to be a directory..</param>
|
||||
/// <param name="path">The destination path.</param>
|
||||
/// <returns>The relative path, or path if the paths don't share the same root.</returns>
|
||||
public static string GetRelativePath(string relativeTo, string path)
|
||||
{
|
||||
#if NETCOREAPP3_1 || NET5_0_OR_GREATER || NETSTANDARD2_1
|
||||
return Path.GetRelativePath(relativeTo, path);
|
||||
#else
|
||||
Guard.NotNull(relativeTo);
|
||||
Guard.NotNull(path);
|
||||
|
||||
static string AppendDirectorySeparatorChar(string path)
|
||||
{
|
||||
// Append a slash only if the path is a directory and does not have a slash.
|
||||
if (!Path.HasExtension(path) && !path.EndsWith(Path.DirectorySeparatorChar.ToString()))
|
||||
{
|
||||
return path + Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
var fromUri = new System.Uri(AppendDirectorySeparatorChar(relativeTo));
|
||||
var toUri = new System.Uri(AppendDirectorySeparatorChar(path));
|
||||
|
||||
if (fromUri.Scheme != toUri.Scheme)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
var relativeUri = fromUri.MakeRelativeUri(toUri);
|
||||
var relativePath = System.Uri.UnescapeDataString(relativeUri.ToString());
|
||||
|
||||
if (string.Equals(toUri.Scheme, "FILE", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
return relativePath;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if PROTOBUF
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JsonConverter.Abstractions;
|
||||
using ProtoBufJsonConverter;
|
||||
using ProtoBufJsonConverter.Models;
|
||||
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal static class ProtoBufUtils
|
||||
{
|
||||
internal static async Task<byte[]> GetProtoBufMessageWithHeaderAsync(
|
||||
IReadOnlyList<string>? protoDefinitions,
|
||||
string? messageType,
|
||||
object? value,
|
||||
IJsonConverter? jsonConverter = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
if (protoDefinitions == null || string.IsNullOrWhiteSpace(messageType) || value is null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var resolver = new WireMockProtoFileResolver(protoDefinitions);
|
||||
var request = new ConvertToProtoBufRequest(protoDefinitions[0], messageType!, value, true)
|
||||
.WithProtoFileResolver(resolver);
|
||||
|
||||
return await SingletonFactory<Converter>
|
||||
.GetInstance()
|
||||
.ConvertAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,101 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if PROTOBUF
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ProtoBufJsonConverter;
|
||||
using ProtoBufJsonConverter.Models;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Util;
|
||||
|
||||
/// <summary>
|
||||
/// Some helper methods for Proto Definitions.
|
||||
/// </summary>
|
||||
public static class ProtoDefinitionHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Builds a dictionary of ProtoDefinitions from a directory.
|
||||
/// - The key will be the filename without extension.
|
||||
/// - The value will be the ProtoDefinition with an extra comment with the relative path to each <c>.proto</c> file so it can be used by the WireMockProtoFileResolver.
|
||||
/// </summary>
|
||||
/// <param name="directory">The directory to start from.</param>
|
||||
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <c>System.Threading.CancellationToken.None</c>.</param>
|
||||
public static async Task<ProtoDefinitionData> FromDirectory(string directory, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Guard.NotNullOrEmpty(directory);
|
||||
|
||||
var fileNameMappedToProtoDefinition = new Dictionary<string, string>();
|
||||
var filePaths = Directory.EnumerateFiles(directory, "*.proto", SearchOption.AllDirectories);
|
||||
|
||||
foreach (var filePath in filePaths)
|
||||
{
|
||||
// Get the relative path to the directory (note that this will be OS specific).
|
||||
var relativePath = FilePathUtils.GetRelativePath(directory, filePath);
|
||||
|
||||
// Make it a valid proto import path
|
||||
var protoRelativePath = relativePath.Replace(Path.DirectorySeparatorChar, '/');
|
||||
|
||||
// Build comment and get content from file.
|
||||
var comment = $"// {protoRelativePath}";
|
||||
#if NETSTANDARD2_0
|
||||
var content = File.ReadAllText(filePath);
|
||||
#else
|
||||
var content = await File.ReadAllTextAsync(filePath, cancellationToken);
|
||||
#endif
|
||||
// Only add the comment if it's not already defined.
|
||||
var modifiedContent = !content.StartsWith(comment) ? $"{comment}\n{content}" : content;
|
||||
var key = Path.GetFileNameWithoutExtension(filePath);
|
||||
|
||||
fileNameMappedToProtoDefinition.Add(key, modifiedContent);
|
||||
}
|
||||
|
||||
var converter = SingletonFactory<Converter>.GetInstance();
|
||||
var resolver = new WireMockProtoFileResolver(fileNameMappedToProtoDefinition.Values);
|
||||
|
||||
var messageTypeMappedToWithProtoDefinition = new Dictionary<string, string>();
|
||||
|
||||
foreach (var protoDefinition in fileNameMappedToProtoDefinition.Values)
|
||||
{
|
||||
var infoRequest = new GetInformationRequest(protoDefinition, resolver);
|
||||
|
||||
try
|
||||
{
|
||||
var info = await converter.GetInformationAsync(infoRequest, cancellationToken);
|
||||
foreach (var messageType in info.MessageTypes)
|
||||
{
|
||||
messageTypeMappedToWithProtoDefinition[messageType.Key] = protoDefinition;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
return new ProtoDefinitionData(fileNameMappedToProtoDefinition);
|
||||
}
|
||||
|
||||
internal static IdOrTexts GetIdOrTexts(WireMockServerSettings settings, params string[] protoDefinitionOrId)
|
||||
{
|
||||
switch (protoDefinitionOrId.Length)
|
||||
{
|
||||
case 1:
|
||||
var idOrText = protoDefinitionOrId[0];
|
||||
if (settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitions) == true)
|
||||
{
|
||||
return new(idOrText, protoDefinitions);
|
||||
}
|
||||
|
||||
return new(null, protoDefinitionOrId);
|
||||
|
||||
default:
|
||||
return new(null, protoDefinitionOrId);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,26 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Util;
|
||||
|
||||
internal static class SingletonLock
|
||||
{
|
||||
public static readonly object Lock = new();
|
||||
}
|
||||
|
||||
internal static class SingletonFactory<T> where T : class, new()
|
||||
{
|
||||
private static T? _instance;
|
||||
|
||||
public static T GetInstance()
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
lock (SingletonLock.Lock)
|
||||
{
|
||||
_instance ??= new T();
|
||||
}
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if PROTOBUF
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ProtoBufJsonConverter;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
|
||||
namespace WireMock.Util;
|
||||
|
||||
/// <summary>
|
||||
/// This resolver is used to resolve the extra ProtoDefinition files.
|
||||
///
|
||||
/// It assumes that:
|
||||
/// - The first commented line of each ProtoDefinition file is the filepath which is used in the import of the other ProtoDefinition file(s).
|
||||
/// </summary>
|
||||
internal class WireMockProtoFileResolver : IProtoFileResolver
|
||||
{
|
||||
private readonly Dictionary<string, string> _files = [];
|
||||
|
||||
public WireMockProtoFileResolver(IReadOnlyCollection<string> protoDefinitions)
|
||||
{
|
||||
if (Guard.NotNullOrEmpty(protoDefinitions).Count() <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var extraProtoDefinition in protoDefinitions)
|
||||
{
|
||||
var firstNonEmptyLine = extraProtoDefinition.Split(['\r', '\n']).FirstOrDefault(l => !string.IsNullOrEmpty(l));
|
||||
if (firstNonEmptyLine != null)
|
||||
{
|
||||
if (TryGetValidPath(firstNonEmptyLine.TrimStart(['/', ' ']), out var validPath))
|
||||
{
|
||||
_files.Add(validPath, extraProtoDefinition);
|
||||
}
|
||||
else
|
||||
{
|
||||
_files.Add(extraProtoDefinition.GetDeterministicHashCodeAsString(), extraProtoDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Exists(string path)
|
||||
{
|
||||
return _files.ContainsKey(path);
|
||||
}
|
||||
|
||||
public TextReader OpenText(string path)
|
||||
{
|
||||
if (_files.TryGetValue(path, out var extraProtoDefinition))
|
||||
{
|
||||
return new StringReader(extraProtoDefinition);
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"The ProtoDefinition '{path}' was not found.");
|
||||
}
|
||||
|
||||
private static bool TryGetValidPath(string path, [NotNullWhen(true)] out string? validPath)
|
||||
{
|
||||
if (!path.Any(c => Path.GetInvalidPathChars().Contains(c)))
|
||||
{
|
||||
validPath = path;
|
||||
return true;
|
||||
}
|
||||
|
||||
validPath = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -125,9 +125,9 @@
|
||||
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
||||
<!--<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
||||
<PackageReference Include="ProtoBufJsonConverter" Version="0.10.0" />
|
||||
</ItemGroup>
|
||||
</ItemGroup>-->
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||
<!--<PackageReference Include="Nullable" Version="1.3.1">
|
||||
@@ -155,16 +155,6 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.5.2" />
|
||||
<!--<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.5.2" />-->
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.5.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' ">
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Xslt" Version="2.5.2" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user