Skip to content

Commit 0e97afd

Browse files
committed
Merge pull request #2078 from elastic/fix/skip-http-disabled-nodes-from-sniff
fix #1957 skip http disabled nodes from sniff
2 parents 404fdc6 + 37b699b commit 0e97afd

File tree

5 files changed

+66
-10
lines changed

5 files changed

+66
-10
lines changed

src/Elasticsearch.Net/ConnectionPool/Node.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,24 @@ public Node(Uri uri)
2323
/// <summary> When set this signals the transport that a ping before first usage would be wise</summary>
2424
public bool IsResurrected { get; set; }
2525

26+
/// <summary>Whether HTTP is enabled on the node or not</summary>
27+
public bool HttpEnabled { get; set; } = true;
28+
2629
/// <summary>Indicates whether this node holds data, defaults to true when unknown/unspecified</summary>
2730
public bool HoldsData { get; set; }
2831

2932
/// <summary>Indicates whether this node is master eligible, defaults to true when unknown/unspecified</summary>
3033
public bool MasterEligible { get; set; }
3134

3235
/// <summary>The id of the node, defaults to null when unknown/unspecified</summary>
33-
public string Id { get; set; }
36+
public string Id { get; set; }
3437

3538
/// <summary>The name of the node, defaults to null when unknown/unspecified</summary>
36-
public string Name { get; set; }
39+
public string Name { get; set; }
3740

3841
/// <summary> The number of failed attempts trying to use this node, resets when a node is marked alive</summary>
3942
public int FailedAttempts { get; private set; }
40-
43+
4144
/// <summary> When marked dead this reflects the date that the node has to be taken out of rotation till</summary>
4245
public DateTime DeadUntil { get; private set; }
4346

@@ -56,7 +59,7 @@ public void MarkAlive()
5659
this.FailedAttempts = 0;
5760
this.IsAlive = true;
5861
this.IsResurrected = false;
59-
this.DeadUntil = default(DateTime);
62+
this.DeadUntil = default(DateTime);
6063
}
6164

6265
public Uri CreatePath(string path) => new Uri(this.Uri, path).Purify();
@@ -90,7 +93,7 @@ public bool Equals(Node other)
9093
if (ReferenceEquals(this, other)) return true;
9194
return this.Uri == other.Uri;
9295
}
93-
96+
9497
public override bool Equals(object obj)
9598
{
9699
if (ReferenceEquals(null, obj)) return false;

src/Elasticsearch.Net/Transport/Sniff/SniffResponse.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Linq;
34
using System.Text.RegularExpressions;
45

56
namespace Elasticsearch.Net
@@ -14,20 +15,22 @@ internal class SniffResponse
1415

1516
public IEnumerable<Node> ToNodes(bool forceHttp = false)
1617
{
17-
foreach (var kv in nodes)
18+
foreach (var kv in nodes.Where(n=>n.Value.HttpEnabled))
1819
{
1920
yield return new Node(this.ParseToUri(kv.Value.http_address, forceHttp))
2021
{
2122
Name = kv.Value.name,
2223
Id = kv.Key,
2324
MasterEligible = kv.Value.MasterEligible,
24-
HoldsData = kv.Value.HoldsData,
25+
HoldsData = kv.Value.HoldsData,
26+
HttpEnabled = kv.Value.HttpEnabled,
2527
};
2628
}
2729
}
2830

2931
private Uri ParseToUri(string httpAdress, bool forceHttp)
3032
{
33+
if (httpAdress.IsNullOrEmpty()) return null;
3134
var suffix = forceHttp ? "s" : string.Empty;
3235
var match = AddressRe.Match(httpAdress);
3336
if (!match.Success) throw new Exception($"Can not parse http_address: {httpAdress} to Uri");
@@ -56,6 +59,15 @@ internal class SniffNode
5659

5760
internal bool MasterEligible => !((this.settings?.ContainsKey("node.master")).GetValueOrDefault(false) && Convert.ToBoolean(this.settings["node.master"]) == false);
5861
internal bool HoldsData => !((this.settings?.ContainsKey("node.data")).GetValueOrDefault(false) && Convert.ToBoolean(this.settings["node.data"]) == false);
62+
internal bool HttpEnabled
63+
{
64+
get
65+
{
66+
if (this.settings == null) return true;
67+
if (!this.settings.ContainsKey("http.enabled")) return true;
68+
return Convert.ToBoolean(this.settings["http.enabled"]) ;
69+
}
70+
}
5971
}
6072

6173
}

