Skip to content
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
43 changes: 43 additions & 0 deletions src/Nest/DSL/NodesHotThreadsDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

using Elasticsearch.Net;
using Elasticsearch.Net.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nest
{
internal static class NodesHotThreadsPathInfo
{
public static void Update(IConnectionSettingsValues settings, ElasticsearchPathInfo<NodesHotThreadsRequestParameters> pathInfo, INodesHotThreadsRequest request)
{
pathInfo.HttpMethod = PathInfoHttpMethod.GET;
}
}

public interface INodesHotThreadsRequest
: INodeIdOptionalPath<NodesHotThreadsRequestParameters>
{
}

public partial class NodesHotThreadsRequest
: NodeIdOptionalPathBase<NodesHotThreadsRequestParameters>, INodesHotThreadsRequest
{
protected override void UpdatePathInfo(IConnectionSettingsValues settings, ElasticsearchPathInfo<NodesHotThreadsRequestParameters> pathInfo)
{
NodesHotThreadsPathInfo.Update(settings, pathInfo, this);
}
}

public partial class NodesHotThreadsDescriptor
: NodeIdOptionalPathBase<NodesHotThreadsRequestParameters>, INodesHotThreadsRequest
{
private INodesHotThreadsRequest Self { get { return this; } }

protected override void UpdatePathInfo(IConnectionSettingsValues settings, ElasticsearchPathInfo<NodesHotThreadsRequestParameters> pathInfo)
{
NodesHotThreadsPathInfo.Update(settings, pathInfo, this.Self);
}
}
}
8 changes: 1 addition & 7 deletions src/Nest/DSL/_Descriptors.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4405,7 +4405,7 @@ public MultiTermVectorsDescriptor<T> Parent(string parent)
///http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/cluster-nodes-hot-threads.html
///</pre>
///</summary>
public partial class NodesHotThreadsDescriptor : BaseRequest<NodesHotThreadsRequestParameters>
public partial class NodesHotThreadsDescriptor
{


Expand Down Expand Up @@ -4441,12 +4441,6 @@ public NodesHotThreadsDescriptor ThreadType(ThreadType thread_type)
return this;
}


protected override void UpdatePathInfo(IConnectionSettingsValues settings, ElasticsearchPathInfo<NodesHotThreadsRequestParameters> pathInfo)
{
throw new NotImplementedException();
}


}

Expand Down
8 changes: 1 addition & 7 deletions src/Nest/DSL/_Requests.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3975,7 +3975,7 @@ public string Parent
///http://www.elasticsearch.org/guide/en/elasticsearch/reference/1.x/cluster-nodes-hot-threads.html
///</pre>
///</summary>
public partial class NodesHotThreadsRequest : BasePathRequest<NodesHotThreadsRequestParameters>
public partial class NodesHotThreadsRequest
{

///<summary>The interval for the second sampling of threads</summary>
Expand Down Expand Up @@ -4009,12 +4009,6 @@ public ThreadType ThreadType
set { this.Request.RequestParameters.AddQueryString("type", value); }
}


protected override void UpdatePathInfo(IConnectionSettingsValues settings, ElasticsearchPathInfo<NodesHotThreadsRequestParameters> pathInfo)
{
throw new NotImplementedException();
}

}


Expand Down
35 changes: 35 additions & 0 deletions src/Nest/Domain/Responses/NodesHotThreadsResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Nest.Resolvers.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nest
{
public class HotThreadInformation
{
public HotThreadInformation()
{
this.Threads = new List<string>();
}

public string Node { get; set; }
public List<string> Threads { get; set; }
}

public interface INodesHotThreadsResponse : IResponse
{
List<HotThreadInformation> HotThreads { get; }
}

public class NodesHotThreadsResponse : BaseResponse, INodesHotThreadsResponse
{
public NodesHotThreadsResponse()
{
this.HotThreads = new List<HotThreadInformation>();
}

public List<HotThreadInformation> HotThreads { get; set; }
}
}
87 changes: 87 additions & 0 deletions src/Nest/ElasticClient-Nodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Elasticsearch.Net;
using System.IO;
using System.Linq;

