Skip to content

Commit b2ee0c7

Browse files
committed
fix #1808 fqdn from http.publish_host should not be parsed correctly and prefered over IP
1 parent 5a60159 commit b2ee0c7

File tree

6 files changed

+72
-12
lines changed

6 files changed

+72
-12
lines changed

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,43 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Text.RegularExpressions;
34

45
namespace Elasticsearch.Net
56
{
67
internal class SniffResponse
78
{
9+
private static Regex AddressRe { get; } = new Regex(@"^(?<fqdn>[^/]+)?/?(?<ip>[^:]+):(?<port>\d+)$");
10+
811
public string cluster_name { get; set; }
912
public Dictionary<string, SniffNode> nodes { get; set; }
1013

1114
public IEnumerable<Node> ToNodes(bool forceHttp = false)
1215
{
13-
var suffix = forceHttp ? "s" : string.Empty;
14-
foreach (var kv in nodes)
15-
yield return new Node(new Uri($"http{suffix}://" + kv.Value.http_address))
16+
foreach (var kv in nodes)
17+
{
18+
yield return new Node(this.ParseToUri(kv.Value.http_address, forceHttp))
1619
{
1720
Name = kv.Value.name,
1821
Id = kv.Key,
1922
MasterEligible = kv.Value.MasterEligible,
2023
HoldsData = kv.Value.HoldsData,
21-
};
24+
};
25+
}
26+
}
27+
28+
private Uri ParseToUri(string httpAdress, bool forceHttp)
29+
{
30+
var suffix = forceHttp ? "s" : string.Empty;
31+
var match = AddressRe.Match(httpAdress);
32+
if (!match.Success) throw new Exception($"Can not parse http_address: {httpAdress} to Uri");
33+
34+
var fqdn = match.Groups["fqdn"].Value?.Trim();
35+
var ip = match.Groups["ip"].Value?.Trim();
36+
var port = match.Groups["port"].Value?.Trim();
37+
var host = !fqdn.IsNullOrEmpty() ? fqdn : ip;
38+
39+
return new Uri($"http{suffix}://{host}:{port}");
40+
2241
}
2342

2443
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,36 @@ public async Task DetectsDataNodes()
7676
}
7777
};
7878
await audit.TraceStartup();
79+
}
80+
[U, SuppressMessage("AsyncUsage", "AsyncFixer001:Unnecessary async/await usage", Justification = "Its a test")]
81+
public async Task DetectsFqdn()
82+
{
83+
var audit = new Auditor(() => Framework.Cluster
84+
.Nodes(10)
85+
.Sniff(s => s.SucceedAlways()
86+
.Succeeds(Always, Framework.Cluster.Nodes(8).StoresNoData(9200, 9201, 9202).SniffShouldReturnFqdn())
87+
)
88+
.SniffingConnectionPool()
89+
.AllDefaults()
90+
)
91+
{
92+
AssertPoolBeforeCall = (pool) =>
93+
{
94+
pool.Should().NotBeNull();
95+
pool.Nodes.Should().HaveCount(10);
96+
pool.Nodes.Where(n => n.HoldsData).Should().HaveCount(10);
97+
pool.Nodes.Should().OnlyContain(n => n.Uri.Host == "localhost");
98+
},
99+
100+
AssertPoolAfterCall = (pool) =>
101+
{
102+
pool.Should().NotBeNull();
103+
pool.Nodes.Should().HaveCount(8);
104+
pool.Nodes.Where(n => n.HoldsData).Should().HaveCount(5);
105+
pool.Nodes.Should().OnlyContain(n => n.Uri.Host.StartsWith("fqdn") && !n.Uri.Host.Contains("/"));
106+
}
107+
};
108+
await audit.TraceStartup();
79109
}
80110
}
81111

