Skip to content

Commit 9d0f350

Browse files
committed
CSHARP-3064: CommitQuorum option support for createIndexes command on MongoDB 4.4.
1 parent cdbed4f commit 9d0f350

14 files changed

+548
-13
lines changed

src/MongoDB.Driver.Core/Core/Misc/Feature.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class Feature
5050
private static readonly CollationFeature __collation = new CollationFeature("Collation", new SemanticVersion(3, 3, 11));
5151
private static readonly Feature __commandMessage = new Feature("CommandMessage", new SemanticVersion(3, 6, 0));
5252
private static readonly CommandsThatWriteAcceptWriteConcernFeature __commandsThatWriteAcceptWriteConcern = new CommandsThatWriteAcceptWriteConcernFeature("CommandsThatWriteAcceptWriteConcern", new SemanticVersion(3, 3, 11));
53+
private static readonly Feature __createIndexCommitQuorum = new Feature("CreateIndexCommitQuorum", new SemanticVersion(4, 4, 0, ""));
5354
private static readonly Feature __createIndexesCommand = new Feature("CreateIndexesCommand", new SemanticVersion(2, 6, 0));
5455
private static readonly Feature __createIndexesUsingInsertOperations = new Feature("CreateIndexesUsingInsertOperations", new SemanticVersion(1, 0, 0), new SemanticVersion(4, 1, 1, ""));
5556
private static readonly Feature __currentOpCommand = new Feature("CurrentOpCommand", new SemanticVersion(3, 2, 0));
@@ -230,6 +231,11 @@ public class Feature
230231
/// </summary>
231232
public static CommandsThatWriteAcceptWriteConcernFeature CommandsThatWriteAcceptWriteConcern => __commandsThatWriteAcceptWriteConcern;
232233

234+
/// <summary>
235+
/// Gets the create index commit quorum feature.
236+
/// </summary>
237+
public static Feature CreateIndexCommitQuorum => __createIndexCommitQuorum;
238+
233239
/// <summary>
234240
/// Gets the create indexes command feature.
235241
/// </summary>

src/MongoDB.Driver.Core/Core/Operations/CreateIndexesOperation.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class CreateIndexesOperation : IWriteOperation<BsonDocument>
3333
{
3434
// fields
3535
private readonly CollectionNamespace _collectionNamespace;
36+
private CreateIndexCommitQuorum _commitQuorum;
3637
private TimeSpan? _maxTime;
3738
private readonly MessageEncoderSettings _messageEncoderSettings;
3839
private readonly IEnumerable<CreateIndexRequest> _requests;
@@ -67,6 +68,15 @@ public CollectionNamespace CollectionNamespace
6768
get { return _collectionNamespace; }
6869
}
6970

