Skip to content

Commit 6e96617

Browse files
committed
Add type to set auto expand replicas
1 parent e4045f6 commit 6e96617

File tree

8 files changed

+280
-9
lines changed

8 files changed

+280
-9
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
using System;
2+
using Newtonsoft.Json;
3+
4+
namespace Nest
5+
{
6+
[JsonConverter(typeof(AutoExpandReplicasJsonConverter))]
7+
public class AutoExpandReplicas
8+
{
9+
private const string AllMaxReplicas = "all";
10+
private Union<int?, string> _maxReplicas;
11+
private int? _minReplicas;
12+
13+
/// <summary>
14+
/// Whether auto expand replicas is enabled
15+
/// </summary>
16+
public bool Enabled { get; private set; }
17+
18+
/// <summary>
19+
/// The lower bound of replicas
20+
/// </summary>
21+
public int? MinReplicas
22+
{
23+
get { return _minReplicas; }
24+
private set
25+
{
26+
if (value == null && _maxReplicas == null) Enabled = false;
27+
else Enabled = true;
28+
_minReplicas = value;
29+
}
30+
}
31+
32+
/// <summary>
33+
/// The upper bound or replicas. Can be an integer value or a string value of "all"
34+
/// </summary>
35+
public Union<int?, string> MaxReplicas
36+
{
37+
get { return _maxReplicas; }
38+
private set
39+
{
40+
if (value == null && _minReplicas == null) Enabled = false;
41+
else Enabled = true;
42+
_maxReplicas = value;
43+
}
44+
}
45+
46+
public static AutoExpandReplicas Disabled { get; } = new AutoExpandReplicas();
47+
48+
/// <summary>
49+
/// Creates an <see cref="AutoExpandReplicas"/> with the specified lower and upper bounds of replicas
50+
/// </summary>
51+
public static AutoExpandReplicas Create(int minReplicas, int maxReplicas)
52+
{
53+
if (minReplicas < 0)
54+
throw new ArgumentException("minReplicas must be greater than or equal to 0", nameof(minReplicas));
55+
56+
if (maxReplicas < 0)
57+
throw new ArgumentException("maxReplicas must be greater than or equal to 0", nameof(minReplicas));
58+
59+
if (minReplicas > maxReplicas)
60+
throw new ArgumentException("minReplicas must be less than or equal to maxReplicas", nameof(minReplicas));
61+
62+
return new AutoExpandReplicas
63+
{
64+
Enabled = true,
65+
MinReplicas = minReplicas,
66+
MaxReplicas = maxReplicas
67+
};
68+
}
69+
70+
/// <summary>
71+
/// Creates an <see cref="AutoExpandReplicas"/> with the specified lower bound of replicas and an
72+
/// "all" upper bound of replicas
73+
/// </summary>
74+
public static AutoExpandReplicas Create(int minReplicas)
75+
{
76+
if (minReplicas < 0)
77+
throw new ArgumentException("minReplicas must be greater than or equal to 0", nameof(minReplicas));
78+
79+
return new AutoExpandReplicas
80+
{
81+
Enabled = true,
82+
MinReplicas = minReplicas,
83+
MaxReplicas = AllMaxReplicas
84+
};
85+
}
86+
87+
/// <summary>
88+
/// Creates an <see cref="AutoExpandReplicas"/> with the specified lower and upper bounds of replicas
89+
/// </summary>
90+
/// <example>0-5</example>
91+
/// <example>0-all</example>
92+
public static AutoExpandReplicas Create(string value)
93+
{
94+
if (value.IsNullOrEmpty())
95+
throw new ArgumentException("cannot be null or empty", nameof(value));
96+
97+
var expandReplicaParts = value.Split('-');
98+
if (expandReplicaParts.Length != 2)
99+
{
100+
throw new ArgumentException("must contain a 'from' and 'to' value", nameof(value));
101+
}
102+
103+
int minReplicas;
104+
if (!int.TryParse(expandReplicaParts[0], out minReplicas))
105+
throw new FormatException("minReplicas must be an integer");
106+
107+
var maxReplicas = 0;
108+
var parsedMaxReplicas = false;
109+
var allMaxReplicas = expandReplicaParts[1] == AllMaxReplicas;
110+
111+
if (!allMaxReplicas)
112+
parsedMaxReplicas = int.TryParse(expandReplicaParts[1], out maxReplicas);
113+
114+
if (!parsedMaxReplicas && !allMaxReplicas)
115+
throw new FormatException("minReplicas must be an integer or 'all'");
116+
117+
return parsedMaxReplicas
118+
? Create(minReplicas, maxReplicas)
119+
: Create(minReplicas);
120+
}
121+
122+
public static implicit operator AutoExpandReplicas(string value) =>
123+
value.IsNullOrEmpty() ? null : Create(value);
124+
125+
public override string ToString()
126+
{
127+
if (!Enabled) return "false";
128+
var maxReplicas = MaxReplicas.Match(i => i.ToString(), s => s);
129+
return string.Join("-", MinReplicas, maxReplicas);
130+
}
131+
}
132+
133+
internal class AutoExpandReplicasJsonConverter : JsonConverter
134+
{
135+
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
136+
{
137+
var autoExpandReplicas = (AutoExpandReplicas)value;
138+
139+
if (autoExpandReplicas == null || !autoExpandReplicas.Enabled)
140+
{
141+
writer.WriteValue(false);
142+
return;
143+
}
144+
145+
writer.WriteValue(autoExpandReplicas.ToString());
146+
}
147+
148+
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
149+
{
150+
if (reader.TokenType == JsonToken.Boolean)
151+
return AutoExpandReplicas.Disabled;
152+
if (reader.TokenType == JsonToken.String)
153+
return AutoExpandReplicas.Create((string)reader.Value);
154+
155+
throw new JsonSerializationException($"Cannot deserialize {typeof(AutoExpandReplicas)} from {reader.TokenType}");
156+
}
157+
158+
public override bool CanConvert(Type objectType) => true;
159+
}
160+
}