namespace Nest
{
using NodesHotThreadConverter = Func<IElasticsearchResponse, Stream, NodesHotThreadsResponse>;
using System.Text.RegularExpressions;
using System.Text;

public partial class ElasticClient
{
/// <inheritdoc />
Expand Down Expand Up @@ -85,5 +91,86 @@ public Task<INodeStatsResponse> NodesStatsAsync(INodesStatsRequest nodesStatsReq
(p, d) => this.RawDispatch.NodesStatsDispatchAsync<NodeStatsResponse>(p)
);
}

/// <inheritdoc />
public INodesHotThreadsResponse NodesHotThreads(Func<NodesHotThreadsDescriptor, NodesHotThreadsDescriptor> selector = null)
{
selector = selector ?? (s => s);
return this.Dispatch<NodesHotThreadsDescriptor, NodesHotThreadsRequestParameters, NodesHotThreadsResponse>(
selector,
(p, d) => this.RawDispatch.NodesHotThreadsDispatch<NodesHotThreadsResponse>(
p.DeserializationState(new NodesHotThreadConverter(DeserializeNodesHotThreadResponse)))
);
}

/// <inheritdoc />
public INodesHotThreadsResponse NodesHotThreads(INodesHotThreadsRequest nodesHotThreadsRequest)
{
return this.Dispatch<INodesHotThreadsRequest, NodesHotThreadsRequestParameters, NodesHotThreadsResponse>(
nodesHotThreadsRequest,
(p, d) => this.RawDispatch.NodesHotThreadsDispatch<NodesHotThreadsResponse>(
p.DeserializationState(new NodesHotThreadConverter(DeserializeNodesHotThreadResponse)))
);
}

/// <inheritdoc />
public Task<INodesHotThreadsResponse> NodesHotThreadsAsync(Func<NodesHotThreadsDescriptor, NodesHotThreadsDescriptor> selector = null)
{
selector = selector ?? (s => s);
return this.DispatchAsync<NodesHotThreadsDescriptor, NodesHotThreadsRequestParameters, NodesHotThreadsResponse, INodesHotThreadsResponse>(
selector,
(p, d) => this.RawDispatch.NodesHotThreadsDispatchAsync<NodesHotThreadsResponse>(
p.DeserializationState(new NodesHotThreadConverter(DeserializeNodesHotThreadResponse)))
);
}

/// <inheritdoc />
public Task<INodesHotThreadsResponse> NodesHotThreadsAsync(INodesHotThreadsRequest nodesHotThreadsRequest)
{
return this.DispatchAsync<INodesHotThreadsRequest, NodesHotThreadsRequestParameters, NodesHotThreadsResponse, INodesHotThreadsResponse>(
nodesHotThreadsRequest,
(p, d) => this.RawDispatch.NodesHotThreadsDispatchAsync<NodesHotThreadsResponse>(
p.DeserializationState(new NodesHotThreadConverter(DeserializeNodesHotThreadResponse)))
);
}

/// <summary>
/// Because the nodes.hot_threads endpoint returns plain text instead of JSON, we have to
/// manually parse the response text into a typed response object.
/// </summary>
private NodesHotThreadsResponse DeserializeNodesHotThreadResponse(IElasticsearchResponse response, Stream stream)
{
var typedResponse = new NodesHotThreadsResponse();
var plainTextResponse = Encoding.UTF8.GetString(response.ResponseRaw);

// If the response doesn't start with :::, which is the pattern that delimits
// each node section in the response, then the response format isn't recognized.
// Just return an empty response object. This is especially useful when unit
// testing against an in-memory connection where you won't get a real response.
if (!plainTextResponse.StartsWith(":::"))
return typedResponse;

var sections = plainTextResponse.Split(new string[] { ":::" }, StringSplitOptions.RemoveEmptyEntries);

foreach(var section in sections)
{
var sectionLines = section.Split(new string[] { "\n \n" }, StringSplitOptions.None);

if (sectionLines.Length > 0)
{
var hotThreadInfo = new HotThreadInformation
{
// First line contains the node name between [ ]
Node = sectionLines.First().Split('[')[1].TrimEnd(']'),
// The rest of the lines are hot threads
Threads = sectionLines.Skip(1).Take(sectionLines.Length - 1).ToList()
};

typedResponse.HotThreads.Add(hotThreadInfo);
}
}

return typedResponse;
}
}
}
2 changes: 1 addition & 1 deletion src/Nest/ElasticClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq;
using System.Threading.Tasks;
using Elasticsearch.Net;
using Elasticsearch.Net.Connection;
Expand Down
18 changes: 17 additions & 1 deletion src/Nest/IElasticClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,23 @@ Task<IIndicesResponse> DeleteMappingAsync<T>(Func<DeleteMappingDescriptor<T>, De

/// <inheritdoc />
Task<INodeStatsResponse> NodesStatsAsync(INodesStatsRequest nodesStatsRequest);


/// <summary>
/// An API allowing to get the current hot threads on each node in the cluster.
/// </summary>
/// <param name="selector"></param>
/// <returns>An optional descriptor to further describe the nodes hot threads operation</returns>
INodesHotThreadsResponse NodesHotThreads(Func<NodesHotThreadsDescriptor, NodesHotThreadsDescriptor> selector = null);

/// <inheritdoc />
INodesHotThreadsResponse NodesHotThreads(INodesHotThreadsRequest nodesHotThreadsRequest);

/// <inheritdoc />
Task<INodesHotThreadsResponse> NodesHotThreadsAsync(Func<NodesHotThreadsDescriptor, NodesHotThreadsDescriptor> selector = null);

/// <inheritdoc />
Task<INodesHotThreadsResponse> NodesHotThreadsAsync(INodesHotThreadsRequest nodesHotThreadsRequest);

/// <summary>
/// Used to check if the index (indices) exists or not.
/// <para> </para>http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-exists.html
Expand Down
2 changes: 2 additions & 0 deletions src/Nest/Nest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
<Compile Include="Domain\Responses\ExplainResponse.cs" />
<Compile Include="Domain\Responses\GetFieldMappingResponse.cs" />
<Compile Include="Domain\Responses\MultiPercolateResponse.cs" />
<Compile Include="Domain\Responses\NodesHotThreadsResponse.cs" />
<Compile Include="DSL\Filter\GeoShapeCircleFilterDescriptor.cs" />
<Compile Include="DSL\Filter\GeoShapeMultiLineStringFilterDescriptor.cs" />
<Compile Include="DSL\Filter\GeoShapeMultiPointFilterDescriptor.cs" />
Expand All @@ -168,6 +169,7 @@
<Compile Include="DSL\GetFieldMappingDescriptor.cs" />
<Compile Include="DSL\MultiPercolate\IPercolateOperation.cs" />
<Compile Include="DSL\MultiPercolateDescriptor.cs" />
<Compile Include="DSL\NodesHotThreadsDescriptor.cs" />
<Compile Include="DSL\Paths\IndexOptionalNamePathDescriptor.cs" />
<Compile Include="DSL\Paths\IndicesOptionalTypesNamePathDecriptor.cs" />
<Compile Include="DSL\TypeExistsDescriptor.cs" />
Expand Down
18 changes: 18 additions & 0 deletions src/Tests/Nest.Tests.Integration/Cluster/NodeTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Linq;
using Elasticsearch.Net;
using FluentAssertions;
using NUnit.Framework;

namespace Nest.Tests.Integration.Cluster
Expand Down Expand Up @@ -50,5 +51,22 @@ public void NodeStats()
Assert.IsNotNull(node.Transport);
Assert.IsNotNull(node.HTTP);
}

