Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NODE-3183,NODE-3249): bring versioned API impl up to date #2814

Merged
merged 3 commits into from
May 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/cmap/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ function performInitialHandshake(
return;
}

if ('isWritablePrimary' in response) {
// Provide pre-hello-style response document.
response.ismaster = response.isWritablePrimary;
}

const supportedServerErr = checkSupportedServer(response, options);
if (supportedServerErr) {
callback(supportedServerErr);
Expand Down Expand Up @@ -145,7 +150,8 @@ function performInitialHandshake(
}

export interface HandshakeDocument extends Document {
ismaster: boolean;
ismaster?: boolean;
hello?: boolean;
client: ClientMetadata;
compression: string[];
saslSupportedMechs?: string;
Expand All @@ -154,9 +160,10 @@ export interface HandshakeDocument extends Document {
function prepareHandshakeDocument(authContext: AuthContext, callback: Callback<HandshakeDocument>) {
const options = authContext.options;
const compressors = options.compressors ? options.compressors : [];
const { serverApi } = authContext.connection;

const handshakeDoc: HandshakeDocument = {
ismaster: true,
[serverApi?.version ? 'hello' : 'ismaster']: true,
client: options.metadata || makeClientMetadata(options),
compression: compressors
};
Expand Down
12 changes: 1 addition & 11 deletions src/cmap/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
let finalCmd = Object.assign({}, cmd);
const inTransaction = session && (session.inTransaction() || isTransactionCommand(finalCmd));

if (this.serverApi && supportsVersionedApi(cmd, session)) {
if (this.serverApi) {
const { version, strict, deprecationErrors } = this.serverApi;
finalCmd.apiVersion = version;
if (strict != null) finalCmd.apiStrict = strict;
Expand Down Expand Up @@ -666,16 +666,6 @@ function supportsOpMsg(conn: Connection) {
return maxWireVersion(conn) >= 6 && !description.__nodejs_mock_server__;
}

function supportsVersionedApi(cmd: Document, session?: ClientSession) {
const inTransaction = session && (session.inTransaction() || isTransactionCommand(cmd));
// if an API version was declared, add the apiVersion option to every command, except:
// a. only in the initial command of a transaction
// b. only in a Cursor's initiating command, not subsequent getMore commands
return (
(!inTransaction || session?.transaction.isStarting) && !cmd.commitTransaction && !cmd.getMore
);
}

function messageHandler(conn: Connection) {
return function messageHandler(message: BinMsg | Response) {
// always emit the message, in case we are streaming
Expand Down
15 changes: 11 additions & 4 deletions src/sdam/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,18 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {

const connection = monitor[kConnection];
if (connection && !connection.closed) {
const { serverApi } = connection;
const connectTimeoutMS = monitor.options.connectTimeoutMS;
const maxAwaitTimeMS = monitor.options.heartbeatFrequencyMS;
const topologyVersion = monitor[kServer].description.topologyVersion;
const isAwaitable = topologyVersion != null;

const cmd =
isAwaitable && topologyVersion
? { ismaster: true, maxAwaitTimeMS, topologyVersion: makeTopologyVersion(topologyVersion) }
: { ismaster: true };
const cmd = {
[serverApi?.version ? 'hello' : 'ismaster']: true,
...(isAwaitable && topologyVersion
? { maxAwaitTimeMS, topologyVersion: makeTopologyVersion(topologyVersion) }
: {})
};

const options = isAwaitable
? {
Expand All @@ -253,6 +256,10 @@ function checkServer(monitor: Monitor, callback: Callback<Document>) {
failureHandler(err);
return;
}
if ('isWritablePrimary' in isMaster) {
// Provide pre-hello-style response document.
isMaster.ismaster = isMaster.isWritablePrimary;
}

const rttPinger = monitor[kRTTPinger];
const duration =
Expand Down
2 changes: 1 addition & 1 deletion test/disabled/mongos/events.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('EventEmitters (Mongos)', function () {
test: function (done) {
test.server.setMessageHandler(req => {
const doc = req.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
req.reply(Object.assign({}, test.defaultFields));
}
});
Expand Down
6 changes: 3 additions & 3 deletions test/disabled/mongos/retryable_writes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Retryable Writes (Mongos)', function () {
const messageHandler = () => {
return request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(test.defaultFields);
} else if (doc.insert) {
command = doc;
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('Retryable Writes (Mongos)', function () {
const messageHandler = () => {
return request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(test.defaultFields);
} else if (doc.insert) {
insertCount++;
Expand Down Expand Up @@ -147,7 +147,7 @@ describe('Retryable Writes (Mongos)', function () {
const messageHandler = () => {
return request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(test.defaultFields);
} else if (doc.insert) {
insertCount++;
Expand Down
4 changes: 2 additions & 2 deletions test/disabled/mongos/sessions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ describe('Sessions (Mongos)', function () {

test.server.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(
Object.assign({}, mock.DEFAULT_ISMASTER, {
msg: 'isdbgrid',
Expand Down Expand Up @@ -176,7 +176,7 @@ describe('Sessions (Mongos)', function () {
const clusterTime = genClusterTime(Date.now());
test.server.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(
Object.assign({}, mock.DEFAULT_ISMASTER_36, {
msg: 'isdbgrid',
Expand Down
8 changes: 4 additions & 4 deletions test/disabled/mongos_mocks/mixed_seed_list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ describe('Mongos Mixed Seed List (mocks)', function () {

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

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

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

mongos2.setMessageHandler(request => {
var doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[1]);
} else if (doc.insert) {
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
Expand Down
8 changes: 4 additions & 4 deletions test/disabled/mongos_mocks/multiple_proxies.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Mongos Multiple Proxies (mocks)', function () {

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

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

mongos1.setMessageHandler(request => {
var doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[0]);
} else if (doc.insert) {
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
Expand All @@ -131,7 +131,7 @@ describe('Mongos Multiple Proxies (mocks)', function () {
mongos2.setMessageHandler(request => {
setTimeout(() => {
var doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[0]);
} else if (doc.insert) {
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
Expand Down
12 changes: 6 additions & 6 deletions test/disabled/mongos_mocks/proxy_failover.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('Mongos Proxy Failover (mocks)', function () {

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

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

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

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

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

mongos2.setMessageHandler(request => {
var doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[0]);
} else if (doc.insert && currentStep === 0) {
setTimeout(() => request.connection.destroy(), 1600);
Expand Down
6 changes: 3 additions & 3 deletions test/disabled/mongos_mocks/proxy_read_preference.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Mongos Proxy Read Preference (mocks)', function () {
mongos1.setMessageHandler(request => {
var doc = request.document;

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

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

mongos1.setMessageHandler(request => {
var doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[0]);
} else if (doc.$query && doc.$readPreference) {
command = doc;
Expand Down
6 changes: 3 additions & 3 deletions test/disabled/mongos_mocks/single_proxy_connection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Mongos Single Proxy Connection (mocks)', function () {
server.setMessageHandler(request => {
var doc = request.document;

if (doc.ismaster && currentStep === 0) {
if ((doc.ismaster || doc.hello) && currentStep === 0) {
request.reply(serverIsMaster[0]);
currentStep += 1;
} else if (doc.insert && currentStep === 1) {
Expand All @@ -51,7 +51,7 @@ describe('Mongos Single Proxy Connection (mocks)', function () {
stopRespondingPrimary = false;
setTimeout(() => request.connection.destroy(), 1500);
}
} else if (doc.ismaster) {
} else if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[0]);
} else if (doc.insert && currentStep === 2) {
request.reply({ ok: 1, n: doc.documents, lastOp: new Date() });
Expand Down Expand Up @@ -120,7 +120,7 @@ describe('Mongos Single Proxy Connection (mocks)', function () {
server.setMessageHandler(request => {
var doc = request.document;

if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(serverIsMaster[0]);
} else if (doc.find) {
setTimeout(() => {
Expand Down
4 changes: 2 additions & 2 deletions test/disabled/pool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('Pool (unit)', function () {
it('should throw a MongoWriteConcernError when a writeConcernError is present', function (done) {
test.server.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
return request.reply(Object.assign({}, mock.DEFAULT_ISMASTER));
} else if (doc.insert) {
return request.reply({
Expand Down Expand Up @@ -53,7 +53,7 @@ describe('Pool (unit)', function () {
it('should not allow overriding `slaveOk` when connected to a mongos', function (done) {
test.server.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
request.reply(Object.assign({ msg: 'isdbgrid' }, mock.DEFAULT_ISMASTER));
} else if (doc.insert) {
request.reply({ ok: 1 });
Expand Down
4 changes: 2 additions & 2 deletions test/disabled/replset/auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('Auth (ReplSet)', function () {

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

test.firstSecondaryServer.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
timeoutIds.push(setTimeout(() => request.reply(test.firstSecondaryStates[0]), 2000));
} else if (doc.saslStart) {
finish();
Expand Down
4 changes: 2 additions & 2 deletions test/disabled/replset/compression.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ describe('Compression (ReplSet)', function () {
const compressionData = [];
test.primaryServer.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
compressionData.push(doc.compression);
request.reply(test.primaryStates[0]);
}
});

test.firstSecondaryServer.setMessageHandler(request => {
const doc = request.document;
if (doc.ismaster) {
if (doc.ismaster || doc.hello) {
compressionData.push(doc.compression);
request.reply(test.firstSecondaryStates[0]);
}
Expand Down
Loading