src/Nest/IndexModules/IndexSettings/Settings/DynamicIndexSettings.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using Newtonsoft.Json;
45

56
namespace Nest
67
{
@@ -16,8 +17,7 @@ public interface IDynamicIndexSettings : IIsADictionary<string, object>
1617
///Auto-expand the number of replicas based on the number of available nodes.
1718
/// Set to a dash delimited lower and upper bound (e.g. 0-5) or use all for the upper bound (e.g. 0-all). Defaults to false (i.e. disabled).
1819
/// </summary>
19-
//TODO SPECIAL TYPE FOR THIS INSTEAD OF JUST STRING
20-
string AutoExpandReplicas { get; set; }
20+
AutoExpandReplicas AutoExpandReplicas { get; set; }
2121

2222
/// <summary>
2323
/// How often to perform a refresh operation, which makes recent changes to the index visible to search.
@@ -103,7 +103,7 @@ public DynamicIndexSettings(IDictionary<string, object> container) : base(contai
103103
public int? NumberOfReplicas { get; set; }
104104

105105
/// <inheritdoc/>
106-
public string AutoExpandReplicas { get; set; }
106+
public AutoExpandReplicas AutoExpandReplicas { get; set; }
107107

108108
/// <inheritdoc/>
109109
public bool? BlocksMetadata { get; set; }
@@ -179,7 +179,7 @@ public TDescriptor Setting(string setting, object value)
179179
public TDescriptor NumberOfReplicas(int? numberOfReplicas) => Assign(a => a.NumberOfReplicas = numberOfReplicas);
180180

181181
/// <inheritdoc/>
182-
public TDescriptor AutoExpandReplicas(string autoExpandReplicas) => Assign(a => a.AutoExpandReplicas = autoExpandReplicas);
182+
public TDescriptor AutoExpandReplicas(AutoExpandReplicas autoExpandReplicas) => Assign(a => a.AutoExpandReplicas = autoExpandReplicas);
183183

184184
/// <inheritdoc/>
185185
public TDescriptor BlocksMetadata(bool? blocksMetadata = true) => Assign(a => a.BlocksMetadata = blocksMetadata);

src/Nest/IndexModules/IndexSettings/Settings/IndexSettingsConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ private void SetKnownIndexSettings(JsonReader reader, JsonSerializer serializer,
115115
var settings = Flatten(JObject.Load(reader)).Properties().ToDictionary(kv => kv.Name);
116116

117117
Set<int?>(s, settings, UpdatableIndexSettings.NumberOfReplicas, v => s.NumberOfReplicas = v);
118-
Set<string>(s, settings, UpdatableIndexSettings.AutoExpandReplicas, v => s.AutoExpandReplicas = v);
118+
Set<AutoExpandReplicas>(s, settings, UpdatableIndexSettings.AutoExpandReplicas, v => s.AutoExpandReplicas = v);
119119
Set<Time>(s, settings, UpdatableIndexSettings.RefreshInterval, v => s.RefreshInterval = v);
120120
Set<bool?>(s, settings, UpdatableIndexSettings.BlocksReadOnly, v => s.BlocksReadOnly = v);
121121
Set<bool?>(s, settings, UpdatableIndexSettings.BlocksRead, v => s.BlocksRead = v);

src/Nest/Nest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,7 @@
628628
<Compile Include="IndexModules\IndexSettings\Merge\MergeSettings.cs" />
629629
<Compile Include="IndexModules\IndexSettings\Queries\IQueriesCacheSettings.cs" />
630630
<Compile Include="IndexModules\IndexSettings\Queries\IQueriesSettings.cs" />
631+
<Compile Include="IndexModules\IndexSettings\Settings\AutoExpandReplicas.cs" />
631632
<Compile Include="IndexModules\IndexSettings\Settings\DynamicIndexSettings.cs" />
632633
<Compile Include="IndexModules\IndexSettings\Settings\IndexSettings.cs" />
633634
<Compile Include="IndexModules\IndexSettings\Settings\IndexSettingsConverter.cs" />
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using FluentAssertions;
7+
using Tests.Framework;
8+
using Nest;
9+
using Xunit;
10+
11+
namespace Tests.CommonOptions.AutoExpandReplicas
12+
{
13+
public class AutoExpandReplicasTests
14+
{
15+
[U]
16+
public void ImplicitConversionFromNullString()
17+
{
18+
string nullString = null;
19+
Nest.AutoExpandReplicas autoExpandReplicas = nullString;
20+
autoExpandReplicas.Should().BeNull();
21+
}
22+
23+
[U]
24+
public void ImplicitConversionFromMinAndMaxString()
25+
{
26+
string minAndMax = "0-5";
27+
Nest.AutoExpandReplicas autoExpandReplicas = minAndMax;
28+
autoExpandReplicas.Should().NotBeNull();
29+
autoExpandReplicas.Enabled.Should().BeTrue();
30+
autoExpandReplicas.MinReplicas.Should().Be(0);
31+
autoExpandReplicas.MaxReplicas.Match(i => i.Should().Be(5), s => Assert.True(false, "expecting a match on integer"));
32+
33+
autoExpandReplicas.ToString().Should().Be(minAndMax);
34+
}
35+
36+
[U]
37+
public void ImplicitConversionFromMinAndAllString()
38+
{
39+
string minAndMax = "0-all";
40+
Nest.AutoExpandReplicas autoExpandReplicas = minAndMax;
41+
autoExpandReplicas.Should().NotBeNull();
42+
autoExpandReplicas.Enabled.Should().BeTrue();
43+
autoExpandReplicas.MinReplicas.Should().Be(0);
44+
autoExpandReplicas.MaxReplicas.Match(
45+
i => Assert.True(false, "expecting a match on string"),
46+
s => s.Should().Be("all"));
47+
48+
autoExpandReplicas.ToString().Should().Be(minAndMax);
49+
}
50+
51+
[U]
52+
public void CreateWithMinAndMax()
53+
{
54+
var autoExpandReplicas = Nest.AutoExpandReplicas.Create(2, 3);
55+
autoExpandReplicas.Should().NotBeNull();
56+
autoExpandReplicas.Enabled.Should().BeTrue();
57+
autoExpandReplicas.MinReplicas.Should().Be(2);
58+
autoExpandReplicas.MaxReplicas.Match(i => i.Should().Be(3), s => Assert.True(false, "expecting a match on integer"));
59+
60+
autoExpandReplicas.ToString().Should().Be("2-3");
61+
}
62+
63+
[U]
64+
public void CreateWithMinAndAll()
65+
{
66+
var autoExpandReplicas = Nest.AutoExpandReplicas.Create(0);
67+
autoExpandReplicas.Should().NotBeNull();
68+
autoExpandReplicas.Enabled.Should().BeTrue();
69+
autoExpandReplicas.MinReplicas.Should().Be(0);
70+
autoExpandReplicas.MaxReplicas.Match(
71+
i => Assert.True(false, "expecting a match on string"),
72+
s => s.Should().Be("all"));
73+
74+
autoExpandReplicas.ToString().Should().Be("0-all");
75+
}
76+
77+
[U]
78+
public void Disabled()
79+
{
80+
var autoExpandReplicas = Nest.AutoExpandReplicas.Disabled;
81+
autoExpandReplicas.Should().NotBeNull();
82+
autoExpandReplicas.Enabled.Should().BeFalse();
83+
autoExpandReplicas.MinReplicas.Should().NotHaveValue();
84+
autoExpandReplicas.MaxReplicas.Should().BeNull();
85+
86+
autoExpandReplicas.ToString().Should().Be("false");
87+
}
88+
89+
[U]
90+
public void MinMustBeEqualOrLessThanMax() => Assert.Throws<ArgumentException>(() => Nest.AutoExpandReplicas.Create(2,1));
91+
92+
[U]
93+
public void MinMustBeGreaterThanOrEqualToZero() => Assert.Throws<ArgumentException>(() => Nest.AutoExpandReplicas.Create(-1));
94+
95+
[U]
96+
public void MinMustBeAnInteger() => Assert.Throws<FormatException>(() => Nest.AutoExpandReplicas.Create("all-all"));
97+
98+
[U]
99+
public void MaxMustBeAllOrAnInteger() => Assert.Throws<FormatException>(() => Nest.AutoExpandReplicas.Create("2-boo"));
100+
}
101+
}

src/Tests/Framework/EndpointTests/Bootstrappers/Seeder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ private void CreateProjectIndex()
152152
private void CreatePercolatorIndex()
153153
{
154154
var createPercolatedIndex = this.Client.CreateIndex(typeof(PercolatedQuery), c => c
155+
.Settings(s => s
156+
.AutoExpandReplicas("0-all")
157+
)
155158
.Mappings(map => map
156159
.Map<PercolatedQuery>(m => m
157160
.AutoMap()
@@ -254,7 +257,6 @@ private static PropertiesDescriptor<Developer> DeveloperProperties(PropertiesDes
254257
)
255258
.GeoPoint(g => g
256259
.Name(p => p.Location)
257-
//.LatLon()
258260
)
259261
.Object<GeoIp>(o => o
260262
.Name(p => p.GeoIp)

src/Tests/Indices/IndexSettings/GetIndexSettings/GetIndexSettingsApiTests.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ protected override LazyResponses ClientUsage() => Calls(
2424
protected override bool ExpectIsValid => true;
2525
protected override int ExpectStatusCode => 200;
2626
protected override HttpMethod HttpMethod => HttpMethod.GET;
27-
protected override string UrlPath => $"/project/_settings/index.%2A?local=true";
27+
protected override string UrlPath => $"/queries/_settings/index.%2A?local=true";
2828

2929
protected override Func<GetIndexSettingsDescriptor, IGetIndexSettingsRequest> Fluent => d => d
30-
.Index<Project>()
30+
.Index<PercolatedQuery>()
3131
.Name("index.*")
3232
.Local();
3333

34-
protected override GetIndexSettingsRequest Initializer => new GetIndexSettingsRequest(Infer.Index<Project>(), "index.*")
34+
protected override GetIndexSettingsRequest Initializer => new GetIndexSettingsRequest(Infer.Index<PercolatedQuery>(), "index.*")
3535
{
3636
Local = true
3737
};
@@ -43,6 +43,12 @@ protected override void ExpectResponse(IGetIndexSettingsResponse response)
4343
index.Should().NotBeNull();
4444
index.Settings.NumberOfShards.Should().HaveValue().And.BeGreaterThan(0);
4545
index.Settings.NumberOfReplicas.Should().HaveValue();
46+
index.Settings.AutoExpandReplicas.Should().NotBeNull();
47+
index.Settings.AutoExpandReplicas.MinReplicas.Should().Be(0);
48+
index.Settings.AutoExpandReplicas.MaxReplicas.Match(
49+
i => { Assert.True(false, "expecting a string"); },
50+
s => s.Should().Be("all"));
51+
index.Settings.AutoExpandReplicas.ToString().Should().Be("0-all");
4652
}
4753
}
4854
}

src/Tests/Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@
224224
<Compile Include="Cluster\TaskManagement\GetTask\GetTaskApiTests.cs" />
225225
<Compile Include="Cluster\TaskManagement\GetTask\GetTaskUrlTests.cs" />
226226
<Compile Include="CodeStandards\Responses.doc.cs" />
227+
<Compile Include="CommonOptions\AutoExpandReplicas\AutoExpandReplicasTests.cs" />
227228
<Compile Include="Document\Multiple\Bulk\BulkUpdateManyTests.cs" />
228229
<Compile Include="Document\Multiple\Bulk\BulkInvalidVersionApiTests.cs" />
229230
<Compile Include="Document\Multiple\Bulk\BulkResponseParsingTests.cs" />

0 commit comments

Comments
 (0)