diff --git a/examples/WireMock.Net.ConsoleApplication/Program.cs b/examples/WireMock.Net.ConsoleApplication/Program.cs
index 28e2ca06..add20e33 100644
--- a/examples/WireMock.Net.ConsoleApplication/Program.cs
+++ b/examples/WireMock.Net.ConsoleApplication/Program.cs
@@ -16,7 +16,12 @@ namespace WireMock.Net.ConsoleApplication
string url2 = "http://localhost:9091/";
string url3 = "https://localhost:9443/";
- var server = FluentMockServer.StartWithAdminInterface(url1, url2, url3);
+ var server = FluentMockServer.Start(new FluentMockServerSettings
+ {
+ Urls = new [] { url1, url2, url3 },
+ StartAdminInterface = true,
+ ReadStaticMappings = true
+ });
Console.WriteLine("FluentMockServer listening at {0}", string.Join(" and ", server.Urls));
server.SetBasicAuthentication("a", "b");
diff --git a/src/WireMock.Net.StandAlone/Program.cs b/src/WireMock.Net.StandAlone/Program.cs
index 37db89bf..f82109c2 100644
--- a/src/WireMock.Net.StandAlone/Program.cs
+++ b/src/WireMock.Net.StandAlone/Program.cs
@@ -16,6 +16,12 @@ namespace WireMock.Net.StandAlone
[SwitchArgument('p', "AllowPartialMapping", true, Description = "Allow Partial Mapping (default set to true).", Optional = true)]
public bool AllowPartialMapping { get; set; }
+
+ [SwitchArgument('s', "StartAdminInterface", true, Description = "Start the AdminInterface (default set to true).", Optional = true)]
+ public bool StartAdminInterface { get; set; }
+
+ [SwitchArgument('r', "ReadStaticMappings", true, Description = "Read StaticMappings from ./__admin/mappings (default set to true).", Optional = true)]
+ public bool ReadStaticMappings { get; set; }
}
static void Main(params string[] args)
@@ -31,7 +37,12 @@ namespace WireMock.Net.StandAlone
if (!options.Urls.Any())
options.Urls.Add("http://localhost:9090/");
- var server = FluentMockServer.StartWithAdminInterface(options.Urls.ToArray());
+ var server = FluentMockServer.Start(new FluentMockServerSettings
+ {
+ Urls = options.Urls.ToArray(),
+ StartAdminInterface = options.StartAdminInterface,
+ ReadStaticMappings = options.ReadStaticMappings
+ });
if (options.AllowPartialMapping)
server.AllowPartialMapping();
diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
index 2fc4dbbb..36f50572 100644
--- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
@@ -66,11 +66,16 @@ namespace WireMock.Server
Check.NotNull(filename, nameof(filename));
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(filename);
- Guid guid;
- if (!Guid.TryParse(filenameWithoutExtension, out guid))
- guid = Guid.NewGuid();
+ Guid guidFromFilename;
- DeserializeAndAddMapping(File.ReadAllText(filename), guid);
+ if (Guid.TryParse(filenameWithoutExtension, out guidFromFilename))
+ {
+ DeserializeAndAddMapping(File.ReadAllText(filename), guidFromFilename);
+ }
+ else
+ {
+ DeserializeAndAddMapping(File.ReadAllText(filename));
+ }
}
private void InitAdmin()
diff --git a/src/WireMock.Net/Server/FluentMockServer.cs b/src/WireMock.Net/Server/FluentMockServer.cs
index d5c553a0..9cdc0885 100644
--- a/src/WireMock.Net/Server/FluentMockServer.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.cs
@@ -19,7 +19,7 @@ namespace WireMock.Server
///
/// The fluent mock server.
///
- public partial class FluentMockServer
+ public partial class FluentMockServer : IDisposable
{
private readonly TinyHttpServer _httpServer;
@@ -112,6 +112,19 @@ namespace WireMock.Server
}
}
+ ///
+ /// Starts the specified settings.
+ ///
+ /// The FluentMockServerSettings.
+ /// The .
+ [PublicAPI]
+ public static FluentMockServer Start(FluentMockServerSettings settings)
+ {
+ Check.NotNull(settings, nameof(settings));
+
+ return new FluentMockServer(settings);
+ }
+
///
/// Start this FluentMockServer.
///
@@ -119,14 +132,13 @@ namespace WireMock.Server
/// The SSL support.
/// The .
[PublicAPI]
- public static FluentMockServer Start(int port = 0, bool ssl = false)
+ public static FluentMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
{
- Check.Condition(port, p => p >= 0, nameof(port));
-
- if (port == 0)
- port = PortUtil.FindFreeTcpPort();
-
- return new FluentMockServer(false, port, ssl);
+ return new FluentMockServer(new FluentMockServerSettings
+ {
+ Port = port,
+ UseSSL = ssl
+ });
}
///
@@ -139,7 +151,10 @@ namespace WireMock.Server
{
Check.NotEmpty(urls, nameof(urls));
- return new FluentMockServer(false, urls);
+ return new FluentMockServer(new FluentMockServerSettings
+ {
+ Urls = urls
+ });
}
///
@@ -149,14 +164,14 @@ namespace WireMock.Server
/// The SSL support.
/// The .
[PublicAPI]
- public static FluentMockServer StartWithAdminInterface(int port = 0, bool ssl = false)
+ public static FluentMockServer StartWithAdminInterface(int? port = 0, bool ssl = false)
{
- Check.Condition(port, p => p >= 0, nameof(port));
-
- if (port == 0)
- port = PortUtil.FindFreeTcpPort();
-
- return new FluentMockServer(true, port, ssl);
+ return new FluentMockServer(new FluentMockServerSettings
+ {
+ Port = port,
+ UseSSL = ssl,
+ StartAdminInterface = true
+ });
}
///
@@ -169,7 +184,57 @@ namespace WireMock.Server
{
Check.NotEmpty(urls, nameof(urls));
- return new FluentMockServer(true, urls);
+ return new FluentMockServer(new FluentMockServerSettings
+ {
+ Urls = urls,
+ StartAdminInterface = true
+ });
+ }
+
+ ///
+ /// Start this FluentMockServer with the admin interface and read static mappings.
+ ///
+ /// The urls.
+ /// The .
+ [PublicAPI]
+ public static FluentMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
+ {
+ Check.NotEmpty(urls, nameof(urls));
+
+ return new FluentMockServer(new FluentMockServerSettings
+ {
+ Urls = urls,
+ StartAdminInterface = true,
+ ReadStaticMappings = true
+ });
+ }
+
+ private FluentMockServer(FluentMockServerSettings settings)
+ {
+ if (settings.Urls != null)
+ {
+ Urls = settings.Urls;
+ }
+ else
+ {
+ int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort();
+ Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
+ }
+
+ _httpServer = new TinyHttpServer(HandleRequestAsync, Urls);
+ Ports = _httpServer.Ports;
+
+ _httpServer.Start();
+
+ if (settings.StartAdminInterface == true)
+ {
+ InitAdmin();
+ }
+
+ if (settings.ReadStaticMappings == true)
+ {
+ ReadStaticMappings();
+ }
}
///
@@ -184,27 +249,6 @@ namespace WireMock.Server
.RespondWith(new DynamicResponseProvider(request => new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" }));
}
- private FluentMockServer(bool startAdminInterface, int port, bool ssl) : this(startAdminInterface, (ssl ? "https" : "http") + "://localhost:" + port + "/")
- {
- }
-
- private FluentMockServer(bool startAdminInterface, params string[] urls)
- {
- Urls = urls;
-
- _httpServer = new TinyHttpServer(HandleRequestAsync, urls);
- Ports = _httpServer.Ports;
-
- _httpServer.Start();
-
- if (startAdminInterface)
- {
- InitAdmin();
- }
-
- ReadStaticMappings();
- }
-
///
/// Stop this server.
///
@@ -214,6 +258,17 @@ namespace WireMock.Server
_httpServer.Stop();
}
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ if (_httpServer != null && _httpServer.IsStarted)
+ {
+ _httpServer.Stop();
+ }
+ }
+
///
/// Resets LogEntries and Mappings.
///
diff --git a/src/WireMock.Net/Server/FluentMockServerSettings.cs b/src/WireMock.Net/Server/FluentMockServerSettings.cs
new file mode 100644
index 00000000..d4eecf5a
--- /dev/null
+++ b/src/WireMock.Net/Server/FluentMockServerSettings.cs
@@ -0,0 +1,48 @@
+namespace WireMock.Server
+{
+ ///
+ /// FluentMockServerSettings
+ ///
+ public class FluentMockServerSettings
+ {
+ ///
+ /// Gets or sets the port.
+ ///
+ ///
+ /// The port.
+ ///
+ public int? Port { get; set; }
+
+ ///
+ /// Gets or sets the use SSL.
+ ///
+ ///
+ /// The use SSL.
+ ///
+ public bool? UseSSL { get; set; }
+
+ ///
+ /// Gets or sets the start admin interface.
+ ///
+ ///
+ /// The start admin interface.
+ ///
+ public bool? StartAdminInterface { get; set; }
+
+ ///
+ /// Gets or sets the read static mappings.
+ ///
+ ///
+ /// The read static mappings.
+ ///
+ public bool? ReadStaticMappings { get; set; }
+
+ ///
+ /// Gets or sets the urls.
+ ///
+ ///
+ /// The urls.
+ ///
+ public string[] Urls { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.cs b/test/WireMock.Net.Tests/FluentMockServerTests.cs
index 6c6c1a90..a20ca18b 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.cs
@@ -19,6 +19,51 @@ namespace WireMock.Net.Tests
{
private FluentMockServer _server;
+ [Test]
+ public void FluentMockServer_ReadStaticMapping_WithNonGuidFilename()
+ {
+ var guid = Guid.Parse("04ee4872-9efd-4770-90d3-88d445265d0d");
+ string title = "documentdb_root_title";
+
+ _server = FluentMockServer.Start();
+
+ _server.ReadStaticMapping("./__admin/mappings/documentdb_root.json");
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(1);
+
+ Check.That(mappings.First().RequestMatcher).IsNotNull();
+ Check.That(mappings.First().Provider).IsNotNull();
+ Check.That(mappings.First().Guid).Equals(guid);
+ Check.That(mappings.First().Title).Equals(title);
+ }
+
+ [Test]
+ public void FluentMockServer_ReadStaticMapping_WithGuidFilename()
+ {
+ string guid = "00000002-ee28-4f29-ae63-1ac9b0802d86";
+
+ _server = FluentMockServer.Start();
+ _server.ReadStaticMapping("./__admin/mappings/" + guid + ".json");
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(1);
+
+ Check.That(mappings.First().RequestMatcher).IsNotNull();
+ Check.That(mappings.First().Provider).IsNotNull();
+ Check.That(mappings.First().Guid).Equals(Guid.Parse(guid));
+ Check.That(mappings.First().Title).IsNullOrEmpty();
+ }
+
+ [Test]
+ public void FluentMockServer_ReadStaticMappings()
+ {
+ _server = FluentMockServer.Start(new FluentMockServerSettings { ReadStaticMappings = true });
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(2);
+ }
+
[Test]
public void FluentMockServer_Admin_Mappings_Get()
{
diff --git a/test/WireMock.Net.Tests/__admin/mappings/00000002-ee28-4f29-ae63-1ac9b0802d86.json b/test/WireMock.Net.Tests/__admin/mappings/00000002-ee28-4f29-ae63-1ac9b0802d86.json
new file mode 100644
index 00000000..9f0cb7e3
--- /dev/null
+++ b/test/WireMock.Net.Tests/__admin/mappings/00000002-ee28-4f29-ae63-1ac9b0802d86.json
@@ -0,0 +1,50 @@
+{
+ "Guid": "00000002-ee28-4f29-ae63-1ac9b0802d86",
+ "Priority": 0,
+ "Request": {
+ "Path": {
+ "Matchers": [
+ {
+ "Name": "ExactMatcher",
+ "Pattern": "/dbs"
+ }
+ ]
+ },
+ "Methods": [
+ "post"
+ ],
+ "Body": {
+ "Matcher": {
+ "Name": "WildcardMatcher",
+ "Pattern": "*db-abc*"
+ }
+ }
+ },
+ "Response": {
+ "StatusCode": 200,
+ "Body": "{\"_rid\":\"\",\"Databases\":[{\"id\":\"db-abc\",\"_rid\":\"hBYWAA==\",\"_self\":\"dbs/hBYWAA==/\",\"_etag\":\"\\\"00008e00-0000-0000-0000-58b94f910000\\\"\",\"_colls\":\"colls/\",\"_users\":\"users/\",\"_ts\":1488539514}],\"_count\":1}",
+ "BodyEncoding": {
+ "CodePage": 65001,
+ "EncodingName": "Unicode (UTF-8)",
+ "WebName": "utf-8"
+ },
+ "UseTransformer": false,
+ "Headers": {
+ "x-ms-schemaversion": "1.3",
+ "Date": "Mon, 06 Mar 2017 10:56:43 GMT",
+ "x-ms-activity-id": "5e39429d-7fcc-4b75-93d6-519b7c582772",
+ "x-ms-item-count": "1",
+ "x-ms-resource-usage": "databases=1;",
+ "x-ms-gatewayversion": "version=1.11.164.3",
+ "x-ms-xp-role": "2",
+ "x-ms-session-token": "0:25908",
+ "x-ms-serviceversion": "version=1.11.150.2",
+ "Strict-Transport-Security": "max-age=31536000",
+ "Server": "Microsoft-HTTPAPI/2.0",
+ "x-ms-last-state-change-utc": "Fri, 24 Feb 2017 11:35:16.053 GMT",
+ "Content-Type": "application/json",
+ "x-ms-request-charge": "4.68",
+ "x-ms-resource-quota": "databases=100;"
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/__admin/mappings/documentdb_root.json b/test/WireMock.Net.Tests/__admin/mappings/documentdb_root.json
new file mode 100644
index 00000000..b9e84681
--- /dev/null
+++ b/test/WireMock.Net.Tests/__admin/mappings/documentdb_root.json
@@ -0,0 +1,42 @@
+{
+ "Guid": "04ee4872-9efd-4770-90d3-88d445265d0d",
+ "Title": "documentdb_root_title",
+ "Priority": 0,
+ "Request": {
+ "Path": {
+ "Matchers": [
+ {
+ "Name": "ExactMatcher",
+ "Pattern": "/"
+ }
+ ]
+ },
+ "Methods": [
+ "get"
+ ],
+ "Body": {}
+ },
+ "Response": {
+ "StatusCode": 200,
+ "Body": "{\"_self\":\"\",\"id\":\"abc\",\"_rid\":\"abc.documents.azure.com\",\"media\":\"//media/\",\"addresses\":\"//addresses/\",\"_dbs\":\"//dbs/\",\"writableLocations\":[{\"name\":\"West Europe\",\"databaseAccountEndpoint\":\"http://localhost:9090/\"}],\"readableLocations\":[{\"name\":\"West Europe\",\"databaseAccountEndpoint\":\"http://localhost:9090/\"}],\"userReplicationPolicy\":{\"asyncReplication\":false,\"minReplicaSetSize\":3,\"maxReplicasetSize\":4},\"userConsistencyPolicy\":{\"defaultConsistencyLevel\":\"Session\"},\"systemReplicationPolicy\":{\"minReplicaSetSize\":3,\"maxReplicasetSize\":4},\"readPolicy\":{\"primaryReadCoefficient\":1,\"secondaryReadCoefficient\":1},\"queryEngineConfiguration\":\"{\\\"maxSqlQueryInputLength\\\":30720,\\\"maxJoinsPerSqlQuery\\\":5,\\\"maxLogicalAndPerSqlQuery\\\":500,\\\"maxLogicalOrPerSqlQuery\\\":500,\\\"maxUdfRefPerSqlQuery\\\":2,\\\"maxInExpressionItemsCount\\\":8000,\\\"queryMaxInMemorySortDocumentCount\\\":500,\\\"maxQueryRequestTimeoutFraction\\\":0.9,\\\"sqlAllowNonFiniteNumbers\\\":false,\\\"sqlAllowAggregateFunctions\\\":true,\\\"sqlAllowSubQuery\\\":false,\\\"allowNewKeywords\\\":true,\\\"sqlAllowLike\\\":false,\\\"maxSpatialQueryCells\\\":12,\\\"spatialMaxGeometryPointCount\\\":256,\\\"sqlAllowTop\\\":true,\\\"enableSpatialIndexing\\\":true}\"}",
+ "BodyEncoding": {
+ "CodePage": 65001,
+ "EncodingName": "Unicode (UTF-8)",
+ "WebName": "utf-8"
+ },
+ "UseTransformer": false,
+ "Headers": {
+ "x-ms-databaseaccount-reserved-mb": "0",
+ "x-ms-databaseaccount-consumed-mb": "0",
+ "Strict-Transport-Security": "max-age=31536000",
+ "x-ms-max-media-storage-usage-mb": "2048",
+ "x-ms-gatewayversion": "version=1.11.164.3",
+ "x-ms-media-storage-usage-mb": "0",
+ "x-ms-databaseaccount-provisioned-mb": "0",
+ "Content-Location": "http://localhost:9090/",
+ "Date": "Mon, 06 Mar 2017 10:56:40 GMT",
+ "Content-Type": "application/json",
+ "Server": "Microsoft-HTTPAPI/2.0"
+ }
+ }
+}
\ No newline at end of file