Change the serialization from the WireMockServerSettings in the logging when WireMockServer is started

This commit is contained in:
Stef Heyenrath
2026-07-01 11:21:56 +02:00
parent cbc28c235c
commit 56c606e1c4
6 changed files with 237 additions and 7 deletions
@@ -1,8 +1,6 @@
// Copyright © WireMock.Net
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using log4net;
using log4net.Config;
using log4net.Repository;
@@ -12,7 +10,7 @@ namespace WireMock.Net.Console.NET8;
static class Program
{
private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly());
private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly()!);
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
static async Task Main(params string[] args)
@@ -70,7 +70,7 @@ public class WireMockService : IWireMockService
_server = WireMockServer.Start(_settings);
_logger.LogInformation($"WireMock.Net server settings {JsonConvert.SerializeObject(_settings)}");
_logger.LogInformation("WireMock.Net server settings {Settings}", JsonConvert.SerializeObject(_settings));
}
public void Stop()
@@ -357,6 +357,7 @@ public class WireMockServerSettings
/// Default is <see cref="NewtonsoftJsonConverter"/>.
/// </remarks>
[PublicAPI]
[JsonConverter(typeof(WireMockSettingsJsonConverter))]
public IJsonConverter DefaultJsonSerializer { get; set; }
/// <summary>
@@ -367,7 +368,7 @@ public class WireMockServerSettings
/// Default is <see cref="NewtonsoftJsonBodyTransformer"/>.
/// </remarks>
[PublicAPI]
[JsonIgnore]
[JsonConverter(typeof(WireMockSettingsJsonConverter))]
public IJsonBodyTransformer DefaultJsonBodyTransformer { get; set; }
/// <summary>
@@ -0,0 +1,151 @@
// Copyright © WireMock.Net
using System.Reflection;
using JsonConverter.Abstractions;
using JsonConverter.Newtonsoft.Json;
using JsonConverter.System.Text.Json;
using Newtonsoft.Json;
using WireMock.Transformers;
using NewtonsoftJsonConverterBase = Newtonsoft.Json.JsonConverter;
namespace WireMock.Settings;
/// <summary>
/// WireMockSettingsJsonConverter serializes and deserializes the special interface-based settings properties as type names.
/// </summary>
public class WireMockSettingsJsonConverter : NewtonsoftJsonConverterBase
{
/// <inheritdoc />
public override bool CanConvert(Type objectType)
{
return typeof(IJsonConverter).IsAssignableFrom(objectType) || typeof(IJsonBodyTransformer).IsAssignableFrom(objectType);
}
/// <inheritdoc />
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
writer.WriteValue(value?.GetType().FullName);
}
/// <inheritdoc />
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return existingValue ?? CreateDefaultValue(objectType);
}
if (reader.TokenType != JsonToken.String)
{
reader.Skip();
return existingValue ?? CreateDefaultValue(objectType);
}
var typeName = reader.Value as string;
if (typeof(IJsonConverter).IsAssignableFrom(objectType))
{
return CreateJsonConverter(typeName) ?? existingValue ?? new NewtonsoftJsonConverter();
}
if (typeof(IJsonBodyTransformer).IsAssignableFrom(objectType))
{
var settings = ExtractSettings(existingValue as IJsonBodyTransformer);
return settings != null
? CreateJsonBodyTransformer(typeName, settings) ?? existingValue ?? new NewtonsoftJsonBodyTransformer(settings)
: existingValue;
}
return existingValue;
}
private static object? CreateDefaultValue(Type objectType)
{
if (typeof(IJsonConverter).IsAssignableFrom(objectType))
{
return new NewtonsoftJsonConverter();
}
return null;
}
private static IJsonConverter? CreateJsonConverter(string? typeName)
{
if (string.IsNullOrWhiteSpace(typeName))
{
return null;
}
if (typeName == nameof(NewtonsoftJsonConverter) || typeName == typeof(NewtonsoftJsonConverter).FullName)
{
return new NewtonsoftJsonConverter();
}
if (typeName == nameof(SystemTextJsonConverter) || typeName == typeof(SystemTextJsonConverter).FullName)
{
return new SystemTextJsonConverter();
}
var type = GetType(typeName);
if (type == null || !typeof(IJsonConverter).IsAssignableFrom(type))
{
return null;
}
return Activator.CreateInstance(type) as IJsonConverter;
}
private static IJsonBodyTransformer? CreateJsonBodyTransformer(string? typeName, WireMockServerSettings settings)
{
if (string.IsNullOrWhiteSpace(typeName))
{
return null;
}
if (typeName == nameof(NewtonsoftJsonBodyTransformer) || typeName == typeof(NewtonsoftJsonBodyTransformer).FullName)
{
return new NewtonsoftJsonBodyTransformer(settings);
}
if (typeName == nameof(SystemTextJsonBodyTransformer) || typeName == typeof(SystemTextJsonBodyTransformer).FullName)
{
return new SystemTextJsonBodyTransformer(settings);
}
var type = GetType(typeName);
if (type == null || !typeof(IJsonBodyTransformer).IsAssignableFrom(type))
{
return null;
}
var constructorWithSettings = type.GetConstructor([typeof(WireMockServerSettings)]);
if (constructorWithSettings != null)
{
return constructorWithSettings.Invoke([settings]) as IJsonBodyTransformer;
}
return Activator.CreateInstance(type) as IJsonBodyTransformer;
}
private static WireMockServerSettings? ExtractSettings(IJsonBodyTransformer? existingValue)
{
if (existingValue == null)
{
return null;
}
return existingValue.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)
.Where(field => typeof(WireMockServerSettings).IsAssignableFrom(field.FieldType))
.Select(field => field.GetValue(existingValue) as WireMockServerSettings)
.FirstOrDefault(settings => settings != null);
}
private static Type? GetType(string typeName)
{
return Type.GetType(typeName, throwOnError: false) ??
AppDomain.CurrentDomain.GetAssemblies()
.Select(assembly => assembly.GetType(typeName, throwOnError: false))
.FirstOrDefault(foundType => foundType != null);
}
}
-2
View File
@@ -1,7 +1,5 @@
// Copyright © WireMock.Net
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using WireMock.Logging;
using WireMock.Net.StandAlone;
@@ -0,0 +1,82 @@
// Copyright © WireMock.Net
using JsonConverter.Newtonsoft.Json;
using JsonConverter.System.Text.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Settings;
using WireMock.Transformers;
namespace WireMock.Net.Tests.Settings;
public class WireMockServerSettingsJsonTests
{
[Fact]
public void NewtonsoftJson_Serialize_WireMockServerSettings_HandlesSpecialProperties_AndKeepsOtherPropertiesAsIs()
{
// Arrange
var settings = new WireMockServerSettings
{
Port = 1234,
AdminPath = "/custom-admin",
StartAdminInterface = true,
DefaultJsonSerializer = new SystemTextJsonConverter()
};
settings.DefaultJsonBodyTransformer = new SystemTextJsonBodyTransformer(settings);
// Act
var json = JsonConvert.SerializeObject(settings);
var jsonObject = JObject.Parse(json);
// Assert
jsonObject[nameof(WireMockServerSettings.Port)]!.Value<int>().Should().Be(1234);
jsonObject[nameof(WireMockServerSettings.AdminPath)]!.Value<string>().Should().Be("/custom-admin");
jsonObject[nameof(WireMockServerSettings.StartAdminInterface)]!.Value<bool>().Should().BeTrue();
jsonObject[nameof(WireMockServerSettings.DefaultJsonSerializer)]!.Type.Should().Be(JTokenType.String);
jsonObject[nameof(WireMockServerSettings.DefaultJsonSerializer)]!.Value<string>().Should().Be(typeof(SystemTextJsonConverter).FullName);
jsonObject[nameof(WireMockServerSettings.DefaultJsonBodyTransformer)]!.Type.Should().Be(JTokenType.String);
jsonObject[nameof(WireMockServerSettings.DefaultJsonBodyTransformer)]!.Value<string>().Should().Be(typeof(SystemTextJsonBodyTransformer).FullName);
}
[Fact]
public void NewtonsoftJson_Deserialize_WireMockServerSettings_HandlesSpecialProperties_AndKeepsOtherPropertiesAsIs()
{
// Arrange
var json =
$"{{\"{nameof(WireMockServerSettings.Port)}\":4321," +
$"\"{nameof(WireMockServerSettings.AdminPath)}\":\"/custom-admin\"," +
$"\"{nameof(WireMockServerSettings.StartAdminInterface)}\":true," +
$"\"{nameof(WireMockServerSettings.DefaultJsonSerializer)}\":\"{typeof(SystemTextJsonConverter).FullName}\"," +
$"\"{nameof(WireMockServerSettings.DefaultJsonBodyTransformer)}\":\"{typeof(SystemTextJsonBodyTransformer).FullName}\"}}";
// Act
var settings = JsonConvert.DeserializeObject<WireMockServerSettings>(json);
// Assert
settings.Should().NotBeNull();
settings!.Port.Should().Be(4321);
settings.AdminPath.Should().Be("/custom-admin");
settings.StartAdminInterface.Should().BeTrue();
settings.DefaultJsonSerializer.Should().BeOfType<SystemTextJsonConverter>();
settings.DefaultJsonBodyTransformer.Should().BeOfType<SystemTextJsonBodyTransformer>();
}
[Fact]
public void NewtonsoftJson_Deserialize_WireMockServerSettings_LegacyObjects_AreIgnored_AndOtherPropertiesStayUntouched()
{
// Arrange
var json =
$"{{\"{nameof(WireMockServerSettings.Port)}\":9876," +
$"\"{nameof(WireMockServerSettings.DefaultJsonSerializer)}\":{{}}," +
$"\"{nameof(WireMockServerSettings.DefaultJsonBodyTransformer)}\":{{}}}}";
// Act
var settings = JsonConvert.DeserializeObject<WireMockServerSettings>(json);
// Assert
settings.Should().NotBeNull();
settings!.Port.Should().Be(9876);
settings.DefaultJsonSerializer.Should().BeOfType<NewtonsoftJsonConverter>();
settings.DefaultJsonBodyTransformer.Should().BeOfType<NewtonsoftJsonBodyTransformer>();
}
}