Skip to content

Commit

Permalink
Make sure we take body: null into account from the spec and not sen…
Browse files Browse the repository at this point in the history
…d any body if no body is documented we relied on serializing empty bodies but the server is now (rightfully) much stricter here.

elastic/elasticsearch#44902
  • Loading branch information
Mpdreamz committed Aug 6, 2019
1 parent cd86174 commit 43544c1
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 169 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ namespace Elasticsearch.Net@(ns)
@foreach (var endpoint in endpoints)
{
var r = endpoint.RequestParameterImplementation;
var supportsBody = endpoint.Body != null;
var names = r.CsharpNames;
<text>
///<summary>Request options for @names.MethodName <para>@r.OfficialDocumentationLink</para></summary>
public class @names.ParametersName : RequestParameters<@names.ParametersName>
{
public override HttpMethod DefaultHttpMethod => HttpMethod.@r.HttpMethod;
public override bool SupportsBody => @(supportsBody ? "true" : "false");
@foreach (var param in r.Params)
{
<text> @Raw(param.InitializerGenerator(param.TypeLowLevel, param.ClsName, param.QueryStringKey, param.SetterLowLevel, param.Description))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace Elasticsearch.Net
public interface IRequestParameters
{
HttpMethod DefaultHttpMethod { get; }

bool SupportsBody { get; }

/// <summary> Allows you to completely circumvent the serializer to build the final response.</summary>
CustomResponseBuilderBase CustomResponseBuilder { get; set; }
Expand Down
338 changes: 169 additions & 169 deletions src/Nest/ElasticClient.cs
Original file line number Diff line number Diff line change
@@ -1,169 +1,169 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Elasticsearch.Net;
using Elasticsearch.Net.Specification.MachineLearningApi;

namespace Nest
{

public class NamespacedClientProxy
{
private readonly ElasticClient _client;

protected NamespacedClientProxy(ElasticClient client) => _client = client;

internal TResponse DoRequest<TRequest, TResponse>(
TRequest p,
IRequestParameters parameters,
Action<IRequestConfiguration> forceConfiguration = null
)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new() =>
_client.DoRequest<TRequest, TResponse>(p, parameters, forceConfiguration);

internal Task<TResponse> DoRequestAsync<TRequest, TResponse>(
TRequest p,
IRequestParameters parameters,
CancellationToken ct,
Action<IRequestConfiguration> forceConfiguration = null
)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new() =>
_client.DoRequestAsync<TRequest, TResponse>(p, parameters, ct, forceConfiguration);

protected CatResponse<TCatRecord> DoCat<TRequest, TParams, TCatRecord>(TRequest request)
where TCatRecord : ICatRecord
where TParams : RequestParameters<TParams>, new()
where TRequest : class, IRequest<TParams>
{
if (typeof(TCatRecord) == typeof(CatHelpRecord))
{
request.RequestParameters.CustomResponseBuilder = CatHelpResponseBuilder.Instance;
return DoRequest<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, r => ElasticClient.ForceTextPlain(r));
}
request.RequestParameters.CustomResponseBuilder = CatResponseBuilder<TCatRecord>.Instance;
return DoRequest<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, r => ElasticClient.ForceJson(r));
}

protected Task<CatResponse<TCatRecord>> DoCatAsync<TRequest, TParams, TCatRecord>(TRequest request, CancellationToken ct)
where TCatRecord : ICatRecord
where TParams : RequestParameters<TParams>, new()
where TRequest : class, IRequest<TParams>
{
if (typeof(TCatRecord) == typeof(CatHelpRecord))
{
request.RequestParameters.CustomResponseBuilder = CatHelpResponseBuilder.Instance;
return DoRequestAsync<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, ct, r => ElasticClient.ForceTextPlain(r));
}
request.RequestParameters.CustomResponseBuilder = CatResponseBuilder<TCatRecord>.Instance;
return DoRequestAsync<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, ct, r => ElasticClient.ForceJson(r));
}

internal IRequestParameters ResponseBuilder(PreviewDatafeedRequestParameters parameters, CustomResponseBuilderBase builder)
{
parameters.CustomResponseBuilder = builder;
return parameters;
}
}
/// <summary>
/// ElasticClient is NEST's strongly typed client which exposes fully mapped Elasticsearch endpoints
/// </summary>
public partial class ElasticClient : IElasticClient
{
public ElasticClient() : this(new ConnectionSettings(new Uri("http://localhost:9200"))) { }

public ElasticClient(Uri uri) : this(new ConnectionSettings(uri)) { }

public ElasticClient(IConnectionSettingsValues connectionSettings)
: this(new Transport<IConnectionSettingsValues>(connectionSettings ?? new ConnectionSettings())) { }

public ElasticClient(ITransport<IConnectionSettingsValues> transport)
{
transport.ThrowIfNull(nameof(transport));
transport.Settings.ThrowIfNull(nameof(transport.Settings));
transport.Settings.RequestResponseSerializer.ThrowIfNull(nameof(transport.Settings.RequestResponseSerializer));
transport.Settings.Inferrer.ThrowIfNull(nameof(transport.Settings.Inferrer));

Transport = transport;
LowLevel = new ElasticLowLevelClient(Transport);
SetupNamespaces();
}

partial void SetupNamespaces();

public IConnectionSettingsValues ConnectionSettings => Transport.Settings;
public Inferrer Infer => Transport.Settings.Inferrer;

public IElasticLowLevelClient LowLevel { get; }
public IElasticsearchSerializer RequestResponseSerializer => Transport.Settings.RequestResponseSerializer;

public IElasticsearchSerializer SourceSerializer => Transport.Settings.SourceSerializer;

private ITransport<IConnectionSettingsValues> Transport { get; }

internal TResponse DoRequest<TRequest, TResponse>(TRequest p, IRequestParameters parameters, Action<IRequestConfiguration> forceConfiguration = null)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new()
{
if (forceConfiguration != null) ForceConfiguration(p, forceConfiguration);
if (p.ContentType != null) ForceContentType(p, p.ContentType);

var url = p.GetUrl(ConnectionSettings);
var b = (p.HttpMethod == HttpMethod.GET || p.HttpMethod == HttpMethod.HEAD) ? null : new SerializableData<TRequest>(p);

return LowLevel.DoRequest<TResponse>(p.HttpMethod, url, b, parameters);
}

internal Task<TResponse> DoRequestAsync<TRequest, TResponse>(
TRequest p,
IRequestParameters parameters,
CancellationToken ct,
Action<IRequestConfiguration> forceConfiguration = null
)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new()
{
if (forceConfiguration != null) ForceConfiguration(p, forceConfiguration);
if (p.ContentType != null) ForceContentType(p, p.ContentType);

var url = p.GetUrl(ConnectionSettings);
var b = (p.HttpMethod == HttpMethod.GET || p.HttpMethod == HttpMethod.HEAD) ? null : new SerializableData<TRequest>(p);

return LowLevel.DoRequestAsync<TResponse>(p.HttpMethod, url, ct, b, parameters);
}

private static void ForceConfiguration(IRequest request, Action<IRequestConfiguration> forceConfiguration)
{
if (forceConfiguration == null) return;

var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
forceConfiguration(configuration);
request.RequestParameters.RequestConfiguration = configuration;
}
private void ForceContentType<TRequest>(TRequest request, string contentType) where TRequest : class, IRequest
{
var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
configuration.Accept = contentType;
configuration.ContentType = contentType;
request.RequestParameters.RequestConfiguration = configuration;
}

internal static void ForceJson(IRequestConfiguration requestConfiguration)
{
requestConfiguration.Accept = RequestData.MimeType;
requestConfiguration.ContentType = RequestData.MimeType;
}
internal static void ForceTextPlain(IRequestConfiguration requestConfiguration)
{
requestConfiguration.Accept = RequestData.MimeTypeTextPlain;
requestConfiguration.ContentType = RequestData.MimeTypeTextPlain;
}

internal IRequestParameters ResponseBuilder(SourceRequestParameters parameters, CustomResponseBuilderBase builder)
{
parameters.CustomResponseBuilder = builder;
return parameters;
}
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
using Elasticsearch.Net;
using Elasticsearch.Net.Specification.MachineLearningApi;

namespace Nest
{

public class NamespacedClientProxy
{
private readonly ElasticClient _client;

protected NamespacedClientProxy(ElasticClient client) => _client = client;

internal TResponse DoRequest<TRequest, TResponse>(
TRequest p,
IRequestParameters parameters,
Action<IRequestConfiguration> forceConfiguration = null
)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new() =>
_client.DoRequest<TRequest, TResponse>(p, parameters, forceConfiguration);

internal Task<TResponse> DoRequestAsync<TRequest, TResponse>(
TRequest p,
IRequestParameters parameters,
CancellationToken ct,
Action<IRequestConfiguration> forceConfiguration = null
)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new() =>
_client.DoRequestAsync<TRequest, TResponse>(p, parameters, ct, forceConfiguration);

protected CatResponse<TCatRecord> DoCat<TRequest, TParams, TCatRecord>(TRequest request)
where TCatRecord : ICatRecord
where TParams : RequestParameters<TParams>, new()
where TRequest : class, IRequest<TParams>
{
if (typeof(TCatRecord) == typeof(CatHelpRecord))
{
request.RequestParameters.CustomResponseBuilder = CatHelpResponseBuilder.Instance;
return DoRequest<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, r => ElasticClient.ForceTextPlain(r));
}
request.RequestParameters.CustomResponseBuilder = CatResponseBuilder<TCatRecord>.Instance;
return DoRequest<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, r => ElasticClient.ForceJson(r));
}

protected Task<CatResponse<TCatRecord>> DoCatAsync<TRequest, TParams, TCatRecord>(TRequest request, CancellationToken ct)
where TCatRecord : ICatRecord
where TParams : RequestParameters<TParams>, new()
where TRequest : class, IRequest<TParams>
{
if (typeof(TCatRecord) == typeof(CatHelpRecord))
{
request.RequestParameters.CustomResponseBuilder = CatHelpResponseBuilder.Instance;
return DoRequestAsync<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, ct, r => ElasticClient.ForceTextPlain(r));
}
request.RequestParameters.CustomResponseBuilder = CatResponseBuilder<TCatRecord>.Instance;
return DoRequestAsync<TRequest, CatResponse<TCatRecord>>(request, request.RequestParameters, ct, r => ElasticClient.ForceJson(r));
}

internal IRequestParameters ResponseBuilder(PreviewDatafeedRequestParameters parameters, CustomResponseBuilderBase builder)
{
parameters.CustomResponseBuilder = builder;
return parameters;
}
}
/// <summary>
/// ElasticClient is NEST's strongly typed client which exposes fully mapped Elasticsearch endpoints
/// </summary>
public partial class ElasticClient : IElasticClient
{
public ElasticClient() : this(new ConnectionSettings(new Uri("http://localhost:9200"))) { }

public ElasticClient(Uri uri) : this(new ConnectionSettings(uri)) { }

public ElasticClient(IConnectionSettingsValues connectionSettings)
: this(new Transport<IConnectionSettingsValues>(connectionSettings ?? new ConnectionSettings())) { }

public ElasticClient(ITransport<IConnectionSettingsValues> transport)
{
transport.ThrowIfNull(nameof(transport));
transport.Settings.ThrowIfNull(nameof(transport.Settings));
transport.Settings.RequestResponseSerializer.ThrowIfNull(nameof(transport.Settings.RequestResponseSerializer));
transport.Settings.Inferrer.ThrowIfNull(nameof(transport.Settings.Inferrer));

Transport = transport;
LowLevel = new ElasticLowLevelClient(Transport);
SetupNamespaces();
}

partial void SetupNamespaces();

public IConnectionSettingsValues ConnectionSettings => Transport.Settings;
public Inferrer Infer => Transport.Settings.Inferrer;

public IElasticLowLevelClient LowLevel { get; }
public IElasticsearchSerializer RequestResponseSerializer => Transport.Settings.RequestResponseSerializer;

public IElasticsearchSerializer SourceSerializer => Transport.Settings.SourceSerializer;

private ITransport<IConnectionSettingsValues> Transport { get; }

internal TResponse DoRequest<TRequest, TResponse>(TRequest p, IRequestParameters parameters, Action<IRequestConfiguration> forceConfiguration = null)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new()
{
if (forceConfiguration != null) ForceConfiguration(p, forceConfiguration);
if (p.ContentType != null) ForceContentType(p, p.ContentType);

var url = p.GetUrl(ConnectionSettings);
var b = (p.HttpMethod == HttpMethod.GET || p.HttpMethod == HttpMethod.HEAD || !parameters.SupportsBody) ? null : new SerializableData<TRequest>(p);

return LowLevel.DoRequest<TResponse>(p.HttpMethod, url, b, parameters);
}

internal Task<TResponse> DoRequestAsync<TRequest, TResponse>(
TRequest p,
IRequestParameters parameters,
CancellationToken ct,
Action<IRequestConfiguration> forceConfiguration = null
)
where TRequest : class, IRequest
where TResponse : class, IElasticsearchResponse, new()
{
if (forceConfiguration != null) ForceConfiguration(p, forceConfiguration);
if (p.ContentType != null) ForceContentType(p, p.ContentType);

var url = p.GetUrl(ConnectionSettings);
var b = (p.HttpMethod == HttpMethod.GET || p.HttpMethod == HttpMethod.HEAD || !parameters.SupportsBody) ? null : new SerializableData<TRequest>(p);

return LowLevel.DoRequestAsync<TResponse>(p.HttpMethod, url, ct, b, parameters);
}

private static void ForceConfiguration(IRequest request, Action<IRequestConfiguration> forceConfiguration)
{
if (forceConfiguration == null) return;

var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
forceConfiguration(configuration);
request.RequestParameters.RequestConfiguration = configuration;
}
private void ForceContentType<TRequest>(TRequest request, string contentType) where TRequest : class, IRequest
{
var configuration = request.RequestParameters.RequestConfiguration ?? new RequestConfiguration();
configuration.Accept = contentType;
configuration.ContentType = contentType;
request.RequestParameters.RequestConfiguration = configuration;
}

internal static void ForceJson(IRequestConfiguration requestConfiguration)
{
requestConfiguration.Accept = RequestData.MimeType;
requestConfiguration.ContentType = RequestData.MimeType;
}
internal static void ForceTextPlain(IRequestConfiguration requestConfiguration)
{
requestConfiguration.Accept = RequestData.MimeTypeTextPlain;
requestConfiguration.ContentType = RequestData.MimeTypeTextPlain;
}

internal IRequestParameters ResponseBuilder(SourceRequestParameters parameters, CustomResponseBuilderBase builder)
{
parameters.CustomResponseBuilder = builder;
return parameters;
}
}
}

0 comments on commit 43544c1

Please sign in to comment.