Skip to content

Commit

Permalink
ApiDetails now reports back on Warning headers, still pending elastic…
Browse files Browse the repository at this point in the history
  • Loading branch information
Mpdreamz authored and awelburn committed Nov 6, 2017
1 parent 3d2b818 commit ad8b6b7
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/Elasticsearch.Net/Connection/HttpConnection-CoreFx.cs
Expand Up @@ -69,6 +69,7 @@ private HttpClient GetClient(RequestData requestData)
var response = client.SendAsync(requestMessage).GetAwaiter().GetResult();
requestData.MadeItToResponse = true;
builder.StatusCode = (int)response.StatusCode;
builder.DeprecationWarnings = response.Headers.GetValues("Warning");

if (response.Content != null)
builder.Stream = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult();
Expand All @@ -91,6 +92,7 @@ private HttpClient GetClient(RequestData requestData)
var response = await client.SendAsync(requestMessage, cancellationToken).ConfigureAwait(false);
requestData.MadeItToResponse = true;
builder.StatusCode = (int)response.StatusCode;
builder.DeprecationWarnings = response.Headers.GetValues("Warning");

if (response.Content != null)
builder.Stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
Expand Down
4 changes: 4 additions & 0 deletions src/Elasticsearch.Net/Connection/HttpConnection.cs
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -143,6 +144,8 @@ protected virtual void SetBasicAuthenticationIfNeeded(HttpWebRequest request, Re
var response = (HttpWebResponse)request.GetResponse();
builder.StatusCode = (int)response.StatusCode;
builder.Stream = response.GetResponseStream();

builder.DeprecationWarnings = response.Headers.GetValues("Warning");
// https://github.com/elastic/elasticsearch-net/issues/2311
// if stream is null call dispose on response instead.
if (builder.Stream == null || builder.Stream == Stream.Null) response.Dispose();
Expand Down Expand Up @@ -199,6 +202,7 @@ private static void TimeoutCallback(object state, bool timedOut)
var response = (HttpWebResponse)(await apmGetResponseTask.ConfigureAwait(false));
builder.StatusCode = (int)response.StatusCode;
builder.Stream = response.GetResponseStream();
builder.DeprecationWarnings = response.Headers.GetValues("Warning");
// https://github.com/elastic/elasticsearch-net/issues/2311
// if stream is null call dispose on response instead.
if (builder.Stream == null || builder.Stream == Stream.Null) response.Dispose();
Expand Down
9 changes: 9 additions & 0 deletions src/Elasticsearch.Net/Responses/ElasticsearchResponse.cs
Expand Up @@ -11,6 +11,12 @@ public static class ResponseStatics
private static readonly string RequestAlreadyCaptured = "<Request stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on ConnectionSettings to force it to be set on the response.>";
public static string DebugInformationBuilder(IApiCallDetails r, StringBuilder sb)
{
if (r.DeprecationWarnings.HasAny())
{
sb.AppendLine($"# Server indicated deprecations:");
foreach(var deprecation in r.DeprecationWarnings)
sb.AppendLine($"- {deprecation}");
}
sb.AppendLine($"# Audit trail of this API call:");
var auditTrail = (r.AuditTrail ?? Enumerable.Empty<Audit>()).ToList();
DebugAuditTrail(auditTrail, sb);
Expand Down Expand Up @@ -67,6 +73,8 @@ public class ElasticsearchResponse<T> : IApiCallDetails

public List<Audit> AuditTrail { get; internal set; }

public IEnumerable<string> DeprecationWarnings { get; internal set; } = Enumerable.Empty<string>();

/// <summary>
/// The response is successful or has a response code between 400-599, the call should not be retried.
/// Only on 502,503 and 504 will this return false;
Expand Down Expand Up @@ -105,6 +113,7 @@ public string DebugInformation
}
}


public override string ToString() => $"{(Success ? "S" : "Uns")}uccessful low level call on {HttpMethod.GetStringValue()}: {Uri.PathAndQuery}";
}
}
12 changes: 7 additions & 5 deletions src/Elasticsearch.Net/Responses/IApiCallDetails.cs
Expand Up @@ -10,7 +10,7 @@ public interface IApiCallDetails
/// The response status code is in the 200 range or is in the allowed list of status codes set on the request.
/// </summary>
bool Success { get; }

/// <summary>
/// If Success is false this will hold the original exception.
/// This will be the orginating CLR exception in most cases.
Expand All @@ -26,14 +26,14 @@ public interface IApiCallDetails
/// The HTTP method used by the request
/// </summary>
HttpMethod HttpMethod { get; }

