Summary

Class:WireMock.Server.FluentMockServer
Assembly:WireMock.Net
File(s):C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.Admin.cs
C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.cs
C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.LogEntries.cs
Covered lines:399
Uncovered lines:333
Coverable lines:732
Total lines:1311
Line coverage:54.5%
Branch coverage:58%

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
InitAdmin()0010
SaveStaticMappings(...)0011
ReadStaticMappings(...)000.811
WatchStaticMappings(...)000.250.75
ReadStaticMappingAndAddOrUpdate(...)0011
InitProxyAndRecord(...)0011
ToMapping(...)0000
SettingsGet(...)0010.5
SettingsUpdate(...)000.5710.5
MappingGet(...)0000
MappingPut(...)0000
MappingDelete(...)0000
MappingsSave(...)0000
SaveMappingToFile(...)000.80.667
SanitizeFileName(...)0000
MappingsGet(...)0000
MappingsPost(...)000.4670
DeserializeAndAddOrUpdateMapping(...)000.8210.8
MappingsDelete(...)0000
RequestGet(...)0000
RequestDelete(...)0000
RequestsGet(...)0011
RequestsDelete(...)0000
RequestsFind(...)0011
ScenariosGet(...)0000
ScenariosReset(...)0000
InitRequestBuilder(...)000.4240.404
InitResponseBuilder(...)000.5740.618
ToJson(...)0010.5
ToEncoding(...)0011
DeserializeObject(...)0010.5
.ctor(...)0010
ProxyAndRecordAsync()0000
Dispose()0000
Dispose(...)0000
Start(...)0010
Start(...)0010
Start(...)0010
StartWithAdminInterface(...)0010
StartWithAdminInterface(...)0000
StartWithAdminInterfaceAndReadStaticMappings(...)0000
Stop()0010.75
AddCatchAllMapping()0000
Reset()0000
ResetMappings()0011
DeleteMapping(...)0000
DeleteMapping(...)0000
AddGlobalProcessingDelay(...)0010
AllowPartialMapping(...)0000
SetBasicAuthentication(...)0010
RemoveBasicAuthentication()0010
SetMaxRequestLogCount(...)0010
SetRequestLogExpirationDuration(...)0000
ResetScenarios()0000
Given(...)0010
RegisterMapping(...)0011
.ctor(...)000.750.659
add_LogEntriesChanged(...)0010
remove_LogEntriesChanged(...)0000
FindLogEntries(...)0011
ResetLogEntries()0010
DeleteLogEntry(...)0000

File(s)

