Compare commits

..

5 Commits

Author SHA1 Message Date
Stef Heyenrath
ce2db748f1 1.0.4.0 2018-06-23 11:26:24 +02:00
Stef Heyenrath
443fc76773 Add request / response logging (#151)
Add request / response logging (#151)
2018-06-23 11:22:07 +02:00
Stef Heyenrath
454051568a 1.0.3.20 2018-05-29 22:01:15 +02:00
Stef Heyenrath
2b498f45cb Revert PortUtil.cs changes (#147) 2018-05-29 21:58:56 +02:00
Stef Heyenrath
2fcfda49c7 Update changelog 2018-05-28 15:13:34 +02:00
15 changed files with 164 additions and 75 deletions

View File

@@ -1,9 +1,28 @@
# 1.0.4.0 (23 June 2018)
- [#151](https://github.com/WireMock-Net/WireMock.Net/issues/151) - Feature: Add logging of incoming request and body for tracability
- [#149](https://github.com/WireMock-Net/WireMock.Net/issues/149) - Question: Transformer and Delay in Static Mappings?
- [#131](https://github.com/WireMock-Net/WireMock.Net/issues/131) - Bug: CurlException Couldn't connect to Server when running multiple tests
Commits: 443fc76773...443fc76773
# 1.0.3.20 (29 May 2018)
- [#147](https://github.com/WireMock-Net/WireMock.Net/pull/147) - Revert PortUtil.cs changes contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#146](https://github.com/WireMock-Net/WireMock.Net/issues/146) - Hang possibly due to Windows firewall prompt
- [#129](https://github.com/WireMock-Net/WireMock.Net/issues/129) - Random test failures between WireMock.Net 1.0.3.1 and 1.0.3.2
Commits: 2fcfda49c7...2b498f45cb
# 1.0.3.19 (28 May 2018)
- [#129](https://github.com/WireMock-Net/WireMock.Net/issues/129) - Random test failures between WireMock.Net 1.0.3.1 and 1.0.3.2
- [#145](https://github.com/WireMock-Net/WireMock.Net/pull/145) - Cancellation token not passed to server instance in .NET Core 2 contributed by Bob Paul ([Bob11327](https://github.com/Bob11327)) +fix
- [#144](https://github.com/WireMock-Net/WireMock.Net/pull/144) - Fix ConcurrentDictionary (#129) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
Commits: 0640c88bcd...297743a19a
Commits: ...
# 1.0.3.18 (25 May 2018)

View File

@@ -1,5 +1,5 @@
https://github.com/GitTools/GitReleaseNotes
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.3.19
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.4.0
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags

View File

@@ -1,6 +1,7 @@
using System;
using System.Net;
using Newtonsoft.Json;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
@@ -28,7 +29,8 @@ namespace WireMock.Net.ConsoleApplication
// SaveMapping = true
//},
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); }
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); },
Logger = new WireMockConsoleLogger()
});
System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(",", server.Urls));

View File

@@ -1,4 +1,6 @@
using log4net;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
using WireMock.Logging;
namespace WireMock.Net.StandAlone.NETCoreApp
@@ -26,5 +28,11 @@ namespace WireMock.Net.StandAlone.NETCoreApp
{
Log.ErrorFormat(formatString, args);
}
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
Log.DebugFormat("Admin[{0}] {1}", isAdminRequest, message);
}
}
}

View File

@@ -1,6 +1,7 @@
using System.Threading;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
using WireMock.Logging;
using WireMock.Net.StandAlone;
using WireMock.Settings;
@@ -42,6 +43,12 @@ namespace WireMock.Net.WebApplication
{
_logger.LogError(formatString, args);
}
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminrequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
_logger.LogDebug("Admin[{0}] {1}", isAdminrequest, message);
}
}
public WireMockService(ILogger logger, IFluentMockServerSettings settings)

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Version>1.0.3.19</Version>
<Version>1.0.4.0</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

View File

