From 78e4dca527d38ae0a9ecab8c03ea8c08d604152b Mon Sep 17 00:00:00 2001 From: Allan hardy Date: Tue, 14 May 2013 22:10:31 +1000 Subject: [PATCH 1/4] allow connection to be created with custom query string parameters --- .../Core/Domain/Connection/ConnectionTests.cs | 55 ++++ .../NameValueCollectionExtensions.cs | 78 +++++ .../Extensions/StringExtensionsTests.cs | 36 +++ .../Extensions/UriExtensionsTests.cs | 36 +++ src/Nest.Tests.Unit/Nest.Tests.Unit.csproj | 4 + src/Nest/Domain/Connection/Connection.cs | 24 +- .../Domain/Connection/ConnectionSettings.cs | 279 +++++++++--------- .../Domain/Connection/IConnectionSettings.cs | 53 ++-- .../NameValueCollectionExtensions.cs | 25 ++ src/Nest/Extensions/StringExtensions.cs | 29 ++ src/Nest/Extensions/UriExtensions.cs | 12 + src/Nest/Nest.csproj | 3 + 12 files changed, 469 insertions(+), 165 deletions(-) create mode 100644 src/Nest.Tests.Unit/Core/Domain/Connection/ConnectionTests.cs create mode 100644 src/Nest.Tests.Unit/Extensions/NameValueCollectionExtensions.cs create mode 100644 src/Nest.Tests.Unit/Extensions/StringExtensionsTests.cs create mode 100644 src/Nest.Tests.Unit/Extensions/UriExtensionsTests.cs create mode 100644 src/Nest/Extensions/NameValueCollectionExtensions.cs create mode 100644 src/Nest/Extensions/StringExtensions.cs create mode 100644 src/Nest/Extensions/UriExtensions.cs diff --git a/src/Nest.Tests.Unit/Core/Domain/Connection/ConnectionTests.cs b/src/Nest.Tests.Unit/Core/Domain/Connection/ConnectionTests.cs new file mode 100644 index 00000000000..e9d26fc5c6b --- /dev/null +++ b/src/Nest.Tests.Unit/Core/Domain/Connection/ConnectionTests.cs @@ -0,0 +1,55 @@ +using NUnit.Framework; +using System; +using System.Collections.Specialized; + +namespace Nest.Tests.Unit.Domain.Connection +{ + using System.Net; + + public class TestConnection : Nest.Connection + { + public TestConnection(IConnectionSettings settings) + : base(settings) { } + + public HttpWebRequest GetConnection(string path, string method) + { + return base.CreateConnection(path, method); + } + } + + [TestFixture] + public class ConnectionTests + { + [Test] + public void CanCreateConnectionWithCustomQueryStringParameters() + { + // Arrange + var uri = new Uri("http://localhost"); + var query = new NameValueCollection { { "authToken", "ABCDEFGHIJK" } }; + var connectionSettings = new ConnectionSettings(uri, query); + var connection = new TestConnection(connectionSettings); + + // Act + var req = connection.GetConnection("/", "GET"); + + // Assert + Assert.IsTrue(string.Compare(req.Address.ToString(), "http://localhost/?authToken=ABCDEFGHIJK", StringComparison.OrdinalIgnoreCase) == 0); + } + + [Test] + public void CanCreateConnectionWithPathAndCustomQueryStringParameters() + { + // Arrange + var uri = new Uri("http://localhost:9000"); + var query = new NameValueCollection { { "authToken", "ABCDEFGHIJK" } }; + var connectionSettings = new ConnectionSettings(uri, query); + var connection = new TestConnection(connectionSettings); + + // Act + var req = connection.GetConnection("/index/", "GET"); + + // Assert + Assert.IsTrue(string.Compare(req.Address.ToString(), "http://localhost:9000/index/?authToken=ABCDEFGHIJK", StringComparison.OrdinalIgnoreCase) == 0); + } + } +} \ No newline at end of file diff --git a/src/Nest.Tests.Unit/Extensions/NameValueCollectionExtensions.cs b/src/Nest.Tests.Unit/Extensions/NameValueCollectionExtensions.cs new file mode 100644 index 00000000000..49440582e4b --- /dev/null +++ b/src/Nest.Tests.Unit/Extensions/NameValueCollectionExtensions.cs @@ -0,0 +1,78 @@ +using NUnit.Framework; +using System; +using System.Collections.Specialized; + +namespace Nest.Tests.Unit.Extensions +{ + [TestFixture] + public class NameValueCollectionExtensions + { + [Test] + public void CanCopyKeyValues() + { + // Arrange + var source = new NameValueCollection { { "key1", "value1" }, { "key2", "value2" }, }; + var dest = new NameValueCollection(); + + // Act + source.CopyKeyValues(dest); + + // Assert + Assert.IsTrue(dest["key1"] == "value1"); + Assert.IsTrue(dest["key2"] == "value2"); + } + + [Test] + public void UnableToCopyKeyValues() + { + // Arrange + var source = new NameValueCollection { { "key1", "value1" }, { "key2", "value2" }, }; + var dest = new NameValueCollection(); + + // Act + source.CopyKeyValues(dest); + + // Assert + Assert.IsTrue(dest["key1"] == "value1"); + Assert.IsTrue(dest["key2"] == "value2"); + } + + [Test] + public void CopyKeyValuesWithDuplicateKeyThrowException() + { + // Arrange + var source = new NameValueCollection { { "key1", "value1" } }; + var dest = new NameValueCollection { { "key1", "value1" } }; + + // Act + // Assert + Assert.Throws(() => source.CopyKeyValues(dest)); + } + + [Test] + public void CanCovertNameValueCollectionToQueryString() + { + // Arrange + var queryCollection = new NameValueCollection { { "key1", "value1" }, { "key2", "value2" }, }; + + // Act + var queryString = queryCollection.ToQueryString(); + + // Assert + Assert.IsTrue(queryString == "?key1=value1&key2=value2"); + } + + [Test] + public void ConvertEmptyNameValueCollectionToQueryStringReturnsEmptyString() + { + // Arrange + var queryCollection = new NameValueCollection(); + + // Act + var queryString = queryCollection.ToQueryString(); + + // Assert + Assert.IsTrue(queryString == string.Empty); + } + } +} diff --git a/src/Nest.Tests.Unit/Extensions/StringExtensionsTests.cs b/src/Nest.Tests.Unit/Extensions/StringExtensionsTests.cs new file mode 100644 index 00000000000..13411149cee --- /dev/null +++ b/src/Nest.Tests.Unit/Extensions/StringExtensionsTests.cs @@ -0,0 +1,36 @@ +using NUnit.Framework; + +namespace Nest.Tests.Unit.Extensions +{ + [TestFixture] + public class StringExtensionsTests + { + [Test] + public void CanConvertQueryStringToNameValueCollectionWithQuestionMark() + { + // Arrange + var queryString = "?test1=one&test2=two"; + + // Act + var queryCollection = queryString.ToNameValueCollection(); + + // Assert + Assert.IsTrue(queryCollection["test1"] == "one"); + Assert.IsTrue(queryCollection["test2"] == "two"); + } + + [Test] + public void CanConvertQueryStringToNameValueCollectionWithoutQuestionMark() + { + // Arrange + var queryString = "test1=testone&test2=testtwo"; + + // Act + var queryCollection = queryString.ToNameValueCollection(); + + // Assert + Assert.IsTrue(queryCollection["test1"] == "testone"); + Assert.IsTrue(queryCollection["test2"] == "testtwo"); + } + } +} diff --git a/src/Nest.Tests.Unit/Extensions/UriExtensionsTests.cs b/src/Nest.Tests.Unit/Extensions/UriExtensionsTests.cs new file mode 100644 index 00000000000..511ca91512e --- /dev/null +++ b/src/Nest.Tests.Unit/Extensions/UriExtensionsTests.cs @@ -0,0 +1,36 @@ +using NUnit.Framework; +using System; + +namespace Nest.Tests.Unit.Extensions +{ + [TestFixture] + public class UriExtensionsTests + { + [Test] + public void CanGetUrlForUriWithPort() + { + // Arrange + var uri = new Uri("http://localhost:8080"); + + // Act + var url = uri.ToUrlAndOverridePath("?test1=value1&test2=value2"); + + // Assert + Assert.IsTrue(url == "http://localhost:8080?test1=value1&test2=value2"); + } + + [Test] + public void CanGetUrlForUriWithoutPort() + { + // Arrange + var uri = new Uri("http://localhost/"); + + // Act + var url = uri.ToUrlAndOverridePath("?test1=value1&test2=value2"); + + // Assert + Assert.IsTrue(url == "http://localhost:80?test1=value1&test2=value2"); + } + + } +} diff --git a/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj b/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj index 60478ea5130..89544feab0d 100644 --- a/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj +++ b/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj @@ -74,6 +74,7 @@ + @@ -98,6 +99,9 @@ + + + diff --git a/src/Nest/Domain/Connection/Connection.cs b/src/Nest/Domain/Connection/Connection.cs index 2fe2af701e3..51d1bfadf37 100644 --- a/src/Nest/Domain/Connection/Connection.cs +++ b/src/Nest/Domain/Connection/Connection.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Specialized; using System.Text; using System.Net; using System.Threading; @@ -303,11 +304,26 @@ public void Iterate(IEnumerable asyncIterator, TaskCompletionSource DefaultTypeNameInferrer { get; private set; } - public FluentDictionary DefaultIndices { get; private set; } - public FluentDictionary DefaultTypeNames { get; private set; } - - public ConnectionSettings(Uri uri) - { - uri.ThrowIfNull("uri"); - - this.Timeout = 60*1000; - - this.Uri = uri; - if (!uri.ToString().EndsWith("/")) - this.Uri = new Uri(uri.ToString() + "/"); - this.Host = uri.Host; - this.Port = uri.Port; - - this.MaximumAsyncConnections = 20; - this.DefaultTypeNameInferrer = this.LowerCaseAndPluralizeTypeNameInferrer; - this.DefaultIndices = new FluentDictionary(); - this.DefaultTypeNames = new FluentDictionary(); - } - - /// - /// Index to default to when no index is specified. - /// - /// When null/empty/not set might throw NRE later on - /// when not specifying index explicitly while indexing. - /// - /// - public ConnectionSettings SetDefaultIndex(string defaultIndex) - { - this.DefaultIndex = defaultIndex; - return this; - } - /// - /// Semaphore asynchronous connections automatically by giving - /// it a maximum concurrent connections. Great to prevent - /// out of memory exceptions - /// - /// defaults to 20 - /// - public ConnectionSettings SetMaximumAsyncConnections(int maximum) - { - this.MaximumAsyncConnections = maximum; - return this; - } - - /// - /// If your connection has to go through proxy use this method to specify the proxy url - /// - /// - public ConnectionSettings SetProxy(Uri proxyAdress, string username, string password) - { - proxyAdress.ThrowIfNull("proxyAdress"); - this.ProxyAddress = proxyAdress.ToString(); - this.ProxyUsername = username; - this.ProxyPassword = password; - return this; - } - - /// - /// Timeout in milliseconds when the .NET webrquest should abort the request, note that you can set this to a high value here, - /// and specify the timeout in various calls on Elasticsearch's side. - /// - /// time out in milliseconds - public ConnectionSettings SetTimeout(int timeout) - { - this.Timeout = timeout; - return this; - } - - /// - /// Append ?pretty=true to requests, this helps to debug send and received json. - /// - /// - public ConnectionSettings UsePrettyResponses(bool b = true) - { - this.UsesPrettyResponses = b; - return this; - } - - private string LowerCaseAndPluralizeTypeNameInferrer(Type type) - { - type.ThrowIfNull("type"); - return Inflector.MakePlural(type.Name).ToLower(); - } - - public ConnectionSettings SetDefaultTypeNameInferrer(Func defaultTypeNameInferrer) - { - defaultTypeNameInferrer.ThrowIfNull("defaultTypeNameInferrer"); - this.DefaultTypeNameInferrer = defaultTypeNameInferrer; - return this; - } - - public ConnectionSettings MapDefaultTypeIndices(Action> mappingSelector) - { - mappingSelector.ThrowIfNull("mappingSelector"); - mappingSelector(this.DefaultIndices); - return this; - } - public ConnectionSettings MapDefaultTypeNames(Action> mappingSelector) - { - mappingSelector.ThrowIfNull("mappingSelector"); - mappingSelector(this.DefaultTypeNames); - return this; - } - - } + public class ConnectionSettings : IConnectionSettings + { + private string _defaultIndex; + public string DefaultIndex + { + get + { + if (this._defaultIndex.IsNullOrEmpty()) + throw new NullReferenceException("No default index set on connection!"); + return this._defaultIndex; + } + private set { this._defaultIndex = value; } + } + public Uri Uri { get; private set; } + public string Host { get; private set; } + public int Port { get; private set; } + public int Timeout { get; private set; } + public string ProxyUsername { get; private set; } + public string ProxyPassword { get; private set; } + public string ProxyAddress { get; private set; } + + public int MaximumAsyncConnections { get; private set; } + public bool UsesPrettyResponses { get; private set; } + + public Func DefaultTypeNameInferrer { get; private set; } + public FluentDictionary DefaultIndices { get; private set; } + public FluentDictionary DefaultTypeNames { get; private set; } + public NameValueCollection QueryStringParameters { get; private set; } + public Action HandleUnauthorizedRequest { get; private set; } + + public ConnectionSettings(Uri uri, NameValueCollection queryStringParamaters) + { + uri.ThrowIfNull("uri"); + + this.Timeout = 60 * 1000; + + this.Uri = uri; + if (!uri.ToString().EndsWith("/")) + this.Uri = new Uri(uri.ToString() + "/"); + this.Host = uri.Host; + this.Port = uri.Port; + + this.MaximumAsyncConnections = 20; + this.DefaultTypeNameInferrer = this.LowerCaseAndPluralizeTypeNameInferrer; + this.DefaultIndices = new FluentDictionary(); + this.DefaultTypeNames = new FluentDictionary(); + this.HandleUnauthorizedRequest = this.HandleDefaultUnauthorizedRequest; + this.QueryStringParameters = queryStringParamaters; + } + + public ConnectionSettings(Uri uri) : this(uri, null) { } + + /// + /// Index to default to when no index is specified. + /// + /// When null/empty/not set might throw NRE later on + /// when not specifying index explicitly while indexing. + /// + /// + public ConnectionSettings SetDefaultIndex(string defaultIndex) + { + this.DefaultIndex = defaultIndex; + return this; + } + /// + /// Semaphore asynchronous connections automatically by giving + /// it a maximum concurrent connections. Great to prevent + /// out of memory exceptions + /// + /// defaults to 20 + /// + public ConnectionSettings SetMaximumAsyncConnections(int maximum) + { + this.MaximumAsyncConnections = maximum; + return this; + } + + /// + /// If your connection has to go through proxy use this method to specify the proxy url + /// + /// + public ConnectionSettings SetProxy(Uri proxyAdress, string username, string password) + { + proxyAdress.ThrowIfNull("proxyAdress"); + this.ProxyAddress = proxyAdress.ToString(); + this.ProxyUsername = username; + this.ProxyPassword = password; + return this; + } + + /// + /// Timeout in milliseconds when the .NET webrquest should abort the request, note that you can set this to a high value here, + /// and specify the timeout in various calls on Elasticsearch's side. + /// + /// time out in milliseconds + public ConnectionSettings SetTimeout(int timeout) + { + this.Timeout = timeout; + return this; + } + + /// + /// Append ?pretty=true to requests, this helps to debug send and received json. + /// + /// + public ConnectionSettings UsePrettyResponses(bool b = true) + { + this.UsesPrettyResponses = b; + return this; + } + + private string LowerCaseAndPluralizeTypeNameInferrer(Type type) + { + type.ThrowIfNull("type"); + return Inflector.MakePlural(type.Name).ToLower(); + } + + private void HandleDefaultUnauthorizedRequest(UnauthorizedAccessException exception) + { + return; + } + + public ConnectionSettings SetDefaultTypeNameInferrer(Func defaultTypeNameInferrer) + { + defaultTypeNameInferrer.ThrowIfNull("defaultTypeNameInferrer"); + this.DefaultTypeNameInferrer = defaultTypeNameInferrer; + return this; + } + + public ConnectionSettings MapDefaultTypeIndices(Action> mappingSelector) + { + mappingSelector.ThrowIfNull("mappingSelector"); + mappingSelector(this.DefaultIndices); + return this; + } + public ConnectionSettings MapDefaultTypeNames(Action> mappingSelector) + { + mappingSelector.ThrowIfNull("mappingSelector"); + mappingSelector(this.DefaultTypeNames); + return this; + } + + } } diff --git a/src/Nest/Domain/Connection/IConnectionSettings.cs b/src/Nest/Domain/Connection/IConnectionSettings.cs index 272fc610448..d2fb8e4ebc9 100644 --- a/src/Nest/Domain/Connection/IConnectionSettings.cs +++ b/src/Nest/Domain/Connection/IConnectionSettings.cs @@ -1,27 +1,28 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Nest -{ - public interface IConnectionSettings - { - FluentDictionary DefaultIndices { get; } - FluentDictionary DefaultTypeNames { get; } - string DefaultIndex { get; } - - string Host { get; } - int Port { get; } - int Timeout { get; } - string ProxyAddress { get; } - string ProxyUsername { get; } - string ProxyPassword { get; } - - int MaximumAsyncConnections { get; } - bool UsesPrettyResponses { get; } - Uri Uri { get; } +using System; +using System.Collections.Specialized; - Func DefaultTypeNameInferrer { get; } - } -} +namespace Nest +{ + public interface IConnectionSettings + { + FluentDictionary DefaultIndices { get; } + FluentDictionary DefaultTypeNames { get; } + string DefaultIndex { get; } + + string Host { get; } + int Port { get; } + int Timeout { get; } + string ProxyAddress { get; } + string ProxyUsername { get; } + string ProxyPassword { get; } + + int MaximumAsyncConnections { get; } + bool UsesPrettyResponses { get; } + Uri Uri { get; } + + NameValueCollection QueryStringParameters { get; } + + Action HandleUnauthorizedRequest { get; } + Func DefaultTypeNameInferrer { get; } + } +} diff --git a/src/Nest/Extensions/NameValueCollectionExtensions.cs b/src/Nest/Extensions/NameValueCollectionExtensions.cs new file mode 100644 index 00000000000..3c1e9d89286 --- /dev/null +++ b/src/Nest/Extensions/NameValueCollectionExtensions.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Specialized; + +namespace Nest +{ + public static class NameValueCollectionExtensions + { + public static void CopyKeyValues(this NameValueCollection self, NameValueCollection source) + { + foreach (var key in source.AllKeys) + { + if (self[key] != null) throw new ApplicationException(string.Format("Attempted to add duplicate key '{0}'", key)); + + self.Add(key, source[key]); + } + } + + public static string ToQueryString(this NameValueCollection self) + { + if (self.AllKeys.Length == 0) return string.Empty; + + return "?" + string.Join("&", Array.ConvertAll(self.AllKeys, key => string.Format("{0}={1}", Uri.EscapeUriString(key), Uri.EscapeUriString(self[key])))); + } + } +} diff --git a/src/Nest/Extensions/StringExtensions.cs b/src/Nest/Extensions/StringExtensions.cs new file mode 100644 index 00000000000..663684799e5 --- /dev/null +++ b/src/Nest/Extensions/StringExtensions.cs @@ -0,0 +1,29 @@ +using System.Collections.Specialized; + +namespace Nest +{ + public static class StringExtensions + { + public static NameValueCollection ToNameValueCollection(this string queryString) + { + if (string.IsNullOrWhiteSpace(queryString)) return new NameValueCollection(); + + var queryParameters = new NameValueCollection(); + var querySegments = queryString.Split('&'); + + foreach (var segment in querySegments) + { + var parts = segment.Split('='); + if (parts.Length > 0) + { + var key = parts[0].Trim(new char[] { '?', ' ' }); + var val = parts[1].Trim(); + + queryParameters.Add(key, val); + } + } + + return queryParameters; + } + } +} diff --git a/src/Nest/Extensions/UriExtensions.cs b/src/Nest/Extensions/UriExtensions.cs new file mode 100644 index 00000000000..239f1ac01be --- /dev/null +++ b/src/Nest/Extensions/UriExtensions.cs @@ -0,0 +1,12 @@ +using System; + +namespace Nest +{ + public static class UriExtensions + { + public static string ToUrlAndOverridePath(this Uri uri, string path) + { + return string.Format("http://{0}:{1}{2}", uri.Host, uri.Port, path); + } + } +} diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj index 7554a8ca595..590ecc5b905 100644 --- a/src/Nest/Nest.csproj +++ b/src/Nest/Nest.csproj @@ -70,7 +70,10 @@ + + + From 0420701f50be7cbeb71d92865bf5295309971053 Mon Sep 17 00:00:00 2001 From: ahardy Date: Wed, 15 May 2013 11:11:07 +1000 Subject: [PATCH 2/4] removing handle unauth request delegate since the httpstatus code is returned in the connectionstatus --- src/Nest/Domain/Connection/ConnectionSettings.cs | 7 ------- src/Nest/Domain/Connection/IConnectionSettings.cs | 1 - 2 files changed, 8 deletions(-) diff --git a/src/Nest/Domain/Connection/ConnectionSettings.cs b/src/Nest/Domain/Connection/ConnectionSettings.cs index b304603b684..3f1f5c340ad 100644 --- a/src/Nest/Domain/Connection/ConnectionSettings.cs +++ b/src/Nest/Domain/Connection/ConnectionSettings.cs @@ -32,7 +32,6 @@ public string DefaultIndex public FluentDictionary DefaultIndices { get; private set; } public FluentDictionary DefaultTypeNames { get; private set; } public NameValueCollection QueryStringParameters { get; private set; } - public Action HandleUnauthorizedRequest { get; private set; } public ConnectionSettings(Uri uri, NameValueCollection queryStringParamaters) { @@ -50,7 +49,6 @@ public ConnectionSettings(Uri uri, NameValueCollection queryStringParamaters) this.DefaultTypeNameInferrer = this.LowerCaseAndPluralizeTypeNameInferrer; this.DefaultIndices = new FluentDictionary(); this.DefaultTypeNames = new FluentDictionary(); - this.HandleUnauthorizedRequest = this.HandleDefaultUnauthorizedRequest; this.QueryStringParameters = queryStringParamaters; } @@ -121,11 +119,6 @@ private string LowerCaseAndPluralizeTypeNameInferrer(Type type) return Inflector.MakePlural(type.Name).ToLower(); } - private void HandleDefaultUnauthorizedRequest(UnauthorizedAccessException exception) - { - return; - } - public ConnectionSettings SetDefaultTypeNameInferrer(Func defaultTypeNameInferrer) { defaultTypeNameInferrer.ThrowIfNull("defaultTypeNameInferrer"); diff --git a/src/Nest/Domain/Connection/IConnectionSettings.cs b/src/Nest/Domain/Connection/IConnectionSettings.cs index d2fb8e4ebc9..0a63a3c083c 100644 --- a/src/Nest/Domain/Connection/IConnectionSettings.cs +++ b/src/Nest/Domain/Connection/IConnectionSettings.cs @@ -22,7 +22,6 @@ public interface IConnectionSettings NameValueCollection QueryStringParameters { get; } - Action HandleUnauthorizedRequest { get; } Func DefaultTypeNameInferrer { get; } } } From 53f4b8b7a8138df011837892388f3f07bc7bf07f Mon Sep 17 00:00:00 2001 From: ahardy Date: Thu, 16 May 2013 10:53:59 +1000 Subject: [PATCH 3/4] allow custom handling of connection status types through a delegate settable on ConnectionSettings --- src/Nest/Domain/Connection/Connection.cs | 10 +++++++--- src/Nest/Domain/Connection/ConnectionSettings.cs | 14 ++++++++++++++ src/Nest/Domain/Connection/IConnectionSettings.cs | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/Nest/Domain/Connection/Connection.cs b/src/Nest/Domain/Connection/Connection.cs index 51d1bfadf37..b4110397da3 100644 --- a/src/Nest/Domain/Connection/Connection.cs +++ b/src/Nest/Domain/Connection/Connection.cs @@ -1,11 +1,11 @@ using System; +using System.Collections.Generic; using System.Collections.Specialized; -using System.Text; +using System.IO; using System.Net; +using System.Text; using System.Threading; -using System.IO; using System.Threading.Tasks; -using System.Collections.Generic; namespace Nest { @@ -185,6 +185,9 @@ protected virtual ConnectionStatus DoSynchronousRequest(HttpWebRequest request, RequestUrl = request.RequestUri.ToString(), RequestMethod = request.Method }; + + _ConnectionSettings.ConnectionStatusHandler(cs); + return cs; } } @@ -210,6 +213,7 @@ protected virtual Task DoAsyncRequest(HttpWebRequest request, return Task.Factory.StartNew(() => { this.Iterate(this._AsyncSteps(request, tcs, data), tcs); + _ConnectionSettings.ConnectionStatusHandler(tcs.Task.Result); return tcs.Task.Result; }, TaskCreationOptions.LongRunning); } diff --git a/src/Nest/Domain/Connection/ConnectionSettings.cs b/src/Nest/Domain/Connection/ConnectionSettings.cs index 3f1f5c340ad..9d4ec657f16 100644 --- a/src/Nest/Domain/Connection/ConnectionSettings.cs +++ b/src/Nest/Domain/Connection/ConnectionSettings.cs @@ -29,6 +29,7 @@ public string DefaultIndex public bool UsesPrettyResponses { get; private set; } public Func DefaultTypeNameInferrer { get; private set; } + public Action ConnectionStatusHandler { get; private set; } public FluentDictionary DefaultIndices { get; private set; } public FluentDictionary DefaultTypeNames { get; private set; } public NameValueCollection QueryStringParameters { get; private set; } @@ -49,6 +50,7 @@ public ConnectionSettings(Uri uri, NameValueCollection queryStringParamaters) this.DefaultTypeNameInferrer = this.LowerCaseAndPluralizeTypeNameInferrer; this.DefaultIndices = new FluentDictionary(); this.DefaultTypeNames = new FluentDictionary(); + this.ConnectionStatusHandler = this.ConnectionStatusDefaultHandler; this.QueryStringParameters = queryStringParamaters; } @@ -119,6 +121,11 @@ private string LowerCaseAndPluralizeTypeNameInferrer(Type type) return Inflector.MakePlural(type.Name).ToLower(); } + private void ConnectionStatusDefaultHandler(ConnectionStatus status) + { + return; + } + public ConnectionSettings SetDefaultTypeNameInferrer(Func defaultTypeNameInferrer) { defaultTypeNameInferrer.ThrowIfNull("defaultTypeNameInferrer"); @@ -126,6 +133,13 @@ public ConnectionSettings SetDefaultTypeNameInferrer(Func defaultT return this; } + public ConnectionSettings SetConnectionStatusHandler(Action handler) + { + handler.ThrowIfNull("handler"); + this.ConnectionStatusHandler = handler; + return this; + } + public ConnectionSettings MapDefaultTypeIndices(Action> mappingSelector) { mappingSelector.ThrowIfNull("mappingSelector"); diff --git a/src/Nest/Domain/Connection/IConnectionSettings.cs b/src/Nest/Domain/Connection/IConnectionSettings.cs index 0a63a3c083c..b2e22005432 100644 --- a/src/Nest/Domain/Connection/IConnectionSettings.cs +++ b/src/Nest/Domain/Connection/IConnectionSettings.cs @@ -21,6 +21,7 @@ public interface IConnectionSettings Uri Uri { get; } NameValueCollection QueryStringParameters { get; } + Action ConnectionStatusHandler { get; } Func DefaultTypeNameInferrer { get; } } From d3756e5822b9b85dfe71492251de9719884b3796 Mon Sep 17 00:00:00 2001 From: ahardy Date: Thu, 16 May 2013 19:00:07 +1000 Subject: [PATCH 4/4] custom handle web exception --- src/Nest/Domain/Connection/Connection.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Nest/Domain/Connection/Connection.cs b/src/Nest/Domain/Connection/Connection.cs index b4110397da3..91ca75538a5 100644 --- a/src/Nest/Domain/Connection/Connection.cs +++ b/src/Nest/Domain/Connection/Connection.cs @@ -193,7 +193,9 @@ protected virtual ConnectionStatus DoSynchronousRequest(HttpWebRequest request, } catch (WebException webException) { - return new ConnectionStatus(webException) { Request = data, RequestUrl = request.RequestUri.ToString(), RequestMethod = request.Method }; + var cs = new ConnectionStatus(webException) { Request = data, RequestUrl = request.RequestUri.ToString(), RequestMethod = request.Method }; + _ConnectionSettings.ConnectionStatusHandler(cs); + return cs; } }