src/Tests/Framework/MockResponses/SniffingResponse.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,34 @@ public static class SniffResponse
1010
{
1111
private static string ClusterName => "elasticsearch-test-cluster";
1212

13-
public static byte[] Create(IEnumerable<Node> nodes)
13+
public static byte[] Create(IEnumerable<Node> nodes, bool randomFqdn = false)
1414
{
1515
var response = new
1616
{
1717
cluster_name = ClusterName,
18-
nodes = SniffResponseNodes(nodes)
18+
nodes = SniffResponseNodes(nodes, randomFqdn)
1919
};
2020
using (var ms = new MemoryStream())
2121
{
2222
new ElasticsearchDefaultSerializer().Serialize(response, ms);
2323
return ms.ToArray();
2424
}
2525
}
26-
private static IDictionary<string, object> SniffResponseNodes(IEnumerable<Node> nodes) =>
26+
private static IDictionary<string, object> SniffResponseNodes(IEnumerable<Node> nodes, bool randomFqdn) =>
2727
(from node in nodes
2828
let id = string.IsNullOrEmpty(node.Id) ? Guid.NewGuid().ToString("N").Substring(0, 8) : node.Id
2929
let name = string.IsNullOrEmpty(node.Name) ? Guid.NewGuid().ToString("N").Substring(0, 8) : node.Name
3030
select new { id, name, node })
31-
.ToDictionary(kv => kv.id, kv => CreateNodeResponse(kv.node, kv.name));
31+
.ToDictionary(kv => kv.id, kv => CreateNodeResponse(kv.node, kv.name, randomFqdn));
3232

33-
private static object CreateNodeResponse(Node node, string name)
33+
private static object CreateNodeResponse(Node node, string name, bool randomFqdn)
3434
{
35+
var fqdn = randomFqdn ? $"fqdn{node.Uri.Port}/" : "";
3536
var nodeResponse = new
3637
{
3738
name = name,
3839
transport_address = $"127.0.0.1:{node.Uri.Port + 1000}]",
39-
http_address = $"127.0.0.1:{node.Uri.Port}",
40+
http_address = $"{fqdn}127.0.0.1:{node.Uri.Port}",
4041
host = Guid.NewGuid().ToString("N").Substring(0, 8),
4142
ip = "127.0.0.1",
4243
version = TestClient.Configuration.ElasticsearchVersion,

src/Tests/Framework/VirtualClustering/VirtualCluster.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,23 @@ public class VirtualCluster
1414
public List<IClientCallRule> ClientCallRules { get; } = new List<IClientCallRule>();
1515
public TestableDateTimeProvider DateTimeProvider { get; } = new TestableDateTimeProvider();
1616

17+
private bool _sniffReturnsFqdn = false;
18+
public bool SniffShouldReturnFqnd => _sniffReturnsFqdn;
19+
20+
1721
public IReadOnlyList<Node> Nodes => _nodes;
1822

1923
public VirtualCluster(IEnumerable<Node> nodes)
2024
{
2125
this._nodes = nodes.ToList();
2226
}
2327

28+
public VirtualCluster SniffShouldReturnFqdn()
29+
{
30+
_sniffReturnsFqdn = true;
31+
return this;
32+
}
33+
2434
public VirtualCluster MasterEligible(params int[] ports)
2535
{
2636
foreach (var node in this._nodes.Where(n => !ports.Contains(n.Uri.Port)))

src/Tests/Framework/VirtualClustering/VirtualClusterConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public override ElasticsearchResponse<TReturn> Request<TReturn>(RequestData requ
5353
this._cluster.SniffingRules,
5454
requestData.RequestTimeout,
5555
(r) => this.UpdateCluster(r.NewClusterState),
56-
() => SniffResponse.Create(this._cluster.Nodes)
56+
() => SniffResponse.Create(this._cluster.Nodes, this._cluster.SniffShouldReturnFqnd)
5757
);
5858
}
5959
if (IsPingRequest(requestData))

src/Tests/tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# mode either u (unit test), i (integration test) or m (mixed mode)
2-
mode: m
2+
mode: u
33
# the elasticsearch version that should be started
44
elasticsearch_version: 2.0.1
55
# whether we want to forcefully reseed on the node, if you are starting the tests with a node already running

0 commit comments

Comments
 (0)