@@ -9,7 +9,6 @@ namespace WireMock.Http
/// </summary>
public static class PortUtil
{
private static readonly IPEndPoint DefaultLoopbackEndpoint = new IPEndPoint(IPAddress.Loopback, port: 0);
private static readonly Regex UrlDetailsRegex = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>\d+)?/", RegexOptions.Compiled);
/// <summary>
@@ -18,10 +17,17 @@ namespace WireMock.Http
/// <remarks>see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.</remarks>
public static int FindFreeTcpPort()
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
TcpListener tcpListener = null;
try
{
socket.Bind(DefaultLoopbackEndpoint);
return ((IPEndPoint)socket.LocalEndPoint).Port;
tcpListener = new TcpListener(IPAddress.Loopback, 0);
tcpListener.Start();
return ((IPEndPoint)tcpListener.LocalEndpoint).Port;
}
finally
{
tcpListener?.Stop();
}
}

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
@@ -43,5 +44,13 @@ namespace WireMock.Logging
[PublicAPI]
[StringFormatMethod("formatString")]
void Error([NotNull] string formatString, [NotNull] params object[] args);
/// <summary>
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).
/// </summary>
/// <param name="logEntryModel">The Request Log Model.</param>
/// <param name="isAdminrequest">Defines if this request is an admin request.</param>
[PublicAPI]
void DebugRequestResponse([NotNull] LogEntryModel logEntryModel, bool isAdminrequest);
}
}

View File

@@ -1,4 +1,6 @@
using System;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
@@ -8,6 +10,14 @@ namespace WireMock.Logging
/// <seealso cref="IWireMockLogger" />
public class WireMockConsoleLogger : IWireMockLogger
{
/// <summary>
/// Initializes a new instance of the <see cref="WireMockConsoleLogger"/> class.
/// </summary>
public WireMockConsoleLogger()
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
}
/// <see cref="IWireMockLogger.Debug"/>
public void Debug(string formatString, params object[] args)
{
@@ -32,9 +42,16 @@ namespace WireMock.Logging
Console.WriteLine(Format("Error", formatString, args));
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
Console.WriteLine(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
}
private static string Format(string level, string formatString, params object[] args)
{
string message = string.Format(formatString, args);
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
return $"{DateTime.UtcNow} [{level}] : {message}";
}

View File

@@ -1,4 +1,6 @@
namespace WireMock.Logging
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
/// <summary>
/// WireMockNullLogger which does not log.
@@ -25,5 +27,10 @@
public void Error(string formatString, params object[] args)
{
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
}
}
}

View File