C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.Admin.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.IO;
 4using System.Linq;
 5using System.Net.Http;
 6using System.Text;
 7using System.Threading.Tasks;
 8using JetBrains.Annotations;
 9using Newtonsoft.Json;
 10using Newtonsoft.Json.Linq;
 11using WireMock.Admin.Mappings;
 12using WireMock.Admin.Scenarios;
 13using WireMock.Admin.Settings;
 14using WireMock.Http;
 15using WireMock.Logging;
 16using WireMock.Matchers;
 17using WireMock.Matchers.Request;
 18using WireMock.RequestBuilders;
 19using WireMock.ResponseBuilders;
 20using WireMock.ResponseProviders;
 21using WireMock.Serialization;
 22using WireMock.Settings;
 23using WireMock.Util;
 24using WireMock.Validation;
 25
 26namespace WireMock.Server
 27{
 28    /// <summary>
 29    /// The fluent mock server.
 30    /// </summary>
 31    public partial class FluentMockServer
 32    {
 33        private const int EnhancedFileSystemWatcherTimeoutMs = 1000;
 34        private const int AdminPriority = int.MinValue;
 35        private const int ProxyPriority = 1000;
 36        private const string ContentTypeJson = "application/json";
 37        private const string AdminMappings = "/__admin/mappings";
 38        private const string AdminRequests = "/__admin/requests";
 39        private const string AdminSettings = "/__admin/settings";
 40        private const string AdminScenarios = "/__admin/scenarios";
 41
 5542        private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^
 5543        private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^
 44
 5545        private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
 5546        {
 5547            Formatting = Formatting.Indented,
 5548            NullValueHandling = NullValueHandling.Ignore
 5549        };
 50
 5551        private readonly JsonSerializerSettings _settingsIncludeNullValues = new JsonSerializerSettings
 5552        {
 5553            Formatting = Formatting.Indented,
 5554            NullValueHandling = NullValueHandling.Include
 5555        };
 56
 57        #region InitAdmin
 58        private void InitAdmin()
 1159        {
 60            // __admin/settings
 1161            Given(Request.Create().WithPath(AdminSettings).UsingGet()).AtPriority(AdminPriority).RespondWith(new Dynamic
 1162            Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.Co
 63
 64            // __admin/mappings
 1165            Given(Request.Create().WithPath(AdminMappings).UsingGet()).AtPriority(AdminPriority).RespondWith(new Dynamic
 1166            Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, Cont
 1167            Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(AdminPriority).RespondWith(new Dyna
 68
 69            // __admin/mappings/reset
 1170            Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith
 71
 72            // __admin/mappings/{guid}
 1173            Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).Respond
 1174            Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.Co
 1175            Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).AtPriority(AdminPriority).Resp
 76
 77            // __admin/mappings/save
 1178            Given(Request.Create().WithPath(AdminMappings + "/save").UsingPost()).AtPriority(AdminPriority).RespondWith(
 79
 80            // __admin/requests
 1181            Given(Request.Create().WithPath(AdminRequests).UsingGet()).AtPriority(AdminPriority).RespondWith(new Dynamic
 1182            Given(Request.Create().WithPath(AdminRequests).UsingDelete()).AtPriority(AdminPriority).RespondWith(new Dyna
 83
 84            // __admin/requests/reset
 1185            Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWith
 86
 87            // __admin/request/{guid}
 1188            Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).AtPriority(AdminPriority).Respond
 1189            Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).AtPriority(AdminPriority).Resp
 90
 91            // __admin/requests/find
 1192            Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).AtPriority(AdminPriority).RespondWith(
 93
 94            // __admin/scenarios
 1195            Given(Request.Create().WithPath(AdminScenarios).UsingGet()).AtPriority(AdminPriority).RespondWith(new Dynami
 1196            Given(Request.Create().WithPath(AdminScenarios).UsingDelete()).AtPriority(AdminPriority).RespondWith(new Dyn
 97
 98            // __admin/scenarios/reset
 1199            Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).AtPriority(AdminPriority).RespondWit
 11100        }
 101        #endregion
 102
 103        #region StaticMappings
 104        /// <summary>
 105        /// Saves the static mappings.
 106        /// </summary>
 107        /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
 108        [PublicAPI]
 109        public void SaveStaticMappings([CanBeNull] string folder = null)
 1110        {
 6111            foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
 1112            {
 1113                SaveMappingToFile(mapping, folder);
 1114            }
 1115        }
 116
 117        /// <summary>
 118        /// Reads the static mappings from a folder.
 119        /// </summary>
 120        /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
 121        [PublicAPI]
 122        public void ReadStaticMappings([CanBeNull] string folder = null)
 4123        {
 4124            if (folder == null)
 1125            {
 1126                folder = _fileSystemHandler.GetMappingFolder();
 1127            }
 128
 4129            if (!_fileSystemHandler.FolderExists(folder))
 1130            {
 1131                _logger.Info("The Static Mapping folder '{0}' does not exist, reading Static MappingFiles will be skippe
 1132                return;
 133            }
 134
 27135            foreach (string filename in _fileSystemHandler.EnumerateFiles(folder).OrderBy(f => f))
 6136            {
 6137                _logger.Info("Reading Static MappingFile : '{0}'", filename);
 138
 139                try
 6140                {
 6141                    ReadStaticMappingAndAddOrUpdate(filename);
 6142                }
 0143                catch
 0144                {
 0145                    _logger.Error("Static MappingFile : '{0}' could not be read. This file will be skipped.", filename);
 0146                }
 6147            }
 4148        }
 149
 150        /// <summary>
 151        /// Watches the static mappings for changes.
 152        /// </summary>
 153        /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
 154        [PublicAPI]
 155        public void WatchStaticMappings([CanBeNull] string folder = null)
 1156        {
 1157            if (folder == null)
 1158            {
 1159                folder = _fileSystemHandler.GetMappingFolder();
 1160            }
 161
 1162            if (!_fileSystemHandler.FolderExists(folder))
 1163            {
 1164                return;
 165            }
 166
 0167            _logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
 168
 0169            var watcher = new EnhancedFileSystemWatcher(folder, "*.json", EnhancedFileSystemWatcherTimeoutMs);
 0170            watcher.Created += (sender, args) =>
 0171            {
 0172                _logger.Info("New MappingFile created : '{0}'", args.FullPath);
 0173                ReadStaticMappingAndAddOrUpdate(args.FullPath);
 0174            };
 0175            watcher.Changed += (sender, args) =>
 0176            {
 0177                _logger.Info("New MappingFile updated : '{0}'", args.FullPath);
 0178                ReadStaticMappingAndAddOrUpdate(args.FullPath);
 0179            };
 0180            watcher.Deleted += (sender, args) =>
 0181            {
 0182                _logger.Info("New MappingFile deleted : '{0}'", args.FullPath);
 0183                string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);
 0184
 0185                if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
 0186                {
 0187                    DeleteMapping(guidFromFilename);
 0188                }
 0189                else
 0190                {
 0191                    DeleteMapping(args.FullPath);
 0192                }
 0193            };
 194
 0195            watcher.EnableRaisingEvents = true;
 1196        }
 197
 198        /// <summary>
 199        /// Reads a static mapping file and adds or updates the mapping.
 200        /// </summary>
 201        /// <param name="path">The path.</param>
 202        [PublicAPI]
 203        public void ReadStaticMappingAndAddOrUpdate([NotNull] string path)
 10204        {
 10205            Check.NotNull(path, nameof(path));
 206
 10207            string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
 208
 10209            MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(_fileSystemHandler.ReadMappingFile(p
 10210            if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
 6211            {
 6212                DeserializeAndAddOrUpdateMapping(mappingModel, guidFromFilename, path);
 6213            }
 214            else
 4215            {
 4216                DeserializeAndAddOrUpdateMapping(mappingModel, null, path);
 4217            }
 10218        }
 219        #endregion
 220
 221        #region Proxy and Record
 222        private HttpClient _httpClientForProxy;
 223
 224        private void InitProxyAndRecord(IFluentMockServerSettings settings)
 2225        {
 2226            _httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ProxyAndRecordSettings.ClientX509Certificat
 227
 2228            var respondProvider = Given(Request.Create().WithPath("/*").UsingAnyMethod());
 2229            if (settings.StartAdminInterface == true)
 1230            {
 1231                respondProvider.AtPriority(ProxyPriority);
 1232            }
 233
 2234            respondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings.ProxyAndRecordSetti
 2235        }
 236
 237        private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings s
 0238        {
 0239            var requestUri = new Uri(requestMessage.Url);
 0240            var proxyUri = new Uri(settings.Url);
 0241            var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
 242
 0243            var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequ
 244
 0245            if (settings.SaveMapping)
 0246            {
 0247                var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { }
 0248                _options.Mappings.TryAdd(mapping.Guid, mapping);
 249
 0250                if (settings.SaveMappingToFile)
 0251                {
 0252                    SaveMappingToFile(mapping);
 0253                }
 0254            }
 255
 0256            return responseMessage;
 0257        }
 258
 259        private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage, string[] blacklistedHe
 0260        {
 0261            var request = Request.Create();
 0262            request.WithPath(requestMessage.Path);
 0263            request.UsingMethod(requestMessage.Method);
 264
 0265            requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
 0266            requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
 267
 0268            var allBlackListedHeaders = new List<string>(blacklistedHeaders) { "Cookie" };
 0269            requestMessage.Headers.Loop((key, value) =>
 0270            {
 0271                if (!allBlackListedHeaders.Any(b => string.Equals(key, b, StringComparison.OrdinalIgnoreCase)))
 0272                {
 0273                    request.WithHeader(key, value.ToArray());
 0274                }
 0275            });
 276
 0277            if (requestMessage.BodyAsJson != null)
 0278            {
 0279                request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));
 0280            }
 0281            else if (requestMessage.Body != null)
 0282            {
 0283                request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
 0284            }
 285
 0286            var response = Response.Create(responseMessage);
 287
 0288            return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);
 0289        }
 290        #endregion
 291
 292        #region Settings
 293        private ResponseMessage SettingsGet(RequestMessage requestMessage)
 1294        {
 1295            var model = new SettingsModel
 1296            {
 1297                AllowPartialMapping = _options.AllowPartialMapping,
 1298                MaxRequestLogCount = _options.MaxRequestLogCount,
 1299                RequestLogExpirationDuration = _options.RequestLogExpirationDuration,
 1300                GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds
 1301            };
 302
 1303            return ToJson(model);
 1304        }
 305
 306        private ResponseMessage SettingsUpdate(RequestMessage requestMessage)
 2307        {
 2308            var settings = DeserializeObject<SettingsModel>(requestMessage);
 2309            _options.MaxRequestLogCount = settings.MaxRequestLogCount;
 2310            _options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;
 311
 2312            if (settings.AllowPartialMapping != null)
 0313            {
 0314                _options.AllowPartialMapping = settings.AllowPartialMapping.Value;
 0315            }
 316
 2317            if (settings.GlobalProcessingDelay != null)
 0318            {
 0319                _options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
 0320            }
 321
 2322            return ResponseMessageBuilder.Create("Settings updated");
 2323        }
 324        #endregion Settings
 325
 326        #region Mapping/{guid}
 327        private ResponseMessage MappingGet(RequestMessage requestMessage)
 0328        {
 0329            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
 0330            var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
 331
 0332            if (mapping == null)
 0333            {
 0334                _logger.Warn("HttpStatusCode set to 404 : Mapping not found");
 0335                return ResponseMessageBuilder.Create("Mapping not found", 404);
 336            }
 337
 0338            var model = MappingConverter.ToMappingModel(mapping);
 339
 0340            return ToJson(model);
 0341        }
 342
 343        private ResponseMessage MappingPut(RequestMessage requestMessage)
 0344        {
 0345            Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
 346
 0347            var mappingModel = DeserializeObject<MappingModel>(requestMessage);
 0348            Guid? guidFromPut = DeserializeAndAddOrUpdateMapping(mappingModel, guid);
 349
 0350            return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);
 0351        }
 352
 353        private ResponseMessage MappingDelete(RequestMessage requestMessage)
 0354        {
 0355            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
 356
 0357            if (DeleteMapping(guid))
 0358            {
 0359                return ResponseMessageBuilder.Create("Mapping removed", 200, guid);
 360            }
 361
 0362            return ResponseMessageBuilder.Create("Mapping not found", 404);
 0363        }
 364        #endregion Mapping/{guid}
 365
 366        #region Mappings
 367        private ResponseMessage MappingsSave(RequestMessage requestMessage)
 0368        {
 0369            SaveStaticMappings();
 370
 0371            return ResponseMessageBuilder.Create("Mappings saved to disk");
 0372        }
 373
 374        private void SaveMappingToFile(Mapping mapping, string folder = null)
 1375        {
 1376            if (folder == null)
 1377            {
 1378                folder = _fileSystemHandler.GetMappingFolder();
 1379            }
 380
 1381            if (!_fileSystemHandler.FolderExists(folder))
 0382            {
 0383                _fileSystemHandler.CreateFolder(folder);
 0384            }
 385
 1386            var model = MappingConverter.ToMappingModel(mapping);
 1387            string filename = (!string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToS
 388
 1389            string path = Path.Combine(folder, filename);
 390
 1391            _logger.Info("Saving Mapping file {0}", filename);
 392
 1393            _fileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, _settings));
 1394        }
 395
 396        private static string SanitizeFileName(string name, char replaceChar = '_')
 0397        {
 0398            return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));
 0399        }
 400
 401        private ResponseMessage MappingsGet(RequestMessage requestMessage)
 0402        {
 0403            var result = new List<MappingModel>();
 0404            foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
 0405            {
 0406                var model = MappingConverter.ToMappingModel(mapping);
 0407                result.Add(model);
 0408            }
 409
 0410            return ToJson(result);
 0411        }
 412
 413        private ResponseMessage MappingsPost(RequestMessage requestMessage)
 1414        {
 415            Guid? guid;
 416            try
 1417            {
 1418                var mappingModel = DeserializeObject<MappingModel>(requestMessage);
 1419                guid = DeserializeAndAddOrUpdateMapping(mappingModel);
 1420            }
 0421            catch (ArgumentException a)
 0422            {
 0423                _logger.Error("HttpStatusCode set to 400 {0}", a);
 0424                return ResponseMessageBuilder.Create(a.Message, 400);
 425            }
 0426            catch (Exception e)
 0427            {
 0428                _logger.Error("HttpStatusCode set to 500 {0}", e);
 0429                return ResponseMessageBuilder.Create(e.ToString(), 500);
 430            }
 431
 1432            return ResponseMessageBuilder.Create("Mapping added", 201, guid);
 1433        }
 434
 435        private Guid? DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
 11436        {
 11437            Check.NotNull(mappingModel, nameof(mappingModel));
 11438            Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
 11439            Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
 440
 11441            var requestBuilder = InitRequestBuilder(mappingModel.Request, true);
 11442            if (requestBuilder == null)
 0443            {
 0444                return null;
 445            }
 446
 11447            var responseBuilder = InitResponseBuilder(mappingModel.Response);
 448
 11449            var respondProvider = Given(requestBuilder);
 450
 11451            if (guid != null)
 6452            {
 6453                respondProvider = respondProvider.WithGuid(guid.Value);
 6454            }
 5455            else if (mappingModel.Guid != null && mappingModel.Guid != Guid.Empty)
 3456            {
 3457                respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
 3458            }
 459
 11460            if (path != null)
 10461            {
 10462                respondProvider = respondProvider.WithPath(path);
 10463            }
 464
 11465            if (!string.IsNullOrEmpty(mappingModel.Title))
 4466            {
 4467                respondProvider = respondProvider.WithTitle(mappingModel.Title);
 4468            }
 469
 11470            if (mappingModel.Priority != null)
 10471            {
 10472                respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
 10473            }
 474
 11475            if (mappingModel.Scenario != null)
 0476            {
 0477                respondProvider = respondProvider.InScenario(mappingModel.Scenario);
 0478                respondProvider = respondProvider.WhenStateIs(mappingModel.WhenStateIs);
 0479                respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo);
 0480            }
 481
 11482            respondProvider.RespondWith(responseBuilder);
 483
 11484            return respondProvider.Guid;
 11485        }
 486
 487        private ResponseMessage MappingsDelete(RequestMessage requestMessage)
 0488        {
 0489            ResetMappings();
 490
 0491            ResetScenarios();
 492
 0493            return ResponseMessageBuilder.Create("Mappings deleted");
 0494        }
 495        #endregion Mappings
 496
 497        #region Request/{guid}
 498        private ResponseMessage RequestGet(RequestMessage requestMessage)
 0499        {
 0500            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));
 0501            var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid)
 502
 0503            if (entry == null)
 0504            {
 0505                _logger.Warn("HttpStatusCode set to 404 : Request not found");
 0506                return ResponseMessageBuilder.Create("Request not found", 404);
 507            }
 508
 0509            var model = LogEntryMapper.Map(entry);
 510
 0511            return ToJson(model);
 0512        }
 513
 514        private ResponseMessage RequestDelete(RequestMessage requestMessage)
 0515        {
 0516            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));
 517
 0518            if (DeleteLogEntry(guid))
 0519            {
 0520                return ResponseMessageBuilder.Create("Request removed");
 521            }
 522
 0523            return ResponseMessageBuilder.Create("Request not found", 404);
 0524        }
 525        #endregion Request/{guid}
 526
 527        #region Requests
 528        private ResponseMessage RequestsGet(RequestMessage requestMessage)
 3529        {
 3530            var result = LogEntries
 6531                .Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
 3532                .Select(LogEntryMapper.Map);
 533
 3534            return ToJson(result);
 3535        }
 536
 537        private ResponseMessage RequestsDelete(RequestMessage requestMessage)
 0538        {
 0539            ResetLogEntries();
 540
 0541            return ResponseMessageBuilder.Create("Requests deleted");
 0542        }
 543        #endregion Requests
 544
 545        #region Requests/find
 546        private ResponseMessage RequestsFind(RequestMessage requestMessage)
 1547        {
 1548            var requestModel = DeserializeObject<RequestModel>(requestMessage);
 549
 1550            var request = (Request)InitRequestBuilder(requestModel, false);
 551
 1552            var dict = new Dictionary<LogEntry, RequestMatchResult>();
 6553            foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))
 1554            {
 1555                var requestMatchResult = new RequestMatchResult();
 1556                if (request.GetMatchingScore(logEntry.RequestMessage, requestMatchResult) > MatchScores.AlmostPerfect)
 1557                {
 1558                    dict.Add(logEntry, requestMatchResult);
 1559                }
 1560            }
 561
 3562            var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(LogEntryMapper.Map);
 563
 1564            return ToJson(result);
 1565        }
 566        #endregion Requests/find
 567
 568        #region Scenarios
 569        private ResponseMessage ScenariosGet(RequestMessage requestMessage)
 0570        {
 0571            var scenariosStates = Scenarios.Values.Select(s => new ScenarioStateModel
 0572            {
 0573                Name = s.Name,
 0574                NextState = s.NextState,
 0575                Started = s.Started,
 0576                Finished = s.Finished
 0577            });
 578
 0579            return ToJson(scenariosStates, true);
 0580        }
 581
 582        private ResponseMessage ScenariosReset(RequestMessage requestMessage)
 0583        {
 0584            ResetScenarios();
 585
 0586            return ResponseMessageBuilder.Create("Scenarios reset");
 0587        }
 588        #endregion
 589
 590        private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
 12591        {
 12592            IRequestBuilder requestBuilder = Request.Create();
 593
 12594            if (requestModel.ClientIP != null)
 0595            {
 0596                if (requestModel.ClientIP is string clientIP)
 0597                {
 0598                    requestBuilder = requestBuilder.WithClientIP(clientIP);
 0599                }
 600                else
 0601                {
 0602                    var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);
 0603                    if (clientIPModel?.Matchers != null)
 0604                    {
 0605                        requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MatcherMapper.Map).Cast<I
 0606                    }
 0607                }
 0608            }
 609
 12610            bool pathOrUrlmatchersValid = false;
 12611            if (requestModel.Path != null)
 11612            {
 11613                if (requestModel.Path is string path)
 1614                {
 1615                    requestBuilder = requestBuilder.WithPath(path);
 1616                    pathOrUrlmatchersValid = true;
 1617                }
 618                else
 10619                {
 10620                    var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
 10621                    if (pathModel?.Matchers != null)
 10622                    {
 10623                        requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast<IStri
 10624                        pathOrUrlmatchersValid = true;
 10625                    }
 10626                }
 11627            }
 1628            else if (requestModel.Url != null)
 0629            {
 0630                if (requestModel.Url is string url)
 0631                {
 0632                    requestBuilder = requestBuilder.WithUrl(url);
 0633                    pathOrUrlmatchersValid = true;
 0634                }
 635                else
 0636                {
 0637                    var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
 0638                    if (urlModel?.Matchers != null)
 0639                    {
 0640                        requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast<IString
 0641                        pathOrUrlmatchersValid = true;
 0642                    }
 0643                }
 0644            }
 645
 12646            if (pathOrUrlRequired && !pathOrUrlmatchersValid)
 0647            {
 0648                _logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added.");
 0649                return null;
 650            }
 651
 12652            if (requestModel.Methods != null)
 11653            {
 11654                requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);
 11655            }
 656
 12657            if (requestModel.Headers != null)
 0658            {
 0659                foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
 0660                {
 0661                    requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MatcherMapp
 0662                }
 0663            }
 664
 12665            if (requestModel.Cookies != null)
 0666            {
 0667                foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
 0668                {
 0669                    requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MatcherMapp
 0670                }
 0671            }
 672
 12673            if (requestModel.Params != null)
 0674            {
 0675                foreach (var paramModel in requestModel.Params.Where(c => c.Matchers != null))
 0676                {
 0677                    requestBuilder = requestBuilder.WithParam(paramModel.Name, paramModel.Matchers.Select(MatcherMapper.
 0678                }
 0679            }
 680
 12681            if (requestModel.Body?.Matcher != null)
 3682            {
 3683                var bodyMatcher = MatcherMapper.Map(requestModel.Body.Matcher);
 3684                requestBuilder = requestBuilder.WithBody(bodyMatcher);
 3685            }
 686
 12687            return requestBuilder;
 12688        }
 689
 690        private IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
 11691        {
 11692            IResponseBuilder responseBuilder = Response.Create();
 693
 11694            if (responseModel.Delay > 0)
 0695            {
 0696                responseBuilder = responseBuilder.WithDelay(responseModel.Delay.Value);
 0697            }
 698
 11699            if (!string.IsNullOrEmpty(responseModel.ProxyUrl))
 0700            {
 0701                if (string.IsNullOrEmpty(responseModel.X509Certificate2ThumbprintOrSubjectName))
 0702                {
 0703                    return responseBuilder.WithProxy(responseModel.ProxyUrl);
 704                }
 705
 0706                return responseBuilder.WithProxy(responseModel.ProxyUrl, responseModel.X509Certificate2ThumbprintOrSubje
 707            }
 708
 11709            if (responseModel.StatusCode.HasValue)
 10710            {
 10711                responseBuilder = responseBuilder.WithStatusCode(responseModel.StatusCode.Value);
 10712            }
 713
 11714            if (responseModel.Headers != null)
 9715            {
 189716                foreach (var entry in responseModel.Headers)
 81717                {
 81718                    responseBuilder = entry.Value is string value ?
 81719                        responseBuilder.WithHeader(entry.Key, value) :
 81720                        responseBuilder.WithHeader(entry.Key, JsonUtils.ParseJTokenToObject<string[]>(entry.Value));
 81721                }
 9722            }
 2723            else if (responseModel.HeadersRaw != null)
 0724            {
 0725                foreach (string headerLine in responseModel.HeadersRaw.Split(new[] { "\n", "\r\n" }, StringSplitOptions.
 0726                {
 0727                    int indexColon = headerLine.IndexOf(":", StringComparison.Ordinal);
 0728                    string key = headerLine.Substring(0, indexColon).TrimStart(' ', '\t');
 0729                    string value = headerLine.Substring(indexColon + 1).TrimStart(' ', '\t');
 0730                    responseBuilder = responseBuilder.WithHeader(key, value);
 0731                }
 0732            }
 733
 11734            if (responseModel.BodyAsBytes != null)
 0735            {
 0736                responseBuilder = responseBuilder.WithBody(responseModel.BodyAsBytes, responseModel.BodyDestination, ToE
 0737            }
 11738            else if (responseModel.Body != null)
 7739            {
 7740                responseBuilder = responseBuilder.WithBody(responseModel.Body, responseModel.BodyDestination, ToEncoding
 7741            }
 4742            else if (responseModel.BodyAsJson != null)
 1743            {
 1744                responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.Body
 1745            }
 3746            else if (responseModel.BodyFromBase64 != null)
 0747            {
 0748                responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseMo
 0749            }
 3750            else if (responseModel.BodyAsFile != null)
 3751            {
 3752                responseBuilder = responseBuilder.WithBodyFromFile(responseModel.BodyAsFile);
 3753            }
 754
 11755            if (responseModel.UseTransformer)
 0756            {
 0757                responseBuilder = responseBuilder.WithTransformer();
 0758            }
 759
 11760            return responseBuilder;
 11761        }
 762
 763        private ResponseMessage ToJson<T>(T result, bool keepNullValues = false)
 5764        {
 5765            return new ResponseMessage
 5766            {
 5767                Body = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings),
 5768                StatusCode = 200,
 5769                Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMoc
 5770            };
 5771        }
 772
 773        private Encoding ToEncoding(EncodingModel encodingModel)
 8774        {
 8775            return encodingModel != null ? Encoding.GetEncoding(encodingModel.CodePage) : null;
 8776        }
 777
 778        private T DeserializeObject<T>(RequestMessage requestMessage)
 4779        {
 4780            return requestMessage.Body != null ?
 4781                JsonConvert.DeserializeObject<T>(requestMessage.Body) :
 4782                ((JObject)requestMessage.BodyAsJson).ToObject<T>();
 4783        }
 784    }
 785}

C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.cs

#LineLine coverage
 1using JetBrains.Annotations;
 2using System;
 3using System.Collections.Concurrent;
 4using System.Collections.Generic;
 5using System.Linq;
 6using System.Text;
 7using System.Threading;
 8using Newtonsoft.Json;
 9using WireMock.Handlers;
 10using WireMock.Logging;
 11using WireMock.Matchers;
 12using WireMock.Matchers.Request;
 13using WireMock.Owin;
 14using WireMock.RequestBuilders;
 15using WireMock.ResponseProviders;
 16using WireMock.Settings;
 17using WireMock.Util;
 18using WireMock.Validation;
 19
 20namespace WireMock.Server
 21{
 22    /// <summary>
 23    /// The fluent mock server.
 24    /// </summary>
 25    public partial class FluentMockServer : IDisposable
 26    {
 27        private readonly IWireMockLogger _logger;
 28        private readonly IFileSystemHandler _fileSystemHandler;
 29
 30        private const int ServerStartDelay = 100;
 31        private readonly IOwinSelfHost _httpServer;
 5532        private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
 33
 34        /// <summary>
 35        /// Gets a value indicating whether this server is started.
 36        /// </summary>
 37        [PublicAPI]
 038        public bool IsStarted => _httpServer != null && _httpServer.IsStarted;
 39
 40        /// <summary>
 41        /// Gets the ports.
 42        /// </summary>
 43        [PublicAPI]
 4044        public List<int> Ports { get; }
 45
 46        /// <summary>
 47        /// Gets the urls.
 48        /// </summary>
 49        [PublicAPI]
 7250        public string[] Urls { get; }
 51
 52        /// <summary>
 53        /// Gets the mappings.
 54        /// </summary>
 55        [PublicAPI]
 1856        public IEnumerable<Mapping> Mappings => _options.Mappings.Values.ToArray();
 57
 58        /// <summary>
 59        /// Gets the scenarios.
 60        /// </summary>
 61        [PublicAPI]
 1362        public ConcurrentDictionary<string, ScenarioState> Scenarios => new ConcurrentDictionary<string, ScenarioState>(
 63
 64        #region IDisposable Members
 65        /// <summary>
 66        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 67        /// </summary>
 68        public void Dispose()
 069        {
 070            Dispose(true);
 071            GC.SuppressFinalize(this);
 072        }
 73
 74        /// <summary>
 75        /// Releases unmanaged and - optionally - managed resources.
 76        /// </summary>
 77        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release
 78        protected virtual void Dispose(bool disposing)
 079        {
 080            if (_httpServer != null)
 081            {
 082                _httpServer.StopAsync();
 083            }
 084        }
 85        #endregion
 86
 87        #region Start/Stop
 88        /// <summary>
 89        /// Starts the specified settings.
 90        /// </summary>
 91        /// <param name="settings">The FluentMockServerSettings.</param>
 92        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 93        [PublicAPI]
 94        public static FluentMockServer Start(IFluentMockServerSettings settings)
 1495        {
 1496            Check.NotNull(settings, nameof(settings));
 97
 1498            return new FluentMockServer(settings);
 1499        }
 100
 101        /// <summary>
 102        /// Start this FluentMockServer.
 103        /// </summary>
 104        /// <param name="port">The port.</param>
 105        /// <param name="ssl">The SSL support.</param>
 106        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 107        [PublicAPI]
 108        public static FluentMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
 36109        {
 36110            return new FluentMockServer(new FluentMockServerSettings
 36111            {
 36112                Port = port,
 36113                UseSSL = ssl
 36114            });
 36115        }
 116
 117        /// <summary>
 118        /// Start this FluentMockServer.
 119        /// </summary>
 120        /// <param name="urls">The urls to listen on.</param>
 121        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 122        [PublicAPI]
 123        public static FluentMockServer Start(params string[] urls)
 1124        {
 1125            Check.NotNullOrEmpty(urls, nameof(urls));
 126
 1127            return new FluentMockServer(new FluentMockServerSettings
 1128            {
 1129                Urls = urls
 1130            });
 1131        }
 132
 133        /// <summary>
 134        /// Start this FluentMockServer with the admin interface.
 135        /// </summary>
 136        /// <param name="port">The port.</param>
 137        /// <param name="ssl">The SSL support.</param>
 138        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 139        [PublicAPI]
 140        public static FluentMockServer StartWithAdminInterface(int? port = 0, bool ssl = false)
 4141        {
 4142            return new FluentMockServer(new FluentMockServerSettings
 4143            {
 4144                Port = port,
 4145                UseSSL = ssl,
 4146                StartAdminInterface = true
 4147            });
 4148        }
 149
 150        /// <summary>
 151        /// Start this FluentMockServer with the admin interface.
 152        /// </summary>
 153        /// <param name="urls">The urls.</param>
 154        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 155        [PublicAPI]
 156        public static FluentMockServer StartWithAdminInterface(params string[] urls)
 0157        {
 0158            Check.NotNullOrEmpty(urls, nameof(urls));
 159
 0160            return new FluentMockServer(new FluentMockServerSettings
 0161            {
 0162                Urls = urls,
 0163                StartAdminInterface = true
 0164            });
 0165        }
 166
 167        /// <summary>
 168        /// Start this FluentMockServer with the admin interface and read static mappings.
 169        /// </summary>
 170        /// <param name="urls">The urls.</param>
 171        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 172        [PublicAPI]
 173        public static FluentMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
 0174        {
 0175            Check.NotNullOrEmpty(urls, nameof(urls));
 176
 0177            return new FluentMockServer(new FluentMockServerSettings
 0178            {
 0179                Urls = urls,
 0180                StartAdminInterface = true,
 0181                ReadStaticMappings = true
 0182            });
 0183        }
 184
 55185        private FluentMockServer(IFluentMockServerSettings settings)
 55186        {
 55187            settings.Logger = settings.Logger ?? new WireMockConsoleLogger();
 188
 55189            _logger = settings.Logger;
 55190            _fileSystemHandler = settings.FileSystemHandler ?? new LocalFileSystemHandler();
 191
 55192            _logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
 55193            _logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented)
 194
 55195            if (settings.Urls != null)
 1196            {
 1197                Urls = settings.Urls.ToArray();
 1198            }
 199            else
 54200            {
 54201                int port = settings.Port > 0 ? settings.Port.Value : PortUtils.FindFreeTcpPort();
 54202                Urls = new[] { $"{(settings.UseSSL == true ? "https" : "http")}://localhost:{port}" };
 54203            }
 204
 55205            _options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
 55206            _options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
 55207            _options.Logger = _logger;
 208
 209#if USE_ASPNETCORE
 55210            _httpServer = new AspNetCoreSelfHost(_options, Urls);
 211#else
 212            _httpServer = new OwinSelfHost(_options, Urls);
 213#endif
 55214            Ports = _httpServer.Ports;
 215
 55216            _httpServer.StartAsync();
 217
 55218            using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))
 55219            {
 451220                while (!_httpServer.IsStarted)
 396221                {
 222                    // Throw out exception if service start fails
 396223                    if (_httpServer.RunningException != null)
 0224                    {
 0225                        throw new Exception($"Service start failed with error: {_httpServer.RunningException.Message}", 
 226                    }
 227
 228                    // Respect start timeout setting by throwing TimeoutException
 396229                    if (ctsStartTimeout.IsCancellationRequested)
 0230                    {
 0231                        throw new TimeoutException($"Service start timed out after {TimeSpan.FromMilliseconds(settings.S
 232                    }
 233
 396234                    ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelay);
 396235                }
 55236            }
 237
 55238            if (settings.AllowPartialMapping == true)
 0239            {
 0240                AllowPartialMapping();
 0241            }
 242
 55243            if (settings.StartAdminInterface == true)
 11244            {
 11245                if (!string.IsNullOrEmpty(settings.AdminUsername) && !string.IsNullOrEmpty(settings.AdminPassword))
 1246                {
 1247                    SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword);
 1248                }
 249
 11250                InitAdmin();
 11251            }
 252
 55253            if (settings.ReadStaticMappings == true)
 0254            {
 0255                ReadStaticMappings();
 0256            }
 257
 55258            if (settings.WatchStaticMappings == true)
 0259            {
 0260                WatchStaticMappings();
 0261            }
 262
 55263            if (settings.ProxyAndRecordSettings != null)
 2264            {
 2265                InitProxyAndRecord(settings);
 2266            }
 267
 55268            if (settings.MaxRequestLogCount != null)
 0269            {
 0270                SetMaxRequestLogCount(settings.MaxRequestLogCount);
 0271            }
 55272        }
 273
 274        /// <summary>
 275        /// Stop this server.
 276        /// </summary>
 277        [PublicAPI]
 278        public void Stop()
 2279        {
 2280            var result = _httpServer?.StopAsync();
 2281            result?.Wait(); // wait for stop to actually happen
 2282        }
 283        #endregion
 284
 285        /// <summary>
 286        /// Adds the catch all mapping.
 287        /// </summary>
 288        [PublicAPI]
 289        public void AddCatchAllMapping()
 0290        {
 0291            Given(Request.Create().WithPath("/*").UsingAnyMethod())
 0292                .WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
 0293                .AtPriority(1000)
 0294                .RespondWith(new DynamicResponseProvider(request => ResponseMessageBuilder.Create("No matching mapping f
 0295        }
 296
 297        /// <summary>
 298        /// Resets LogEntries and Mappings.
 299        /// </summary>
 300        [PublicAPI]
 301        public void Reset()
 0302        {
 0303            ResetLogEntries();
 304
 0305            ResetMappings();
 0306        }
 307
 308        /// <summary>
 309        /// Resets the Mappings.
 310        /// </summary>
 311        [PublicAPI]
 312        public void ResetMappings()
 10313        {
 66314            foreach (var nonAdmin in _options.Mappings.ToArray().Where(m => !m.Value.IsAdminInterface))
 12315            {
 12316                _options.Mappings.TryRemove(nonAdmin.Key, out _);
 12317            }
 10318        }
 319
 320        /// <summary>
 321        /// Deletes the mapping.
 322        /// </summary>
 323        /// <param name="guid">The unique identifier.</param>
 324        [PublicAPI]
 325        public bool DeleteMapping(Guid guid)
 0326        {
 327            // Check a mapping exists with the same GUID, if so, remove it.
 0328            if (_options.Mappings.ContainsKey(guid))
 0329            {
 0330                return _options.Mappings.TryRemove(guid, out _);
 331            }
 332
 0333            return false;
 0334        }
 335
 336        private bool DeleteMapping(string path)
 0337        {
 338            // Check a mapping exists with the same path, if so, remove it.
 0339            var mapping = _options.Mappings.ToArray().FirstOrDefault(entry => string.Equals(entry.Value.Path, path, Stri
 0340            return DeleteMapping(mapping.Key);
 0341        }
 342
 343        /// <summary>
 344        /// The add request processing delay.
 345        /// </summary>
 346        /// <param name="delay">The delay.</param>
 347        [PublicAPI]
 348        public void AddGlobalProcessingDelay(TimeSpan delay)
 1349        {
 1350            _options.RequestProcessingDelay = delay;
 1351        }
 352
 353        /// <summary>
 354        /// Allows the partial mapping.
 355        /// </summary>
 356        [PublicAPI]
 357        public void AllowPartialMapping(bool allow = true)
 0358        {
 0359            _logger.Info("AllowPartialMapping is set to {0}", allow);
 0360            _options.AllowPartialMapping = allow;
 0361        }
 362
 363        /// <summary>
 364        /// Sets the basic authentication.
 365        /// </summary>
 366        /// <param name="username">The username.</param>
 367        /// <param name="password">The password.</param>
 368        [PublicAPI]
 369        public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
 3370        {
 3371            Check.NotNull(username, nameof(username));
 3372            Check.NotNull(password, nameof(password));
 373
 3374            string authorization = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + p
 3375            _options.AuthorizationMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, "^(?i)BASIC " + authorization
 3376        }
 377
 378        /// <summary>
 379        /// Removes the basic authentication.
 380        /// </summary>
 381        [PublicAPI]
 382        public void RemoveBasicAuthentication()
 1383        {
 1384            _options.AuthorizationMatcher = null;
 1385        }
 386
 387        /// <summary>
 388        /// Sets the maximum RequestLog count.
 389        /// </summary>
 390        /// <param name="maxRequestLogCount">The maximum RequestLog count.</param>
 391        [PublicAPI]
 392        public void SetMaxRequestLogCount([CanBeNull] int? maxRequestLogCount)
 1393        {
 1394            _options.MaxRequestLogCount = maxRequestLogCount;
 1395        }
 396
 397        /// <summary>
 398        /// Sets RequestLog expiration in hours.
 399        /// </summary>
 400        /// <param name="requestLogExpirationDuration">The RequestLog expiration in hours.</param>
 401        [PublicAPI]
 402        public void SetRequestLogExpirationDuration([CanBeNull] int? requestLogExpirationDuration)
 0403        {
 0404            _options.RequestLogExpirationDuration = requestLogExpirationDuration;
 0405        }
 406
 407        /// <summary>
 408        /// Resets the Scenarios.
 409        /// </summary>
 410        [PublicAPI]
 411        public void ResetScenarios()
 0412        {
 0413            _options.Scenarios.Clear();
 0414        }
 415
 416        /// <summary>
 417        /// The given.
 418        /// </summary>
 419        /// <param name="requestMatcher">The request matcher.</param>
 420        /// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
 421        [PublicAPI]
 422        public IRespondWithAProvider Given(IRequestMatcher requestMatcher)
 264423        {
 264424            return new RespondWithAProvider(RegisterMapping, requestMatcher);
 264425        }
 426
 427        private void RegisterMapping(Mapping mapping)
 264428        {
 429            // Check a mapping exists with the same Guid, if so, replace it.
 264430            if (_options.Mappings.ContainsKey(mapping.Guid))
 1431            {
 1432                _options.Mappings[mapping.Guid] = mapping;
 1433            }
 434            else
 263435            {
 263436                _options.Mappings.TryAdd(mapping.Guid, mapping);
 263437            }
 264438        }
 439    }
 440}

C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.LogEntries.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Collections.ObjectModel;
 5using System.Collections.Specialized;
 6using JetBrains.Annotations;
 7using WireMock.Logging;
 8using WireMock.Matchers.Request;
 9using System.Linq;
 10using WireMock.Matchers;
 11
 12namespace WireMock.Server
 13{
 14    public partial class FluentMockServer
 15    {
 16        /// <summary>
 17        /// Occurs when [log entries changed].
 18        /// </summary>
 19        [PublicAPI]
 20        public event NotifyCollectionChangedEventHandler LogEntriesChanged
 21        {
 222            add => _options.LogEntries.CollectionChanged += value;
 023            remove => _options.LogEntries.CollectionChanged -= value;
 24        }
 25
 26        /// <summary>
 27        /// Gets the request logs.
 28        /// </summary>
 29        [PublicAPI]
 1230        public IEnumerable<LogEntry> LogEntries => new ReadOnlyCollection<LogEntry>(_options.LogEntries);
 31
 32        /// <summary>
 33        /// The search log-entries based on matchers.
 34        /// </summary>
 35        /// <param name="matchers">The matchers.</param>
 36        /// <returns>The <see cref="IEnumerable"/>.</returns>
 37        [PublicAPI]
 38        public IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers)
 139        {
 140            var results = new Dictionary<LogEntry, RequestMatchResult>();
 41
 742            foreach (var log in _options.LogEntries)
 243            {
 244                var requestMatchResult = new RequestMatchResult();
 1045                foreach (var matcher in matchers)
 246                {
 247                    matcher.GetMatchingScore(log.RequestMessage, requestMatchResult);
 248                }
 49
 250                if (requestMatchResult.AverageTotalScore > MatchScores.AlmostPerfect)
 151                {
 152                    results.Add(log, requestMatchResult);
 153                }
 254            }
 55
 356            return new ReadOnlyCollection<LogEntry>(results.OrderBy(x => x.Value).Select(x => x.Key).ToList());
 157        }
 58
 59        /// <summary>
 60        /// Resets the LogEntries.
 61        /// </summary>
 62        [PublicAPI]
 63        public void ResetLogEntries()
 964        {
 965            _options.LogEntries.Clear();
 966        }
 67
 68        /// <summary>
 69        /// Deletes a LogEntry.
 70        /// </summary>
 71        /// <param name="guid">The unique identifier.</param>
 72        [PublicAPI]
 73        public bool DeleteLogEntry(Guid guid)
 074        {
 75            // Check a logentry exists with the same GUID, if so, remove it.
 076            var existing = _options.LogEntries.FirstOrDefault(m => m.Guid == guid);
 077            if (existing != null)
 078            {
 079                _options.LogEntries.Remove(existing);
 080                return true;
 81            }
 82
 083            return false;
 084        }
 85    }
 86}

Methods/Properties

.ctor(WireMock.Settings.IFluentMockServerSettings)
InitAdmin()
SaveStaticMappings(System.String)
ReadStaticMappings(System.String)
WatchStaticMappings(System.String)
ReadStaticMappingAndAddOrUpdate(System.String)
InitProxyAndRecord(WireMock.Settings.IFluentMockServerSettings)
ProxyAndRecordAsync()
ToMapping(WireMock.RequestMessage,WireMock.ResponseMessage,System.String[])
SettingsGet(WireMock.RequestMessage)
SettingsUpdate(WireMock.RequestMessage)
MappingGet(WireMock.RequestMessage)
MappingPut(WireMock.RequestMessage)
MappingDelete(WireMock.RequestMessage)
MappingsSave(WireMock.RequestMessage)
SaveMappingToFile(WireMock.Mapping,System.String)
SanitizeFileName(System.String,System.Char)
MappingsGet(WireMock.RequestMessage)
MappingsPost(WireMock.RequestMessage)
DeserializeAndAddOrUpdateMapping(WireMock.Admin.Mappings.MappingModel,System.Nullable`1<System.Guid>,System.String)
MappingsDelete(WireMock.RequestMessage)
RequestGet(WireMock.RequestMessage)
RequestDelete(WireMock.RequestMessage)
RequestsGet(WireMock.RequestMessage)
RequestsDelete(WireMock.RequestMessage)
RequestsFind(WireMock.RequestMessage)
ScenariosGet(WireMock.RequestMessage)
ScenariosReset(WireMock.RequestMessage)
InitRequestBuilder(WireMock.Admin.Mappings.RequestModel,System.Boolean)
InitResponseBuilder(WireMock.Admin.Mappings.ResponseModel)
ToJson(T,System.Boolean)
ToEncoding(WireMock.Admin.Mappings.EncodingModel)
DeserializeObject(WireMock.RequestMessage)
.ctor(WireMock.Settings.IFluentMockServerSettings)
IsStarted()
Ports()
Urls()
Mappings()
Scenarios()
Dispose()
Dispose(System.Boolean)
Start(WireMock.Settings.IFluentMockServerSettings)
Start(System.Nullable`1<System.Int32>,System.Boolean)
Start(System.String[])
StartWithAdminInterface(System.Nullable`1<System.Int32>,System.Boolean)
StartWithAdminInterface(System.String[])
StartWithAdminInterfaceAndReadStaticMappings(System.String[])
Stop()
AddCatchAllMapping()
Reset()
ResetMappings()
DeleteMapping(System.Guid)
DeleteMapping(System.String)
AddGlobalProcessingDelay(System.TimeSpan)
AllowPartialMapping(System.Boolean)
SetBasicAuthentication(System.String,System.String)
RemoveBasicAuthentication()
SetMaxRequestLogCount(System.Nullable`1<System.Int32>)
SetRequestLogExpirationDuration(System.Nullable`1<System.Int32>)
ResetScenarios()
Given(WireMock.Matchers.Request.IRequestMatcher)
RegisterMapping(WireMock.Mapping)
add_LogEntriesChanged(System.Collections.Specialized.NotifyCollectionChangedEventHandler)
remove_LogEntriesChanged(System.Collections.Specialized.NotifyCollectionChangedEventHandler)
LogEntries()
FindLogEntries(WireMock.Matchers.Request.IRequestMatcher[])
ResetLogEntries()
DeleteLogEntry(System.Guid)