mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-22 16:28:27 +02:00
Add Grpc ProtoBuf support (request-response) (#1047)
* ProtoBuf
* .
* x
* ---
* x
* fx
* ...
* sc
* ...
* .
* groen
* x
* fix tests
* ok!?
* fix tests
* fix tests
* !
* x
* 6
* .
* x
* ivaluematcher
* transformer
* .
* sc
* .
* mapping
* x
* tra
* com
* ...
* .
* .
* .
* AddProtoDefinition
* .
* set
* grpahj
* .
* .
* IdOrText
* ...
* async
* async2
* .
* t
* nuget
* <PackageReference Include="ProtoBufJsonConverter" Version="0.2.0-preview-04" />
* http version
* tests
* .WithHttpVersion("2")
* <PackageReference Include="ProtoBufJsonConverter" Version="0.2.0" />
* HttpVersionParser
This commit is contained in:
@@ -184,4 +184,21 @@ public interface IRespondWithAProvider
|
||||
/// <param name="probability">The probability when this request should be matched. Value is between 0 and 1.</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithProbability(double probability);
|
||||
|
||||
/// <summary>
|
||||
/// Define a Grpc ProtoDefinition which is used for the request and the response.
|
||||
/// This can be a ProtoDefinition as a string, or an id when the ProtoDefinitions are defined at the WireMockServer.
|
||||
/// </summary>
|
||||
/// <param name="protoDefinitionOrId">The proto definition as text or as id.</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithProtoDefinition(string protoDefinitionOrId);
|
||||
|
||||
/// <summary>
|
||||
/// Define a GraphQL Schema which is used for the request and the response.
|
||||
/// This can be a GraphQL Schema as a string, or an id when the GraphQL Schema are defined at the WireMockServer.
|
||||
/// </summary>
|
||||
/// <param name="graphQLSchemaOrId">The GraphQL Schema as text or as id.</param>
|
||||
/// <param name="customScalars">A dictionary defining the custom scalars used in this schema. [optional]</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithGraphQLSchema(string graphQLSchemaOrId, IDictionary<string, Type>? customScalars = null);
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
@@ -34,6 +33,8 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
private int _timesInSameState = 1;
|
||||
private bool? _useWebhookFireAndForget;
|
||||
private double? _probability;
|
||||
private IdOrText? _protoDefinition;
|
||||
private GraphQLSchemaDetails? _graphQLSchemaDetails;
|
||||
|
||||
public Guid Guid { get; private set; }
|
||||
|
||||
@@ -76,7 +77,8 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
/// <param name="provider">The provider.</param>
|
||||
public void RespondWith(IResponseProvider provider)
|
||||
{
|
||||
var mapping = new Mapping(
|
||||
var mapping = new Mapping
|
||||
(
|
||||
Guid,
|
||||
_dateTimeUtils.UtcNow,
|
||||
_title,
|
||||
@@ -93,14 +95,23 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
Webhooks,
|
||||
_useWebhookFireAndForget,
|
||||
TimeSettings,
|
||||
Data,
|
||||
_probability);
|
||||
Data
|
||||
);
|
||||
|
||||
if (_probability != null)
|
||||
{
|
||||
mapping.WithProbability(_probability.Value);
|
||||
}
|
||||
|
||||
if (_protoDefinition != null)
|
||||
{
|
||||
mapping.WithProtoDefinition(_protoDefinition.Value);
|
||||
}
|
||||
|
||||
_registrationCallback(mapping, _saveToFile);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IRespondWithAProvider WithData(object data)
|
||||
{
|
||||
Data = data;
|
||||
@@ -117,7 +128,6 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
public IRespondWithAProvider WithGuid(Guid guid)
|
||||
{
|
||||
Guid = guid;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -133,7 +143,6 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
public IRespondWithAProvider WithDescription(string description)
|
||||
{
|
||||
_description = description;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -141,7 +150,6 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
public IRespondWithAProvider WithPath(string path)
|
||||
{
|
||||
_path = path;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -149,15 +157,13 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
public IRespondWithAProvider AtPriority(int priority)
|
||||
{
|
||||
_priority = priority;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider InScenario(string scenario)
|
||||
{
|
||||
_scenario = scenario;
|
||||
|
||||
_scenario = Guard.NotNullOrWhiteSpace(scenario);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -209,9 +215,7 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithTimeSettings(ITimeSettings timeSettings)
|
||||
{
|
||||
Guard.NotNull(timeSettings, nameof(timeSettings));
|
||||
|
||||
TimeSettings = timeSettings;
|
||||
TimeSettings = Guard.NotNull(timeSettings);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -219,10 +223,9 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithWebhook(params IWebhook[] webhooks)
|
||||
{
|
||||
Guard.HasNoNulls(webhooks, nameof(webhooks));
|
||||
Guard.HasNoNulls(webhooks);
|
||||
|
||||
Webhooks = webhooks;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -283,13 +286,45 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
public IRespondWithAProvider WithWebhookFireAndForget(bool useWebhooksFireAndForget)
|
||||
{
|
||||
_useWebhookFireAndForget = useWebhooksFireAndForget;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IRespondWithAProvider WithProbability(double probability)
|
||||
{
|
||||
_probability = Guard.Condition(probability, p => p is >= 0 and <= 1.0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithProtoDefinition(string protoDefinitionOrId)
|
||||
{
|
||||
Guard.NotNullOrWhiteSpace(protoDefinitionOrId);
|
||||
|
||||
if (_settings.ProtoDefinitions?.TryGetValue(protoDefinitionOrId, out var protoDefinition) == true)
|
||||
{
|
||||
_protoDefinition = new (protoDefinitionOrId, protoDefinition);
|
||||
}
|
||||
else
|
||||
{
|
||||
_protoDefinition = new(null, protoDefinitionOrId);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRespondWithAProvider WithGraphQLSchema(string graphQLSchemaOrId, IDictionary<string, Type>? customScalars = null)
|
||||
{
|
||||
Guard.NotNullOrWhiteSpace(graphQLSchemaOrId);
|
||||
|
||||
if (_settings.GraphQLSchemas?.TryGetValue(graphQLSchemaOrId, out _graphQLSchemaDetails) != true)
|
||||
{
|
||||
_graphQLSchemaDetails = new GraphQLSchemaDetails
|
||||
{
|
||||
SchemaAsString = graphQLSchemaOrId,
|
||||
CustomScalars = customScalars
|
||||
};
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -299,7 +334,8 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
||||
string method,
|
||||
IDictionary<string, WireMockList<string>>? headers,
|
||||
bool useTransformer,
|
||||
TransformerType transformerType)
|
||||
TransformerType transformerType
|
||||
)
|
||||
{
|
||||
return new Webhook
|
||||
{
|
||||
|
||||
@@ -231,9 +231,11 @@ public partial class WireMockServer
|
||||
DisableRequestBodyDecompressing = _settings.DisableRequestBodyDecompressing,
|
||||
DoNotSaveDynamicResponseInLogEntry = _settings.DoNotSaveDynamicResponseInLogEntry,
|
||||
GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds,
|
||||
// GraphQLSchemas TODO
|
||||
HandleRequestsSynchronously = _settings.HandleRequestsSynchronously,
|
||||
HostingScheme = _settings.HostingScheme,
|
||||
MaxRequestLogCount = _settings.MaxRequestLogCount,
|
||||
ProtoDefinitions = _settings.ProtoDefinitions,
|
||||
QueryParameterMultipleValueSupport = _settings.QueryParameterMultipleValueSupport,
|
||||
ReadStaticMappings = _settings.ReadStaticMappings,
|
||||
RequestLogExpirationDuration = _settings.RequestLogExpirationDuration,
|
||||
@@ -268,6 +270,7 @@ public partial class WireMockServer
|
||||
_settings.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry;
|
||||
_settings.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
|
||||
_settings.MaxRequestLogCount = settings.MaxRequestLogCount;
|
||||
_settings.ProtoDefinitions = settings.ProtoDefinitions;
|
||||
_settings.ProxyAndRecordSettings = TinyMapperUtils.Instance.Map(settings.ProxyAndRecordSettings);
|
||||
_settings.QueryParameterMultipleValueSupport = settings.QueryParameterMultipleValueSupport;
|
||||
_settings.ReadStaticMappings = settings.ReadStaticMappings;
|
||||
|
||||
@@ -195,6 +195,11 @@ public partial class WireMockServer
|
||||
requestBuilder = requestBuilder.UsingMethod(matchBehaviour, matchOperator, requestModel.Methods);
|
||||
}
|
||||
|
||||
if (requestModel.HttpVersion != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithHttpVersion(requestModel.HttpVersion);
|
||||
}
|
||||
|
||||
if (requestModel.Headers != null)
|
||||
{
|
||||
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
@@ -18,6 +19,7 @@ using WireMock.Handlers;
|
||||
using WireMock.Http;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
using WireMock.Owin;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
@@ -209,19 +211,38 @@ public partial class WireMockServer : IWireMockServer
|
||||
return new WireMockServer(settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts this WireMockServer with the specified settings.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to configure the WireMockServerSettings.</param>
|
||||
/// <returns>The <see cref="WireMockServer"/>.</returns>
|
||||
[PublicAPI]
|
||||
public static WireMockServer Start(Action<WireMockServerSettings> action)
|
||||
{
|
||||
Guard.NotNull(action);
|
||||
|
||||
var settings = new WireMockServerSettings();
|
||||
|
||||
action(settings);
|
||||
|
||||
return new WireMockServer(settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start this WireMockServer.
|
||||
/// </summary>
|
||||
/// <param name="port">The port.</param>
|
||||
/// <param name="ssl">The SSL support.</param>
|
||||
/// <param name="useSSL">The SSL support.</param>
|
||||
/// <param name="useHttp2">Use HTTP 2 (needed for Grpc).</param>
|
||||
/// <returns>The <see cref="WireMockServer"/>.</returns>
|
||||
[PublicAPI]
|
||||
public static WireMockServer Start(int? port = 0, bool ssl = false)
|
||||
public static WireMockServer Start(int? port = 0, bool useSSL = false, bool useHttp2 = false)
|
||||
{
|
||||
return new WireMockServer(new WireMockServerSettings
|
||||
{
|
||||
Port = port,
|
||||
UseSSL = ssl
|
||||
UseSSL = useSSL,
|
||||
UseHttp2 = useHttp2
|
||||
});
|
||||
}
|
||||
|
||||
@@ -245,15 +266,17 @@ public partial class WireMockServer : IWireMockServer
|
||||
/// Start this WireMockServer with the admin interface.
|
||||
/// </summary>
|
||||
/// <param name="port">The port.</param>
|
||||
/// <param name="ssl">The SSL support.</param>
|
||||
/// <param name="useSSL">The SSL support.</param>
|
||||
/// <param name="useHttp2">Use HTTP 2 (needed for Grpc).</param>
|
||||
/// <returns>The <see cref="WireMockServer"/>.</returns>
|
||||
[PublicAPI]
|
||||
public static WireMockServer StartWithAdminInterface(int? port = 0, bool ssl = false)
|
||||
public static WireMockServer StartWithAdminInterface(int? port = 0, bool useSSL = false, bool useHttp2 = false)
|
||||
{
|
||||
return new WireMockServer(new WireMockServerSettings
|
||||
{
|
||||
Port = port,
|
||||
UseSSL = ssl,
|
||||
UseSSL = useSSL,
|
||||
UseHttp2 = useHttp2,
|
||||
StartAdminInterface = true
|
||||
});
|
||||
}
|
||||
@@ -266,7 +289,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
[PublicAPI]
|
||||
public static WireMockServer StartWithAdminInterface(params string[] urls)
|
||||
{
|
||||
Guard.NotNullOrEmpty(urls, nameof(urls));
|
||||
Guard.NotNullOrEmpty(urls);
|
||||
|
||||
return new WireMockServer(new WireMockServerSettings
|
||||
{
|
||||
@@ -329,6 +352,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
urlOptions = new HostUrlOptions
|
||||
{
|
||||
HostingScheme = settings.HostingScheme.Value,
|
||||
UseHttp2 = settings.UseHttp2,
|
||||
Port = settings.Port
|
||||
};
|
||||
}
|
||||
@@ -337,6 +361,7 @@ public partial class WireMockServer : IWireMockServer
|
||||
urlOptions = new HostUrlOptions
|
||||
{
|
||||
HostingScheme = settings.UseSSL == true ? HostingScheme.Https : HostingScheme.Http,
|
||||
UseHttp2 = settings.UseHttp2,
|
||||
Port = settings.Port
|
||||
};
|
||||
}
|
||||
@@ -573,6 +598,49 @@ public partial class WireMockServer : IWireMockServer
|
||||
return _mappingBuilder.Given(requestMatcher, saveToFile);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a Grpc ProtoDefinition at server-level.
|
||||
/// </summary>
|
||||
/// <param name="id">Unique identifier for the ProtoDefinition.</param>
|
||||
/// <param name="protoDefinition">The ProtoDefinition as text.</param>
|
||||
/// <returns><see cref="WireMockServer"/></returns>
|
||||
[PublicAPI]
|
||||
public WireMockServer AddProtoDefinition(string id, string protoDefinition)
|
||||
{
|
||||
Guard.NotNullOrWhiteSpace(id);
|
||||
Guard.NotNullOrWhiteSpace(protoDefinition);
|
||||
|
||||
_settings.ProtoDefinitions ??= new Dictionary<string, string>();
|
||||
|
||||
_settings.ProtoDefinitions[id] = protoDefinition;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a GraphQL Schema at server-level.
|
||||
/// </summary>
|
||||
/// <param name="id">Unique identifier for the GraphQL Schema.</param>
|
||||
/// <param name="graphQLSchema">The GraphQL Schema as string or StringPattern.</param>
|
||||
/// <param name="customScalars">A dictionary defining the custom scalars used in this schema. [optional]</param>
|
||||
/// <returns><see cref="WireMockServer"/></returns>
|
||||
[PublicAPI]
|
||||
public WireMockServer AddGraphQLSchema(string id, AnyOf<string, StringPattern> graphQLSchema, Dictionary<string, Type>? customScalars = null)
|
||||
{
|
||||
Guard.NotNullOrWhiteSpace(id);
|
||||
Guard.NotNullOrWhiteSpace(graphQLSchema);
|
||||
|
||||
_settings.GraphQLSchemas ??= new Dictionary<string, GraphQLSchemaDetails>();
|
||||
|
||||
_settings.GraphQLSchemas[id] = new GraphQLSchemaDetails
|
||||
{
|
||||
SchemaAsString = graphQLSchema,
|
||||
CustomScalars = customScalars
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public string? MappingToCSharpCode(Guid guid, MappingConverterType converterType)
|
||||
|
||||
Reference in New Issue
Block a user