@@ -7,6 +7,7 @@ using WireMock.Matchers;
using WireMock.Util;
using Newtonsoft.Json;
using WireMock.Http;
using WireMock.Serialization;
#if !NETSTANDARD
using Microsoft.Owin;
#else
@@ -153,6 +154,8 @@ namespace WireMock.Owin
private void LogRequest(LogEntry entry, bool addRequest)
{
_options.Logger.DebugRequestResponse(LogEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__admin/"));
if (addRequest)
{
_options.LogEntries.Add(entry);

View File

@@ -0,0 +1,70 @@
using System.Linq;
using WireMock.Admin.Mappings;
using WireMock.Admin.Requests;
using WireMock.Logging;
namespace WireMock.Serialization
{
internal static class LogEntryMapper
{
public static LogEntryModel Map(LogEntry logEntry)
{
return new LogEntryModel
{
Guid = logEntry.Guid,
Request = new LogRequestModel
{
DateTime = logEntry.RequestMessage.DateTime,
ClientIP = logEntry.RequestMessage.ClientIP,
Path = logEntry.RequestMessage.Path,
AbsoluteUrl = logEntry.RequestMessage.Url,
Query = logEntry.RequestMessage.Query,
Method = logEntry.RequestMessage.Method,
Body = logEntry.RequestMessage.Body,
BodyAsJson = logEntry.RequestMessage.BodyAsJson,
BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
Headers = logEntry.RequestMessage.Headers,
Cookies = logEntry.RequestMessage.Cookies,
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
WebName = logEntry.RequestMessage.BodyEncoding.WebName
} : null
},
Response = new LogResponseModel
{
StatusCode = logEntry.ResponseMessage.StatusCode,
BodyDestination = logEntry.ResponseMessage.BodyDestination,
Body = logEntry.ResponseMessage.Body,
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
Headers = logEntry.ResponseMessage.Headers,
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
WebName = logEntry.ResponseMessage.BodyEncoding.WebName
} : null
},
MappingGuid = logEntry.MappingGuid,
MappingTitle = logEntry.MappingTitle,
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
{
TotalScore = logEntry.RequestMatchResult.TotalScore,
TotalNumber = logEntry.RequestMatchResult.TotalNumber,
IsPerfectMatch = logEntry.RequestMatchResult.IsPerfectMatch,
AverageTotalScore = logEntry.RequestMatchResult.AverageTotalScore,
MatchDetails = logEntry.RequestMatchResult.MatchDetails.Select(x => new
{
Name = x.Key.Name.Replace("RequestMessage", string.Empty),
Score = x.Value
} as object).ToList()
} : null
};
}
}
}

View File

@@ -457,7 +457,7 @@ namespace WireMock.Server
return new ResponseMessage { StatusCode = 404, Body = "Request not found" };
}
var model = ToLogEntryModel(entry);
var model = LogEntryMapper.Map(entry);
return ToJson(model);
}
@@ -478,71 +478,11 @@ namespace WireMock.Server
{
var result = LogEntries
.Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
.Select(ToLogEntryModel);
.Select(LogEntryMapper.Map);
return ToJson(result);
}
private LogEntryModel ToLogEntryModel(LogEntry logEntry)
{
return new LogEntryModel
{
Guid = logEntry.Guid,
Request = new LogRequestModel
{
DateTime = logEntry.RequestMessage.DateTime,
ClientIP = logEntry.RequestMessage.ClientIP,
Path = logEntry.RequestMessage.Path,
AbsoluteUrl = logEntry.RequestMessage.Url,
Query = logEntry.RequestMessage.Query,
Method = logEntry.RequestMessage.Method,
Body = logEntry.RequestMessage.Body,
BodyAsJson = logEntry.RequestMessage.BodyAsJson,
BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
Headers = logEntry.RequestMessage.Headers,
Cookies = logEntry.RequestMessage.Cookies,
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
WebName = logEntry.RequestMessage.BodyEncoding.WebName
} : null
},
Response = new LogResponseModel
{
StatusCode = logEntry.ResponseMessage.StatusCode,
BodyDestination = logEntry.ResponseMessage.BodyDestination,
Body = logEntry.ResponseMessage.Body,
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
Headers = logEntry.ResponseMessage.Headers,
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
WebName = logEntry.ResponseMessage.BodyEncoding.WebName
} : null
},
MappingGuid = logEntry.MappingGuid,
MappingTitle = logEntry.MappingTitle,
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
{
TotalScore = logEntry.RequestMatchResult.TotalScore,
TotalNumber = logEntry.RequestMatchResult.TotalNumber,
IsPerfectMatch = logEntry.RequestMatchResult.IsPerfectMatch,
AverageTotalScore = logEntry.RequestMatchResult.AverageTotalScore,
MatchDetails = logEntry.RequestMatchResult.MatchDetails.Select(x => new
{
Name = x.Key.Name.Replace("RequestMessage", string.Empty),
Score = x.Value
} as object).ToList()
} : null
};
}
private ResponseMessage RequestsDelete(RequestMessage requestMessage)
{
ResetLogEntries();
@@ -568,7 +508,7 @@ namespace WireMock.Server
}
}
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(ToLogEntryModel);
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(LogEntryMapper.Map);
return ToJson(result);
}

View File

@@ -161,6 +161,7 @@ namespace WireMock.Server
settings.Logger = settings.Logger ?? new WireMockConsoleLogger();
_logger = settings.Logger;
_logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
_logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
if (settings.Urls != null)

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
<AssemblyTitle>WireMock.Net</AssemblyTitle>
<Version>1.0.3.19</Version>
<Version>1.0.4.0</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>