/// <summary>
/// The url as requested
/// The url as requested
/// </summary>
Uri Uri { get; }

/// <summary>
/// The HTTP status code as returned by Elasticsearch
/// The HTTP status code as returned by Elasticsearch
/// </summary>
int? HttpStatusCode { get; }

Expand All @@ -49,5 +49,7 @@ public interface IApiCallDetails
List<Audit> AuditTrail { get; }

string DebugInformation { get; }

IEnumerable<string> DeprecationWarnings { get; }
}
}
5 changes: 5 additions & 0 deletions src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -20,6 +22,8 @@ public class ResponseBuilder<TReturn>
public int? StatusCode { get; set; }
public Stream Stream { get; set; }

public IEnumerable<string> DeprecationWarnings { get; set; }

public ResponseBuilder(RequestData requestData, CancellationToken cancellationToken = default(CancellationToken))
{
_requestData = requestData;
Expand Down Expand Up @@ -55,6 +59,7 @@ private ElasticsearchResponse<TReturn> Initialize(int? statusCode, Exception exc
response.Uri = this._requestData.Uri;
response.HttpMethod = this._requestData.Method;
response.OriginalException = exception;
response.DeprecationWarnings = this.DeprecationWarnings ?? Enumerable.Empty<string>();
return response;
}

Expand Down
Expand Up @@ -21,6 +21,7 @@ internal class ApiCallDetailsOverride : IApiCallDetails
public byte[] RequestBodyInBytes => this._original.RequestBodyInBytes;
public List<Audit> AuditTrail => this._original.AuditTrail;
public string DebugInformation => this._original.DebugInformation;
public IEnumerable<string> DeprecationWarnings => this._original.DeprecationWarnings;

public ApiCallDetailsOverride(IApiCallDetails original, bool isValid)
{
Expand Down
39 changes: 39 additions & 0 deletions src/Tests/ClientConcepts/DeprecationLogging.doc.cs
@@ -0,0 +1,39 @@
using FluentAssertions;
using Nest;
using Tests.Framework;
using Tests.Framework.Integration;
using Tests.Framework.MockData;
using Xunit;

namespace Tests.ClientConcepts
{
/**== Deprecation Logging
* Elasticsearch will send back `Warn` HTTP Headers when you are using an API feature thats deprecated and will soon
* be removed or rewritten.
*
* Elasticsearch.NET and NEST report these back to you so you can log and watch out for them.
*/
public class DeprecationLogging : IntegrationDocumentationTestBase, IClusterFixture<ReadOnlyCluster>
{
public DeprecationLogging(ReadOnlyCluster cluster) : base(cluster) { }

[I] public void RequestWithMultipleWarning()
{
var response = this.Client.Search<Project>(s => s
.FielddataFields(fd => fd
.Field(p => p.State)
.Field(p => p.NumberOfCommits)
)
.ScriptFields(sfs => sfs
.ScriptField("commit_factor", sf => sf
.Inline("doc['numberOfCommits'].value * 2")
.Lang("groovy")
)
)
);

response.ApiCall.DeprecationWarnings.Should().NotBeNullOrEmpty();
response.DebugInformation.Should().Contain("Server indicated deprecations:");
}
}
}
1 change: 1 addition & 0 deletions src/Tests/Tests.csproj
Expand Up @@ -225,6 +225,7 @@
<Compile Include="ClientConcepts\ConnectionPooling\Dispose\ResponseBuilderDisposeTests.cs" />
<Compile Include="ClientConcepts\ConnectionPooling\Sniffing\AddressParsing.doc.cs" />
<Compile Include="ClientConcepts\Connection\CustomConnections.cs" />
<Compile Include="ClientConcepts\DeprecationLogging.doc.cs" />
<Compile Include="Cluster\TaskManagement\GetTask\GetTaskApiTests.cs" />
<Compile Include="Cluster\TaskManagement\GetTask\GetTaskUrlTests.cs" />
<Compile Include="CodeStandards\Responses.doc.cs" />
Expand Down
4 changes: 2 additions & 2 deletions src/Tests/tests.yaml
@@ -1,8 +1,8 @@
# mode either u (unit test), i (integration test) or m (mixed mode)
mode: u
mode: i
# the elasticsearch version that should be started
# Can be a snapshot version of sonatype or "latest" to get the latest snapshot of sonatype
elasticsearch_version: 5.1.1
elasticsearch_version: 5.2.0
# cluster filter allows you to only run the integration tests of a particular cluster (cluster suffix not needed)
# cluster_filter:
# whether we want to forcefully reseed on the node, if you are starting the tests with a node already running
Expand Down

0 comments on commit ad8b6b7

Please sign in to comment.