src/Tests/ClientConcepts/ConnectionPooling/Sniffing/RoleDetection.doc.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,39 @@ public async Task DetectsDataNodes()
7777
};
7878
await audit.TraceStartup();
7979
}
80+
81+
[U, SuppressMessage("AsyncUsage", "AsyncFixer001:Unnecessary async/await usage", Justification = "Its a test")]
82+
public async Task SkipsNodesThatDisableHttp()
83+
{
84+
var audit = new Auditor(() => Framework.Cluster
85+
.Nodes(10)
86+
.Sniff(s => s.SucceedAlways()
87+
.Succeeds(Always, Framework.Cluster.Nodes(8).StoresNoData(9200, 9201, 9202).HttpDisabled(9201))
88+
)
89+
.SniffingConnectionPool()
90+
.AllDefaults()
91+
)
92+
{
93+
AssertPoolBeforeCall = (pool) =>
94+
{
95+
pool.Should().NotBeNull();
96+
pool.Nodes.Should().HaveCount(10);
97+
pool.Nodes.Where(n => n.HoldsData).Should().HaveCount(10);
98+
pool.Nodes.Where(n => n.HttpEnabled).Should().HaveCount(10);
99+
pool.Nodes.Should().OnlyContain(n => n.Uri.Host == "localhost");
100+
},
101+
102+
AssertPoolAfterCall = (pool) =>
103+
{
104+
pool.Should().NotBeNull();
105+
pool.Nodes.Should().HaveCount(7, "we filtered the node that stores no data");
106+
pool.Nodes.Should().NotContain(n=>n.Uri.Port == 9201);
107+
pool.Nodes.Where(n => n.HoldsData).Should().HaveCount(5);
108+
}
109+
};
110+
await audit.TraceStartup();
111+
}
112+
80113
[U, SuppressMessage("AsyncUsage", "AsyncFixer001:Unnecessary async/await usage", Justification = "Its a test")]
81114
public async Task DetectsFqdn()
82115
{

src/Tests/Framework/MockResponses/SniffingResponse.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ private static IDictionary<string, object> SniffResponseNodes(IEnumerable<Node>
3030
select new { id, name, node })
3131
.ToDictionary(kv => kv.id, kv => CreateNodeResponse(kv.node, kv.name, randomFqdn));
3232

33+
private static Random Random = new Random(1337);
3334
private static object CreateNodeResponse(Node node, string name, bool randomFqdn)
3435
{
3536
var fqdn = randomFqdn ? $"fqdn{node.Uri.Port}/" : "";
37+
3638
var nodeResponse = new
3739
{
3840
name = name,
3941
transport_address = $"127.0.0.1:{node.Uri.Port + 1000}]",
40-
http_address = $"{fqdn}127.0.0.1:{node.Uri.Port}",
42+
http_address = node.HttpEnabled ? $"{fqdn}127.0.0.1:{node.Uri.Port}" : null,
4143
host = Guid.NewGuid().ToString("N").Substring(0, 8),
4244
ip = "127.0.0.1",
4345
version = TestClient.Configuration.ElasticsearchVersion,
@@ -49,6 +51,7 @@ private static object CreateNodeResponse(Node node, string name, bool randomFqdn
4951
};
5052
if (!node.MasterEligible) nodeResponse.settings.Add("node.master", false);
5153
if (!node.HoldsData) nodeResponse.settings.Add("node.data", false);
54+
if (!node.HttpEnabled) nodeResponse.settings.Add("http.enabled", false);
5255
return nodeResponse;
5356
}
5457

src/Tests/Framework/VirtualClustering/VirtualCluster.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public class VirtualCluster
1616

1717
private bool _sniffReturnsFqdn = false;
1818
public bool SniffShouldReturnFqnd => _sniffReturnsFqdn;
19-
2019

2120
public IReadOnlyList<Node> Nodes => _nodes;
2221

@@ -44,6 +43,12 @@ public VirtualCluster StoresNoData(params int[] ports)
4443
node.HoldsData = false;
4544
return this;
4645
}
46+
public VirtualCluster HttpDisabled(params int[] ports)
47+
{
48+
foreach (var node in this._nodes.Where(n => ports.Contains(n.Uri.Port)))
49+
node.HttpEnabled = false;
50+
return this;
51+
}
4752

4853
public VirtualCluster Ping(Func<PingRule, IRule> selector)
4954
{
@@ -86,4 +91,4 @@ public SealedVirtualCluster StickyConnectionPool(Func<IList<Node>, IEnumerable<N
8691
}
8792
}
8893

89-
}
94+
}

0 commit comments

Comments
 (0)