Skip to content

Commit cd3b73a

Browse files
authored
fix(NODE-3183,NODE-3249): bring versioned API impl up to date (#2814)
1 parent 0b636ba commit cd3b73a

File tree

79 files changed

+490
-585
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+490
-585
lines changed

src/cmap/connect.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ function performInitialHandshake(
108108
return;
109109
}
110110

111+
if ('isWritablePrimary' in response) {
112+
// Provide pre-hello-style response document.
113+
response.ismaster = response.isWritablePrimary;
114+
}
115+
111116
const supportedServerErr = checkSupportedServer(response, options);
112117
if (supportedServerErr) {
113118
callback(supportedServerErr);
@@ -145,7 +150,8 @@ function performInitialHandshake(
145150
}
146151

147152
export interface HandshakeDocument extends Document {
148-
ismaster: boolean;
153+
ismaster?: boolean;
154+
hello?: boolean;
149155
client: ClientMetadata;
150156
compression: string[];
151157
saslSupportedMechs?: string;
@@ -154,9 +160,10 @@ export interface HandshakeDocument extends Document {
154160
function prepareHandshakeDocument(authContext: AuthContext, callback: Callback<HandshakeDocument>) {
155161
const options = authContext.options;
156162
const compressors = options.compressors ? options.compressors : [];
163+
const { serverApi } = authContext.connection;
157164

158165
const handshakeDoc: HandshakeDocument = {
159-
ismaster: true,
166+
[serverApi?.version ? 'hello' : 'ismaster']: true,
160167
client: options.metadata || makeClientMetadata(options),
161168
compression: compressors
162169
};

src/cmap/connection.ts

+1-11
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
350350
let finalCmd = Object.assign({}, cmd);
351351
const inTransaction = session && (session.inTransaction() || isTransactionCommand(finalCmd));
352352

353-
if (this.serverApi && supportsVersionedApi(cmd, session)) {
353+
if (this.serverApi) {
354354
const { version, strict, deprecationErrors } = this.serverApi;
355355
finalCmd.apiVersion = version;
356356
if (strict != null) finalCmd.apiStrict = strict;
@@ -676,16 +676,6 @@ function supportsOpMsg(conn: Connection) {
676676
return maxWireVersion(conn) >= 6 && !description.__nodejs_mock_server__;
677677
}
678678

679-
function supportsVersionedApi(cmd: Document, session?: ClientSession) {
680-
const inTransaction = session && (session.inTransaction() || isTransactionCommand(cmd));
681-
// if an API version was declared, add the apiVersion option to every command, except:
682-
// a. only in the initial command of a transaction
683-
// b. only in a Cursor's initiating command, not subsequent getMore commands
684-
return (
685-
(!inTransaction || session?.transaction.isStarting) && !cmd.commitTransaction && !cmd.getMore
686-
);
687-
}
688-
689679
function messageHandler(conn: Connection) {
690680
return function messageHandler(message: BinMsg | Response) {
691681
// always emit the message, in case we are streaming

src/sdam/monitor.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -227,15 +227,18 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
227227

228228
const connection = monitor[kConnection];
229229
if (connection && !connection.closed) {
230+
const { serverApi } = connection;
230231
const connectTimeoutMS = monitor.options.connectTimeoutMS;
231232
const maxAwaitTimeMS = monitor.options.heartbeatFrequencyMS;
232233
const topologyVersion = monitor[kServer].description.topologyVersion;
233234
const isAwaitable = topologyVersion != null;
234235

235-
const cmd =
236-
isAwaitable && topologyVersion
237-
? { ismaster: true, maxAwaitTimeMS, topologyVersion: makeTopologyVersion(topologyVersion) }
238-
: { ismaster: true };
236+
const cmd = {
237+
[serverApi?.version ? 'hello' : 'ismaster']: true,
238+
...(isAwaitable && topologyVersion
239+
? { maxAwaitTimeMS, topologyVersion: makeTopologyVersion(topologyVersion) }
240+
: {})
241+
};
239242

240243
const options = isAwaitable
241244
? {
@@ -259,6 +262,10 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
259262
failureHandler(err);
260263
return;
261264
}
265+
if ('isWritablePrimary' in isMaster) {
266+
// Provide pre-hello-style response document.
267+
isMaster.ismaster = isMaster.isWritablePrimary;
268+
}
262269

263270
const rttPinger = monitor[kRTTPinger];
264271
const duration =

test/disabled/mongos/events.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ describe('EventEmitters (Mongos)', function () {
2020
test: function (done) {
2121
test.server.setMessageHandler(req => {
2222
const doc = req.document;
23-
if (doc.ismaster) {
23+
if (doc.ismaster || doc.hello) {
2424
req.reply(Object.assign({}, test.defaultFields));
2525
}
2626
});

test/disabled/mongos/retryable_writes.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('Retryable Writes (Mongos)', function () {
3636
const messageHandler = () => {
3737
return request => {
3838
const doc = request.document;
39-
if (doc.ismaster) {
39+
if (doc.ismaster || doc.hello) {
4040
request.reply(test.defaultFields);
4141
} else if (doc.insert) {
4242
command = doc;
@@ -90,7 +90,7 @@ describe('Retryable Writes (Mongos)', function () {
9090
const messageHandler = () => {
9191
return request => {
9292
const doc = request.document;
93-
if (doc.ismaster) {
93+
if (doc.ismaster || doc.hello) {
9494
request.reply(test.defaultFields);
9595
} else if (doc.insert) {
9696
insertCount++;
@@ -147,7 +147,7 @@ describe('Retryable Writes (Mongos)', function () {
147147
const messageHandler = () => {
148148
return request => {
149149
const doc = request.document;
150-
if (doc.ismaster) {
150+
if (doc.ismaster || doc.hello) {
151151
request.reply(test.defaultFields);
152152
} else if (doc.insert) {
153153
insertCount++;

test/disabled/mongos/sessions.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ describe('Sessions (Mongos)', function () {
9292

9393
test.server.setMessageHandler(request => {
9494
const doc = request.document;
95-
if (doc.ismaster) {
95+
if (doc.ismaster || doc.hello) {
9696
request.reply(
9797
Object.assign({}, mock.DEFAULT_ISMASTER, {
9898
msg: 'isdbgrid',
@@ -176,7 +176,7 @@ describe('Sessions (Mongos)', function () {
176176
const clusterTime = genClusterTime(Date.now());
177177
test.server.setMessageHandler(request => {
178178
const doc = request.document;
179-
if (doc.ismaster) {
179+
if (doc.ismaster || doc.hello) {
180180
request.reply(
181181
Object.assign({}, mock.DEFAULT_ISMASTER_36, {
182182
msg: 'isdbgrid',

test/disabled/mongos_mocks/mixed_seed_list.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ describe('Mongos Mixed Seed List (mocks)', function () {
4848

4949
mongos1.setMessageHandler(request => {
5050
var doc = request.document;
51-
if (doc.ismaster) {
51+
if (doc.ismaster || doc.hello) {
5252
request.reply(serverIsMaster[0]);
5353
} else if (doc.insert) {
5454
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -57,7 +57,7 @@ describe('Mongos Mixed Seed List (mocks)', function () {
5757

5858
mongos2.setMessageHandler(request => {
5959
var doc = request.document;
60-
if (doc.ismaster) {
60+
if (doc.ismaster || doc.hello) {
6161
request.reply(serverIsMaster[1]);
6262
} else if (doc.insert) {
6363
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -124,7 +124,7 @@ describe('Mongos Mixed Seed List (mocks)', function () {
124124

125125
mongos1.setMessageHandler(request => {
126126
var doc = request.document;
127-
if (doc.ismaster) {
127+
if (doc.ismaster || doc.hello) {
128128
request.reply(serverIsMaster[0]);
129129
} else if (doc.insert) {
130130
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -133,7 +133,7 @@ describe('Mongos Mixed Seed List (mocks)', function () {
133133

134134
mongos2.setMessageHandler(request => {
135135
var doc = request.document;
136-
if (doc.ismaster) {
136+
if (doc.ismaster || doc.hello) {
137137
request.reply(serverIsMaster[1]);
138138
} else if (doc.insert) {
139139
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });

test/disabled/mongos_mocks/multiple_proxies.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('Mongos Multiple Proxies (mocks)', function () {
3636

3737
mongos1.setMessageHandler(request => {
3838
var doc = request.document;
39-
if (doc.ismaster) {
39+
if (doc.ismaster || doc.hello) {
4040
request.reply(serverIsMaster[0]);
4141
} else if (doc.insert) {
4242
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -45,7 +45,7 @@ describe('Mongos Multiple Proxies (mocks)', function () {
4545

4646
mongos2.setMessageHandler(request => {
4747
var doc = request.document;
48-
if (doc.ismaster) {
48+
if (doc.ismaster || doc.hello) {
4949
request.reply(serverIsMaster[0]);
5050
} else if (doc.insert) {
5151
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -121,7 +121,7 @@ describe('Mongos Multiple Proxies (mocks)', function () {
121121

122122
mongos1.setMessageHandler(request => {
123123
var doc = request.document;
124-
if (doc.ismaster) {
124+
if (doc.ismaster || doc.hello) {
125125
request.reply(serverIsMaster[0]);
126126
} else if (doc.insert) {
127127
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -131,7 +131,7 @@ describe('Mongos Multiple Proxies (mocks)', function () {
131131
mongos2.setMessageHandler(request => {
132132
setTimeout(() => {
133133
var doc = request.document;
134-
if (doc.ismaster) {
134+
if (doc.ismaster || doc.hello) {
135135
request.reply(serverIsMaster[0]);
136136
} else if (doc.insert) {
137137
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });

test/disabled/mongos_mocks/proxy_failover.test.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe('Mongos Proxy Failover (mocks)', function () {
3232

3333
mongos1.setMessageHandler(request => {
3434
var doc = request.document;
35-
if (doc.ismaster) {
35+
if (doc.ismaster || doc.hello) {
3636
request.reply(serverIsMaster[0]);
3737
} else if (doc.insert) {
3838
mongos1.destroy();
@@ -42,7 +42,7 @@ describe('Mongos Proxy Failover (mocks)', function () {
4242

4343
mongos2.setMessageHandler(request => {
4444
var doc = request.document;
45-
if (doc.ismaster) {
45+
if (doc.ismaster || doc.hello) {
4646
request.reply(serverIsMaster[0]);
4747
} else if (doc.insert) {
4848
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -106,7 +106,7 @@ describe('Mongos Proxy Failover (mocks)', function () {
106106

107107
mongos1.setMessageHandler(request => {
108108
var doc = request.document;
109-
if (doc.ismaster) {
109+
if (doc.ismaster || doc.hello) {
110110
request.reply(serverIsMaster[0]);
111111
} else if (doc.insert && currentStep === 0) {
112112
setTimeout(() => request.connection.destroy(), 1600);
@@ -117,7 +117,7 @@ describe('Mongos Proxy Failover (mocks)', function () {
117117

118118
mongos2.setMessageHandler(request => {
119119
var doc = request.document;
120-
if (doc.ismaster) {
120+
if (doc.ismaster || doc.hello) {
121121
request.reply(serverIsMaster[0]);
122122
} else if (doc.insert) {
123123
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -201,7 +201,7 @@ describe('Mongos Proxy Failover (mocks)', function () {
201201

202202
mongos1.setMessageHandler(request => {
203203
var doc = request.document;
204-
if (doc.ismaster) {
204+
if (doc.ismaster || doc.hello) {
205205
request.reply(serverIsMaster[0]);
206206
} else if (doc.insert && currentStep === 0) {
207207
setTimeout(() => request.connection.destroy(), 1600);
@@ -212,7 +212,7 @@ describe('Mongos Proxy Failover (mocks)', function () {
212212

213213
mongos2.setMessageHandler(request => {
214214
var doc = request.document;
215-
if (doc.ismaster) {
215+
if (doc.ismaster || doc.hello) {
216216
request.reply(serverIsMaster[0]);
217217
} else if (doc.insert && currentStep === 0) {
218218
setTimeout(() => request.connection.destroy(), 1600);

test/disabled/mongos_mocks/proxy_read_preference.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('Mongos Proxy Read Preference (mocks)', function () {
3636
mongos1.setMessageHandler(request => {
3737
var doc = request.document;
3838

39-
if (doc.ismaster) {
39+
if (doc.ismaster || doc.hello) {
4040
request.reply(serverIsMaster[0]);
4141
} else if (doc.$query && doc.$readPreference) {
4242
command = doc;
@@ -115,7 +115,7 @@ describe('Mongos Proxy Read Preference (mocks)', function () {
115115

116116
mongos1.setMessageHandler(request => {
117117
var doc = request.document;
118-
if (doc.ismaster) {
118+
if (doc.ismaster || doc.hello) {
119119
request.reply(serverIsMaster[0]);
120120
} else if (doc.$query && doc.$readPreference) {
121121
command = doc;
@@ -195,7 +195,7 @@ describe('Mongos Proxy Read Preference (mocks)', function () {
195195

196196
mongos1.setMessageHandler(request => {
197197
var doc = request.document;
198-
if (doc.ismaster) {
198+
if (doc.ismaster || doc.hello) {
199199
request.reply(serverIsMaster[0]);
200200
} else if (doc.$query && doc.$readPreference) {
201201
command = doc;

test/disabled/mongos_mocks/single_proxy_connection.test.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('Mongos Single Proxy Connection (mocks)', function () {
4141
server.setMessageHandler(request => {
4242
var doc = request.document;
4343

44-
if (doc.ismaster && currentStep === 0) {
44+
if ((doc.ismaster || doc.hello) && currentStep === 0) {
4545
request.reply(serverIsMaster[0]);
4646
currentStep += 1;
4747
} else if (doc.insert && currentStep === 1) {
@@ -51,7 +51,7 @@ describe('Mongos Single Proxy Connection (mocks)', function () {
5151
stopRespondingPrimary = false;
5252
setTimeout(() => request.connection.destroy(), 1500);
5353
}
54-
} else if (doc.ismaster) {
54+
} else if (doc.ismaster || doc.hello) {
5555
request.reply(serverIsMaster[0]);
5656
} else if (doc.insert && currentStep === 2) {
5757
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
@@ -120,7 +120,7 @@ describe('Mongos Single Proxy Connection (mocks)', function () {
120120
server.setMessageHandler(request => {
121121
var doc = request.document;
122122

123-
if (doc.ismaster) {
123+
if (doc.ismaster || doc.hello) {
124124
request.reply(serverIsMaster[0]);
125125
} else if (doc.find) {
126126
setTimeout(() => {

test/disabled/pool.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('Pool (unit)', function () {
1818
it('should throw a MongoWriteConcernError when a writeConcernError is present', function (done) {
1919
test.server.setMessageHandler(request => {
2020
const doc = request.document;
21-
if (doc.ismaster) {
21+
if (doc.ismaster || doc.hello) {
2222
return request.reply(Object.assign({}, mock.DEFAULT_ISMASTER));
2323
} else if (doc.insert) {
2424
return request.reply({
@@ -53,7 +53,7 @@ describe('Pool (unit)', function () {
5353
it('should not allow overriding `slaveOk` when connected to a mongos', function (done) {
5454
test.server.setMessageHandler(request => {
5555
const doc = request.document;
56-
if (doc.ismaster) {
56+
if (doc.ismaster || doc.hello) {
5757
request.reply(Object.assign({ msg: 'isdbgrid' }, mock.DEFAULT_ISMASTER));
5858
} else if (doc.insert) {
5959
request.reply({ ok: 1 });

test/disabled/replset/auth.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('Auth (ReplSet)', function () {
3636

3737
test.primaryServer.setMessageHandler(request => {
3838
const doc = request.document;
39-
if (doc.ismaster) {
39+
if (doc.ismaster || doc.hello) {
4040
setTimeout(() => request.reply(test.primaryStates[0]));
4141
} else if (doc.saslStart) {
4242
finish();
@@ -45,7 +45,7 @@ describe('Auth (ReplSet)', function () {
4545

4646
test.firstSecondaryServer.setMessageHandler(request => {
4747
const doc = request.document;
48-
if (doc.ismaster) {
48+
if (doc.ismaster || doc.hello) {
4949
timeoutIds.push(setTimeout(() => request.reply(test.firstSecondaryStates[0]), 2000));
5050
} else if (doc.saslStart) {
5151
finish();

test/disabled/replset/compression.test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ describe('Compression (ReplSet)', function () {
1515
const compressionData = [];
1616
test.primaryServer.setMessageHandler(request => {
1717
const doc = request.document;
18-
if (doc.ismaster) {
18+
if (doc.ismaster || doc.hello) {
1919
compressionData.push(doc.compression);
2020
request.reply(test.primaryStates[0]);
2121
}
2222
});
2323

2424
test.firstSecondaryServer.setMessageHandler(request => {
2525
const doc = request.document;
26-
if (doc.ismaster) {
26+
if (doc.ismaster || doc.hello) {
2727
compressionData.push(doc.compression);
2828
request.reply(test.firstSecondaryStates[0]);
2929
}

0 commit comments

Comments
 (0)