71+
/// <summary>
72+
/// Gets or sets the commit quorum.
73+
/// </summary>
74+
public CreateIndexCommitQuorum CommitQuorum
75+
{
76+
get => _commitQuorum;
77+
set => _commitQuorum = value;
78+
}
79+
7080
/// <summary>
7181
/// Gets the message encoder settings.
7282
/// </summary>
@@ -145,6 +155,7 @@ internal IWriteOperation<BsonDocument> CreateOperation()
145155
{
146156
return new CreateIndexesUsingCommandOperation(_collectionNamespace, _requests, _messageEncoderSettings)
147157
{
158+
CommitQuorum = _commitQuorum,
148159
MaxTime = _maxTime,
149160
WriteConcern = _writeConcern
150161
};

src/MongoDB.Driver.Core/Core/Operations/CreateIndexesUsingCommandOperation.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public class CreateIndexesUsingCommandOperation : IWriteOperation<BsonDocument>
3737
{
3838
// fields
3939
private readonly CollectionNamespace _collectionNamespace;
40+
private CreateIndexCommitQuorum _commitQuorum;
4041
private TimeSpan? _maxTime;
4142
private readonly MessageEncoderSettings _messageEncoderSettings;
4243
private readonly IEnumerable<CreateIndexRequest> _requests;
@@ -71,6 +72,15 @@ public CollectionNamespace CollectionNamespace
7172
get { return _collectionNamespace; }
7273
}
7374

75+
/// <summary>
76+
/// Gets or sets the commit quorum.
77+
/// </summary>
78+
public CreateIndexCommitQuorum CommitQuorum
79+
{
80+
get => _commitQuorum;
81+
set => _commitQuorum = value;
82+
}
83+
7484
/// <summary>
7585
/// Gets the message encoder settings.
7686
/// </summary>
@@ -104,6 +114,7 @@ public WriteConcern WriteConcern
104114
get { return _writeConcern; }
105115
set { _writeConcern = Ensure.IsNotNull(value, nameof(value)); }
106116
}
117+
107118
/// <summary>
108119
/// Gets or sets the MaxTime
109120
/// </summary>
@@ -148,12 +159,18 @@ internal BsonDocument CreateCommand(ICoreSessionHandle session, ConnectionDescri
148159
{
149160
var serverVersion = connectionDescription.ServerVersion;
150161
var writeConcern = WriteConcernHelper.GetWriteConcernForCommandThatWrites(session, _writeConcern, serverVersion);
162+
if (_commitQuorum != null)
163+
{
164+
Feature.CreateIndexCommitQuorum.ThrowIfNotSupported(serverVersion);
165+
}
166+
151167
return new BsonDocument
152168
{
153169
{ "createIndexes", _collectionNamespace.CollectionName },
154170
{ "indexes", new BsonArray(_requests.Select(request => request.CreateIndexDocument(serverVersion))) },
155171
{ "maxTimeMS", () => MaxTimeHelper.ToMaxTimeMS(_maxTime.Value), _maxTime.HasValue },
156-
{ "writeConcern", writeConcern, writeConcern != null }
172+
{ "writeConcern", writeConcern, writeConcern != null },
173+
{ "commitQuorum", () => _commitQuorum.ToBsonValue(), _commitQuorum != null }
157174
};
158175
}
159176

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/* Copyright 2020-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using MongoDB.Bson;
17+
using MongoDB.Driver.Core.Misc;
18+
19+
namespace MongoDB.Driver
20+
{
21+
/// <summary>
22+
/// Represents a create index commit quorum.
23+
/// </summary>
24+
public abstract class CreateIndexCommitQuorum
25+
{
26+
#region static
27+
// private static fields
28+
private static readonly CreateIndexCommitQuorum __majority = new CreateIndexCommitQuorumWithMode("majority");
29+
private static readonly CreateIndexCommitQuorum __votingMembers = new CreateIndexCommitQuorumWithMode("votingMembers");
30+
31+
// public static properties
32+
/// <summary>
33+
/// Gets a create index commit quorum of majority.
34+
/// </summary>
35+
public static CreateIndexCommitQuorum Majority => __majority;
36+
37+
/// <summary>
38+
/// Gets a create index commit quorum of voting members.
39+
/// </summary>
40+
public static CreateIndexCommitQuorum VotingMembers => __votingMembers;
41+
42+
// public static methods
43+
/// <summary>
44+
/// Creates a create index commit quorum with a mode value.
45+
/// </summary>
46+
/// <param name="mode">The mode value.</param>
47+
/// <returns>A create index commit quorum.</returns>
48+
public static CreateIndexCommitQuorum Create(string mode) => new CreateIndexCommitQuorumWithMode(mode);
49+
50+
/// <summary>
51+
/// Creates a create index commit quorum with a w value.
52+
/// </summary>
53+
/// <param name="w">The w value.</param>
54+
/// <returns>A create index commit quorum.</returns>
55+
public static CreateIndexCommitQuorum Create(int w) => new CreateIndexCommitQuorumWithW(w);
56+
#endregion
57+
58+
// public methods
59+
/// <summary>
60+
/// Converts the create index commit quorum to a BsonValue.
61+
/// </summary>
62+
/// <returns>A BsonValue.</returns>
63+
public abstract BsonValue ToBsonValue();
64+
}
65+
66+
/// <summary>
67+
/// Represents a CreateIndexCommitQuorum with a mode value.
68+
/// </summary>
69+
public sealed class CreateIndexCommitQuorumWithMode : CreateIndexCommitQuorum
70+
{
71+
// private fields
72+
private readonly string _mode;
73+
74+
// constructors
75+
/// <summary>
76+
/// Initializes an instance of CreateIndexCommitQuorumWithMode.
77+
/// </summary>
78+
/// <param name="mode">The mode value.</param>
79+
public CreateIndexCommitQuorumWithMode(string mode)
80+
{
81+
_mode = Ensure.IsNotNullOrEmpty(mode, nameof(mode));
82+
}
83+
84+
// public properties
85+
/// <summary>
86+
/// The mode value.
87+
/// </summary>
88+
public string Mode => _mode;
89+
90+
// public methods
91+
/// <inheritdoc/>
92+
public override BsonValue ToBsonValue()
93+
{
94+
return new BsonString(_mode);
95+
}
96+
}
97+
98+
/// <summary>
99+
/// Represents a CreateIndexCommitQuorum with a w value.
100+
/// </summary>
101+
public sealed class CreateIndexCommitQuorumWithW : CreateIndexCommitQuorum
102+
{
103+
// private fields
104+
private readonly int _w;
105+
106+
// constructors
107+
/// <summary>
108+
/// Initializes an instance of CreateIndexCommitQuorumWithW.
109+
/// </summary>
110+
/// <param name="w">The w value.</param>
111+
public CreateIndexCommitQuorumWithW(int w)
112+
{
113+
_w = Ensure.IsGreaterThanOrEqualToZero(w, nameof(w));
114+
}
115+
116+
// public properties
117+
/// <summary>
118+
/// The w value.
119+
/// </summary>
120+
public int W => _w;
121+
122+
// public methods
123+
/// <inheritdoc/>
124+
public override BsonValue ToBsonValue()
125+
{
126+
return BsonInt32.Create(_w);
127+
}
128+
}
129+
}

src/MongoDB.Driver/CreateManyIndexesOptions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,21 @@ namespace MongoDB.Driver
2323
/// </summary>
2424
public class CreateManyIndexesOptions
2525
{
26+
// private fields
27+
private CreateIndexCommitQuorum _commitQuorum;
2628
private TimeSpan? _maxTime;
2729

30+
// public properties
31+
/// <summary>
32+
/// Gets or sets the commit quorum.
33+
/// </summary>
34+
/// <value>The commit quorum.</value>
35+
public CreateIndexCommitQuorum CommitQuorum
36+
{
37+
get { return _commitQuorum; }
38+
set { _commitQuorum = value; }
39+
}
40+
2841
/// <summary>
2942
/// Gets or sets the maximum time.
3043
/// </summary>

src/MongoDB.Driver/CreateOneIndexOptions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,21 @@ namespace MongoDB.Driver
2323
/// </summary>
2424
public class CreateOneIndexOptions
2525
{
26+
// private fields
27+
private CreateIndexCommitQuorum _commitQuorum;
2628
private TimeSpan? _maxTime;
2729

30+
// public properties
31+
/// <summary>
32+
/// Gets or sets the commit quorum.
33+
/// </summary>
34+
/// <value>The commit quorum.</value>
35+
public CreateIndexCommitQuorum CommitQuorum
36+
{
37+
get { return _commitQuorum; }
38+
set { _commitQuorum = value; }
39+
}
40+
2841
/// <summary>
2942
/// Gets or sets the maximum time.
3043
/// </summary>

src/MongoDB.Driver/MongoCollectionImpl.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,7 @@ private CreateIndexesOperation CreateCreateIndexesOperation(IEnumerable<CreateIn
15401540
{
15411541
return new CreateIndexesOperation(_collection._collectionNamespace, requests, _collection._messageEncoderSettings)
15421542
{
1543+
CommitQuorum = options?.CommitQuorum,
15431544
MaxTime = options?.MaxTime,
15441545
WriteConcern = _collection.Settings.WriteConcern
15451546
};

src/MongoDB.Driver/MongoIndexManagerBase.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,11 @@ public virtual Task DropOneAsync(IClientSessionHandle session, string name, Drop
292292

293293
private CreateManyIndexesOptions ToCreateManyIndexesOptions(CreateOneIndexOptions options)
294294
{
295-
return new CreateManyIndexesOptions { MaxTime = options?.MaxTime };
295+
return new CreateManyIndexesOptions
296+
{
297+
CommitQuorum = options?.CommitQuorum,
298+
MaxTime = options?.MaxTime
299+
};
296300
}
297301
}
298302
}

tests/MongoDB.Driver.Core.Tests/Core/Operations/CreateIndexesOperationTests.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,33 @@ public void constructor_should_throw_when_messageEncoderSettings_is_null()
6767
argumentNullException.ParamName.Should().Be("messageEncoderSettings");
6868
}
6969

70+
[SkippableTheory]
71+
[ParameterAttributeData]
72+
public void CommitQuorum_get_and_set_should_work(
73+
[Values(null, 1, 2)] int? w)
74+
{
75+
var subject = new CreateIndexesOperation(_collectionNamespace, Enumerable.Empty<CreateIndexRequest>(), _messageEncoderSettings);
76+
var value = w.HasValue ? CreateIndexCommitQuorum.Create(w.Value) : null;
77+
78+
subject.CommitQuorum = value;
79+
var result = subject.CommitQuorum;
80+
81+
result.Should().BeSameAs(value);
82+
}
83+
7084
[Theory]
7185
[ParameterAttributeData]
7286
public void CreateOperation_should_return_expected_result(
87+
[Values(null, 1, 2)] int? w,
7388
[Values(null, -10000, 0, 1, 42, 9000, 10000, 10001)] int? maxTimeTicks)
7489
{
7590
var requests = new[] { new CreateIndexRequest(new BsonDocument("x", 1)) };
76-
var writeConcern = new WriteConcern(1);
91+
var commitQuorum = w.HasValue ? CreateIndexCommitQuorum.Create(w.Value) : null;
7792
var maxTime = maxTimeTicks == null ? (TimeSpan?)null : TimeSpan.FromTicks(maxTimeTicks.Value);
93+
var writeConcern = new WriteConcern(1);
7894
var subject = new CreateIndexesOperation(_collectionNamespace, requests, _messageEncoderSettings)
7995
{
96+
CommitQuorum = commitQuorum,
8097
MaxTime = maxTime,
8198
WriteConcern = writeConcern
8299
};
@@ -86,10 +103,11 @@ public void CreateOperation_should_return_expected_result(
86103
result.Should().BeOfType<CreateIndexesUsingCommandOperation>();
87104
var operation = (CreateIndexesUsingCommandOperation)result;
88105
operation.CollectionNamespace.Should().BeSameAs(_collectionNamespace);
106+
operation.CommitQuorum.Should().BeSameAs(commitQuorum);
107+
operation.MaxTime.Should().Be(maxTime);
89108
operation.MessageEncoderSettings.Should().BeSameAs(_messageEncoderSettings);
90109
operation.Requests.Should().Equal(requests);
91110
operation.WriteConcern.Should().BeSameAs(writeConcern);
92-
operation.MaxTime.Should().Be(maxTime);
93111
}
94112

95113
[SkippableTheory]

0 commit comments

Comments
 (0)