Skip to content

Commit 5e5abfe

Browse files
committed
Merge pull request #1913 from elastic/fix/1901
await CreateAsync() when try to create a ServerError asynchronously
2 parents 7bbb3fa + 0c4b348 commit 5e5abfe

File tree

7 files changed

+107
-23
lines changed

7 files changed

+107
-23
lines changed

Diff for: src/Elasticsearch.Net/Connection/InMemoryConnection.cs

+34-4
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,22 @@ public class InMemoryConnection : IConnection
1111
{
1212
private readonly byte[] _responseBody;
1313
private readonly int _statusCode;
14+
private readonly Exception _exception;
1415

1516
public InMemoryConnection()
1617
{
1718
_statusCode = 200;
1819
}
1920

20-
public InMemoryConnection(byte[] responseBody, int statusCode = 200)
21+
public InMemoryConnection(byte[] responseBody, int statusCode = 200, Exception exception = null)
2122
{
2223
_responseBody = responseBody;
2324
_statusCode = statusCode;
25+
_exception = exception;
2426
}
2527

26-
public virtual Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(RequestData requestData) where TReturn : class =>
27-
Task.FromResult(this.ReturnConnectionStatus<TReturn>(requestData));
28+
public virtual async Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(RequestData requestData) where TReturn : class =>
29+
await this.ReturnConnectionStatusAsync<TReturn>(requestData).ConfigureAwait(false);
2830

2931
public virtual ElasticsearchResponse<TReturn> Request<TReturn>(RequestData requestData) where TReturn : class =>
3032
this.ReturnConnectionStatus<TReturn>(requestData);
@@ -49,12 +51,40 @@ protected ElasticsearchResponse<TReturn> ReturnConnectionStatus<TReturn>(Request
4951
var builder = new ResponseBuilder<TReturn>(requestData)
5052
{
5153
StatusCode = statusCode ?? this._statusCode,
52-
Stream = (body != null) ? new MemoryStream(body) : null
54+
Stream = (body != null) ? new MemoryStream(body) : null,
55+
Exception = _exception
5356
};
5457
var cs = builder.ToResponse();
5558
return cs;
5659
}
5760

61+
protected async Task<ElasticsearchResponse<TReturn>> ReturnConnectionStatusAsync<TReturn>(RequestData requestData, byte[] responseBody = null, int? statusCode = null)
62+
where TReturn : class
63+
{
64+
var body = responseBody ?? _responseBody;
65+
var data = requestData.PostData;
66+
if (data != null)
67+
{
68+
using (var stream = new MemoryStream())
69+
{
70+
if (requestData.HttpCompression)
71+
using (var zipStream = new GZipStream(stream, CompressionMode.Compress))
72+
await data.WriteAsync(zipStream, requestData.ConnectionSettings).ConfigureAwait(false);
73+
else
74+
await data.WriteAsync(stream, requestData.ConnectionSettings).ConfigureAwait(false);
75+
}
76+
}
77+
78+
var builder = new ResponseBuilder<TReturn>(requestData)
79+
{
80+
StatusCode = statusCode ?? this._statusCode,
81+
Stream = (body != null) ? new MemoryStream(body) : null,
82+
Exception = _exception
83+
};
84+
var cs = await builder.ToResponseAsync().ConfigureAwait(false);
85+
return cs;
86+
}
87+
5888
void IDisposable.Dispose() => DisposeManagedResources();
5989

6090
protected virtual void DisposeManagedResources() { }

Diff for: src/Elasticsearch.Net/Responses/ServerError.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class ServerError
1414
public int Status { get; set; }
1515

1616
public static ServerError Create(Stream stream) => ElasticsearchDefaultSerializer.Instance.Deserialize<ServerError>(stream);
17-
public static Task<ServerError> CreateAsync(Stream stream, CancellationToken token) =>
17+
public static Task<ServerError> CreateAsync(Stream stream, CancellationToken token) =>
1818
ElasticsearchDefaultSerializer.Instance.DeserializeAsync<ServerError>(stream, token);
1919

2020
/// <summary>
@@ -31,9 +31,9 @@ public static bool TryCreate(Stream stream, out ServerError serverError)
3131
/// <summary>
3232
/// Creating the server error might fail in cases where a proxy returns an http response which is not json at all
3333
/// </summary>
34-
public static Task<ServerError> TryCreateAsync(Stream stream, CancellationToken token)
34+
public static async Task<ServerError> TryCreateAsync(Stream stream, CancellationToken token)
3535
{
36-
try { return CreateAsync(stream, token); }
36+
try { return await CreateAsync(stream, token).ConfigureAwait(false); }
3737
catch { // ignored
3838
}
3939
return null;
@@ -56,7 +56,7 @@ internal static ServerError Create(IDictionary<string, object> dict, IJsonSerial
5656
};
5757
}
5858

59-
public override string ToString()
59+
public override string ToString()
6060
{
6161
var sb = new StringBuilder();
6262
sb.Append($"ServerError: {Status}");

Diff for: src/Profiling_Net45/Profiling.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4-
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
54
<PropertyGroup>
65
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
76
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -635,5 +634,6 @@
635634
</ItemGroup>
636635
</When>
637636
</Choose>
637+
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
638638
<Import Project="..\..\packages\JetBrains.Profiler.Kernel.Windows.Api\build\JetBrains.Profiler.Kernel.Windows.Api.Targets" Condition="Exists('..\..\packages\JetBrains.Profiler.Kernel.Windows.Api\build\JetBrains.Profiler.Kernel.Windows.Api.Targets')" Label="Paket" />
639639
</Project>

Diff for: src/Tests/Framework/TestClient.cs

+25-12
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ private static ConnectionSettings DefaultSettings(ConnectionSettings settings) =
3434
.Ignore(p => p.PrivateValue)
3535
.Rename(p => p.OnlineHandle, "nickname")
3636
)
37-
//We try and fetch the test name during integration tests when running fiddler to send the name
37+
//We try and fetch the test name during integration tests when running fiddler to send the name
3838
//as the TestMethod header, this allows us to quickly identify which test sent which request
3939
.GlobalHeaders(new NameValueCollection
4040
{
4141
{ "TestMethod", ExpensiveTestNameForIntegrationTests() }
4242
});
4343

44-
44+
4545
public static ConnectionSettings CreateSettings(
46-
Func<ConnectionSettings, ConnectionSettings> modifySettings = null,
47-
int port = 9200,
46+
Func<ConnectionSettings, ConnectionSettings> modifySettings = null,
47+
int port = 9200,
4848
bool forceInMemory = false,
49-
Func<Uri, IConnectionPool> createPool = null,
49+
Func<Uri, IConnectionPool> createPool = null,
5050
Func<ConnectionSettings, IElasticsearchSerializer> serializerFactory = null
5151
)
5252
{
@@ -77,16 +77,29 @@ public static IConnection CreateConnection(ConnectionSettings settings = null, b
7777
: new InMemoryConnection();
7878

7979
public static IElasticClient GetFixedReturnClient(
80-
object responseJson, int statusCode = 200, Func<ConnectionSettings, ConnectionSettings> modifySettings = null)
80+
object response,
81+
int statusCode = 200,
82+
Func<ConnectionSettings, ConnectionSettings> modifySettings = null,
83+
string contentType = "application/json",
84+
Exception exception = null)
8185
{
8286
var serializer = new JsonNetSerializer(new ConnectionSettings());
8387
byte[] fixedResult;
84-
using (var ms = new MemoryStream())
88+
89+
if (contentType == "application/json")
8590
{
86-
serializer.Serialize(responseJson, ms);
87-
fixedResult = ms.ToArray();
91+
using (var ms = new MemoryStream())
92+
{
93+
serializer.Serialize(response, ms);
94+
fixedResult = ms.ToArray();
95+
}
8896
}
89-
var connection = new InMemoryConnection(fixedResult, statusCode);
97+
else
98+
{
99+
fixedResult = Encoding.UTF8.GetBytes(response.ToString());
100+
}
101+
102+
var connection = new InMemoryConnection(fixedResult, statusCode, exception);
90103
var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
91104
var defaultSettings = new ConnectionSettings(connectionPool, connection);
92105
var settings = (modifySettings != null) ? modifySettings(defaultSettings) : defaultSettings;
@@ -130,8 +143,8 @@ private static ITestConfiguration LoadConfiguration()
130143

131144
// If running the classic .NET solution, tests run from bin/{config} directory,
132145
// but when running DNX solution, tests run from the test project root
133-
var yamlConfigurationPath = directoryInfo.Name == "Tests" &&
134-
directoryInfo.Parent != null &&
146+
var yamlConfigurationPath = directoryInfo.Name == "Tests" &&
147+
directoryInfo.Parent != null &&
135148
directoryInfo.Parent.Name == "src"
136149
? "tests.yaml"
137150
: @"..\..\tests.yaml";

Diff for: src/Tests/Reproduce/GithubIssue1901.cs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Linq.Expressions;
3+
using System.Threading.Tasks;
4+
using Elasticsearch.Net;
5+
using Nest;
6+
using Tests.Framework;
7+
using Tests.Framework.Integration;
8+
using Xunit;
9+
using FluentAssertions;
10+
11+
namespace Tests.Reproduce
12+
{
13+
public class GithubIssue1901
14+
{
15+
private class Example
16+
{
17+
}
18+
19+
private const string ProxyAuthResponse = @"<html>
20+
<head><title>401 Authorization Required</title></head>
21+
<body bgcolor=""white"">
22+
<center><h1>401 Authorization Required</h1></center>
23+
<hr><center>nginx/1.4.6 (Ubuntu)</center>
24+
</body>
25+
</html>
26+
<!-- a padding to disable MSIE and Chrome friendly error page -->
27+
<!-- a padding to disable MSIE and Chrome friendly error page -->
28+
<!-- a padding to disable MSIE and Chrome friendly error page -->
29+
<!-- a padding to disable MSIE and Chrome friendly error page -->
30+
<!-- a padding to disable MSIE and Chrome friendly error page -->
31+
<!-- a padding to disable MSIE and Chrome friendly error page -->";
32+
33+
[U]
34+
public async Task BadAuthResponseDoesNotThrowExceptionWhenAttemptingToDeserializeResponse()
35+
{
36+
var client = TestClient.GetFixedReturnClient(ProxyAuthResponse, 401, contentType: "text/html", exception: new Exception("problem with the request as a result of 401"));
37+
var source = await client.LowLevel.GetSourceAsync<Example>("examples", "example", "1");
38+
source.Success.Should().BeFalse();
39+
}
40+
}
41+
}

Diff for: src/Tests/tests.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# mode either u (unit test), i (integration test) or m (mixed mode)
2-
mode: u
2+
mode: m
33
# the elasticsearch version that should be started
44
elasticsearch_version: 2.2.0
55
# whether we want to forcefully reseed on the node, if you are starting the tests with a node already running

Diff for: src/Tests_Net45/Tests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4-
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
54
<PropertyGroup>
65
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
76
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -790,4 +789,5 @@
790789
</ItemGroup>
791790
</When>
792791
</Choose>
792+
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
793793
</Project>

0 commit comments

Comments
 (0)