[Test]
public void NodesHotThreads()
{
var r = this.Client.NodesHotThreads(n => n
.Interval("20s")
.Snapshots(5)
.Threads(5)
.ThreadType(ThreadType.Cpu)
);

r.IsValid.Should().BeTrue();
r.HotThreads.Count.Should().BeGreaterOrEqualTo(1);
var hotThreadInfo = r.HotThreads.First();
hotThreadInfo.Node.Should().NotBeNullOrEmpty();
hotThreadInfo.Threads.Count.ShouldBeEquivalentTo(5);
}
}
}
2 changes: 1 addition & 1 deletion src/Tests/Nest.Tests.Unit/Nest.Tests.Unit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@
<None Include="Core\Map\Properties\MultiFieldPropertyWithJustNamePath.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Compile Include="Core\Map\GetFieldMappingRequestTests.cs" />
<Compile Include="Core\MultiPercolate\MultiPercolateTests.cs" />
<Compile Include="Core\Map\Transform\MappingTansformTests.cs" />
<Compile Include="Core\Scroll\ScrollRequestTests.cs" />
Expand Down Expand Up @@ -232,6 +231,7 @@
<Compile Include="ObjectInitializer\Aliases\GetAliasRequestTests.cs" />
<Compile Include="ObjectInitializer\Aliases\GetAliasesRequestTests.cs" />
<Compile Include="ObjectInitializer\Aliases\AliasRequestTests.cs" />
<Compile Include="ObjectInitializer\Nodes\NodesHotThreadsRequestTests.cs" />
<Compile Include="ObjectInitializer\Status\StatusRequestTests.cs" />
<Compile Include="ObjectInitializer\IndicesStats\IndicesStatsRequestTests.cs" />
<Compile Include="ObjectInitializer\ClusterState\ClusterStateRequestTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Elasticsearch.Net;
using FluentAssertions;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Nest.Tests.Unit.ObjectInitializer.Nodes
{
[TestFixture]
public class NodesHotThreadsRequestTests : BaseJsonTests
{
private readonly IElasticsearchResponse _status;

public NodesHotThreadsRequestTests()
{
var request = new NodesHotThreadsRequest
{
NodeId = "my-node-id",
ThreadType = ThreadType.Block,
Threads = 10,
Snapshots = 2,
Interval = "5s"
};

var response = _client.NodesHotThreads(request);
this._status = response.ConnectionStatus;
}

[Test]
public void Url()
{
this._status.RequestUrl.Should().EndWith("/nodes/my-node-id/hotthreads?type=block&threads=10&snapshots=2&interval=5s");
this._status.RequestMethod.Should().Be("GET");
}
}
}