Skip to content

await CreateAsync() when try to create a ServerError asynchronously #1913

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions src/Elasticsearch.Net/Connection/InMemoryConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ public class InMemoryConnection : IConnection
{
private readonly byte[] _responseBody;
private readonly int _statusCode;
private readonly Exception _exception;

public InMemoryConnection()
{
_statusCode = 200;
}

public InMemoryConnection(byte[] responseBody, int statusCode = 200)
public InMemoryConnection(byte[] responseBody, int statusCode = 200, Exception exception = null)
{
_responseBody = responseBody;
_statusCode = statusCode;
_exception = exception;
}

public virtual Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(RequestData requestData) where TReturn : class =>
Task.FromResult(this.ReturnConnectionStatus<TReturn>(requestData));
public virtual async Task<ElasticsearchResponse<TReturn>> RequestAsync<TReturn>(RequestData requestData) where TReturn : class =>
await this.ReturnConnectionStatusAsync<TReturn>(requestData).ConfigureAwait(false);

public virtual ElasticsearchResponse<TReturn> Request<TReturn>(RequestData requestData) where TReturn : class =>
this.ReturnConnectionStatus<TReturn>(requestData);
Expand All @@ -49,12 +51,40 @@ protected ElasticsearchResponse<TReturn> ReturnConnectionStatus<TReturn>(Request
var builder = new ResponseBuilder<TReturn>(requestData)
{
StatusCode = statusCode ?? this._statusCode,
Stream = (body != null) ? new MemoryStream(body) : null
Stream = (body != null) ? new MemoryStream(body) : null,
Exception = _exception
};
var cs = builder.ToResponse();
return cs;
}

protected async Task<ElasticsearchResponse<TReturn>> ReturnConnectionStatusAsync<TReturn>(RequestData requestData, byte[] responseBody = null, int? statusCode = null)
where TReturn : class
{
var body = responseBody ?? _responseBody;
var data = requestData.PostData;
if (data != null)
{
using (var stream = new MemoryStream())
{
if (requestData.HttpCompression)
using (var zipStream = new GZipStream(stream, CompressionMode.Compress))
await data.WriteAsync(zipStream, requestData.ConnectionSettings).ConfigureAwait(false);
else
await data.WriteAsync(stream, requestData.ConnectionSettings).ConfigureAwait(false);
}
}

var builder = new ResponseBuilder<TReturn>(requestData)
{
StatusCode = statusCode ?? this._statusCode,
Stream = (body != null) ? new MemoryStream(body) : null,
Exception = _exception
};
var cs = await builder.ToResponseAsync().ConfigureAwait(false);
return cs;
}

void IDisposable.Dispose() => DisposeManagedResources();

protected virtual void DisposeManagedResources() { }
Expand Down
8 changes: 4 additions & 4 deletions src/Elasticsearch.Net/Responses/ServerError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ServerError
public int Status { get; set; }

public static ServerError Create(Stream stream) => ElasticsearchDefaultSerializer.Instance.Deserialize<ServerError>(stream);
public static Task<ServerError> CreateAsync(Stream stream, CancellationToken token) =>
public static Task<ServerError> CreateAsync(Stream stream, CancellationToken token) =>
ElasticsearchDefaultSerializer.Instance.DeserializeAsync<ServerError>(stream, token);

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

public override string ToString()
public override string ToString()
{
var sb = new StringBuilder();
sb.Append($"ServerError: {Status}");
Expand Down
2 changes: 1 addition & 1 deletion src/Profiling_Net45/Profiling.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
Expand Down Expand Up @@ -635,5 +634,6 @@
</ItemGroup>
</When>
</Choose>
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
<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" />
</Project>
37 changes: 25 additions & 12 deletions src/Tests/Framework/TestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@ private static ConnectionSettings DefaultSettings(ConnectionSettings settings) =
.Ignore(p => p.PrivateValue)
.Rename(p => p.OnlineHandle, "nickname")
)
//We try and fetch the test name during integration tests when running fiddler to send the name
//We try and fetch the test name during integration tests when running fiddler to send the name
//as the TestMethod header, this allows us to quickly identify which test sent which request
.GlobalHeaders(new NameValueCollection
{
{ "TestMethod", ExpensiveTestNameForIntegrationTests() }
});


public static ConnectionSettings CreateSettings(
Func<ConnectionSettings, ConnectionSettings> modifySettings = null,
int port = 9200,
Func<ConnectionSettings, ConnectionSettings> modifySettings = null,
int port = 9200,
bool forceInMemory = false,
Func<Uri, IConnectionPool> createPool = null,
Func<Uri, IConnectionPool> createPool = null,
Func<ConnectionSettings, IElasticsearchSerializer> serializerFactory = null
)
{
Expand Down Expand Up @@ -77,16 +77,29 @@ public static IConnection CreateConnection(ConnectionSettings settings = null, b
: new InMemoryConnection();

public static IElasticClient GetFixedReturnClient(
object responseJson, int statusCode = 200, Func<ConnectionSettings, ConnectionSettings> modifySettings = null)
object response,
int statusCode = 200,
Func<ConnectionSettings, ConnectionSettings> modifySettings = null,
string contentType = "application/json",
Exception exception = null)
{
var serializer = new JsonNetSerializer(new ConnectionSettings());
byte[] fixedResult;
using (var ms = new MemoryStream())

if (contentType == "application/json")
{
serializer.Serialize(responseJson, ms);
fixedResult = ms.ToArray();
using (var ms = new MemoryStream())
{
serializer.Serialize(response, ms);
fixedResult = ms.ToArray();
}
}
var connection = new InMemoryConnection(fixedResult, statusCode);
else
{
fixedResult = Encoding.UTF8.GetBytes(response.ToString());
}

var connection = new InMemoryConnection(fixedResult, statusCode, exception);
var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultSettings = new ConnectionSettings(connectionPool, connection);
var settings = (modifySettings != null) ? modifySettings(defaultSettings) : defaultSettings;
Expand Down Expand Up @@ -130,8 +143,8 @@ private static ITestConfiguration LoadConfiguration()

// If running the classic .NET solution, tests run from bin/{config} directory,
// but when running DNX solution, tests run from the test project root
var yamlConfigurationPath = directoryInfo.Name == "Tests" &&
directoryInfo.Parent != null &&
var yamlConfigurationPath = directoryInfo.Name == "Tests" &&
directoryInfo.Parent != null &&
directoryInfo.Parent.Name == "src"
? "tests.yaml"
: @"..\..\tests.yaml";
Expand Down
41 changes: 41 additions & 0 deletions src/Tests/Reproduce/GithubIssue1901.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Elasticsearch.Net;
using Nest;
using Tests.Framework;
using Tests.Framework.Integration;
using Xunit;
using FluentAssertions;

namespace Tests.Reproduce
{
public class GithubIssue1901
{
private class Example
{
}

private const string ProxyAuthResponse = @"<html>
<head><title>401 Authorization Required</title></head>
<body bgcolor=""white"">
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.4.6 (Ubuntu)</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->";

[U]
public async Task BadAuthResponseDoesNotThrowExceptionWhenAttemptingToDeserializeResponse()
{
var client = TestClient.GetFixedReturnClient(ProxyAuthResponse, 401, contentType: "text/html", exception: new Exception("problem with the request as a result of 401"));
var source = await client.LowLevel.GetSourceAsync<Example>("examples", "example", "1");
source.Success.Should().BeFalse();
}
}
}
2 changes: 1 addition & 1 deletion src/Tests/tests.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# mode either u (unit test), i (integration test) or m (mixed mode)
mode: u
mode: m
# the elasticsearch version that should be started
elasticsearch_version: 2.2.0
# whether we want to forcefully reseed on the node, if you are starting the tests with a node already running
Expand Down
2 changes: 1 addition & 1 deletion src/Tests_Net45/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
Expand Down Expand Up @@ -790,4 +789,5 @@
</ItemGroup>
</When>
</Choose>
<Import Project="..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props" Condition="Exists('..\..\packages\xunit.core\build\$(__paket__xunit_core_props).props')" Label="Paket" />
</Project>