Skip to content

Commit 2819374

Browse files
updates from code review on 6.x branch
1 parent 018fd02 commit 2819374

File tree

10 files changed

+88
-25
lines changed

10 files changed

+88
-25
lines changed

src/cmap/connect.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import {
2525
type ConnectionOptions,
2626
CryptoConnection
2727
} from './connection';
28-
import { addContainerMetadata } from './handshake/client_metadata';
2928
import {
3029
MAX_SUPPORTED_SERVER_VERSION,
3130
MAX_SUPPORTED_WIRE_VERSION,
@@ -197,7 +196,7 @@ export async function prepareHandshakeDocument(
197196
const options = authContext.options;
198197
const compressors = options.compressors ? options.compressors : [];
199198
const { serverApi } = authContext.connection;
200-
const clientMetadata = await addContainerMetadata(options.metadata);
199+
const clientMetadata = await options.extendedMetadata;
201200

202201
const handshakeDoc: HandshakeDocument = {
203202
[serverApi?.version ? 'hello' : LEGACY_HELLO_COMMAND]: 1,

src/cmap/connection.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ export interface ConnectionOptions
133133
socketTimeoutMS?: number;
134134
cancellationToken?: CancellationToken;
135135
metadata: ClientMetadata;
136+
/** @internal */
137+
extendedMetadata: Promise<Document>;
136138
}
137139

138140
/** @internal */

src/cmap/handshake/client_metadata.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,15 @@ export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMe
157157
return metadataDocument.toObject() as ClientMetadata;
158158
}
159159

160-
let isDocker: boolean;
161-
let dockerPromise: Promise<void>;
160+
let dockerPromise: Promise<boolean>;
162161
/** @internal */
163162
async function getContainerMetadata() {
164163
const containerMetadata: Record<string, any> = {};
165-
if (isDocker == null) {
166-
dockerPromise ??= fs.access('/.dockerenv');
167-
try {
168-
await dockerPromise;
169-
isDocker = true;
170-
} catch {
171-
isDocker = false;
172-
}
173-
}
164+
dockerPromise ??= fs.access('/.dockerenv').then(
165+
() => true,
166+
() => false
167+
);
168+
const isDocker = await dockerPromise;
174169

175170
const { KUBERNETES_SERVICE_HOST = '' } = process.env;
176171
const isKubernetes = KUBERNETES_SERVICE_HOST.length > 0 ? true : false;

src/connection_string.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { URLSearchParams } from 'url';
66
import type { Document } from './bson';
77
import { MongoCredentials } from './cmap/auth/mongo_credentials';
88
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers';
9-
import { makeClientMetadata } from './cmap/handshake/client_metadata';
9+
import { addContainerMetadata, makeClientMetadata } from './cmap/handshake/client_metadata';
1010
import { Compressor, type CompressorName } from './cmap/wire_protocol/compression';
1111
import { Encrypter } from './encrypter';
1212
import {
@@ -550,6 +550,9 @@ export function parseOptions(
550550
);
551551

552552
mongoOptions.metadata = makeClientMetadata(mongoOptions);
553+
mongoOptions.extendedMetadata = addContainerMetadata(mongoOptions.metadata).catch(() => {
554+
/* rejections will be handled later */
555+
});
553556

554557
return mongoOptions;
555558
}

src/mongo_client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,8 @@ export interface MongoOptions
757757
writeConcern: WriteConcern;
758758
dbName: string;
759759
metadata: ClientMetadata;
760+
/** @internal */
761+
extendedMetadata: Promise<Document>;
760762
/**
761763
* @deprecated This option will be removed in the next major version.
762764
*/

src/sdam/topology.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
143143
directConnection: boolean;
144144
loadBalanced: boolean;
145145
metadata: ClientMetadata;
146+
extendedMetadata: Promise<Document>;
146147
/** MongoDB server API version */
147148
serverApi?: ServerApi;
148149
[featureFlag: symbol]: any;

test/integration/connection-monitoring-and-pooling/connection.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { expect } from 'chai';
22

33
import {
4+
addContainerMetadata,
45
connect,
56
Connection,
67
type ConnectionOptions,
@@ -36,7 +37,8 @@ describe('Connection', function () {
3637
const connectOptions: Partial<ConnectionOptions> = {
3738
connectionType: Connection,
3839
...this.configuration.options,
39-
metadata: makeClientMetadata({ driverInfo: {} })
40+
metadata: makeClientMetadata({ driverInfo: {} }),
41+
extendedMetadata: addContainerMetadata(makeClientMetadata({ driverInfo: {} }))
4042
};
4143

4244
connect(connectOptions as any as ConnectionOptions, (err, conn) => {
@@ -60,7 +62,8 @@ describe('Connection', function () {
6062
connectionType: Connection,
6163
monitorCommands: true,
6264
...this.configuration.options,
63-
metadata: makeClientMetadata({ driverInfo: {} })
65+
metadata: makeClientMetadata({ driverInfo: {} }),
66+
extendedMetadata: addContainerMetadata(makeClientMetadata({ driverInfo: {} }))
6467
};
6568

6669
connect(connectOptions as any as ConnectionOptions, (err, conn) => {

test/tools/cmap_spec_runner.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { clearTimeout, setTimeout } from 'timers';
44
import { promisify } from 'util';
55

66
import {
7+
addContainerMetadata,
78
CMAP_EVENTS,
89
type Connection,
910
ConnectionPool,
@@ -371,6 +372,7 @@ async function runCmapTest(test: CmapTest, threadContext: ThreadContext) {
371372
}
372373

373374
const metadata = makeClientMetadata({ appName: poolOptions.appName, driverInfo: {} });
375+
const extendedMetadata = addContainerMetadata(metadata);
374376
delete poolOptions.appName;
375377

376378
const operations = test.operations;
@@ -382,7 +384,12 @@ async function runCmapTest(test: CmapTest, threadContext: ThreadContext) {
382384
const mainThread = threadContext.getThread(MAIN_THREAD_KEY);
383385
mainThread.start();
384386

385-
threadContext.createPool({ ...poolOptions, metadata, minPoolSizeCheckFrequencyMS });
387+
threadContext.createPool({
388+
...poolOptions,
389+
metadata,
390+
extendedMetadata,
391+
minPoolSizeCheckFrequencyMS
392+
});
386393
// yield control back to the event loop so that the ConnectionPoolCreatedEvent
387394
// has a chance to be fired before any synchronously-emitted events from
388395
// the queued operations

test/unit/cmap/connect.test.ts

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { expect } from 'chai';
22
import { promisify } from 'util';
33

44
import {
5+
addContainerMetadata,
56
CancellationToken,
67
type ClientMetadata,
78
connect,
@@ -24,6 +25,7 @@ const CONNECT_DEFAULTS = {
2425
generation: 1,
2526
monitorCommands: false,
2627
metadata: {} as ClientMetadata,
28+
extendedMetadata: addContainerMetadata({} as ClientMetadata),
2729
loadBalanced: false
2830
};
2931

@@ -212,13 +214,17 @@ describe('Connect Tests', function () {
212214
const cachedEnv = process.env;
213215

214216
context('when only kubernetes is present', () => {
215-
const authContext = {
216-
connection: {},
217-
options: { ...CONNECT_DEFAULTS }
218-
};
217+
let authContext;
219218

220219
beforeEach(() => {
221220
process.env.KUBERNETES_SERVICE_HOST = 'I exist';
221+
authContext = {
222+
connection: {},
223+
options: {
224+
...CONNECT_DEFAULTS,
225+
extendedMetadata: addContainerMetadata({} as ClientMetadata)
226+
}
227+
};
222228
});
223229

224230
afterEach(() => {
@@ -227,6 +233,7 @@ describe('Connect Tests', function () {
227233
} else {
228234
delete process.env.KUBERNETES_SERVICE_HOST;
229235
}
236+
authContext = {};
230237
});
231238

232239
it(`should include { orchestrator: 'kubernetes'} in client.env.container`, async () => {
@@ -238,16 +245,36 @@ describe('Connect Tests', function () {
238245
const handshakeDocument = await prepareHandshakeDocument(authContext);
239246
expect(handshakeDocument.client.env).to.not.have.property('name');
240247
});
248+
249+
context('when 512 byte size limit is exceeded', async () => {
250+
it(`should not 'env' property in client`, async () => {
251+
// make metadata = 507 bytes, so it takes up entire LimitedSizeDocument
252+
const longAppName = 's'.repeat(493);
253+
const longAuthContext = {
254+
connection: {},
255+
options: {
256+
...CONNECT_DEFAULTS,
257+
extendedMetadata: addContainerMetadata({ appName: longAppName })
258+
}
259+
};
260+
const handshakeDocument = await prepareHandshakeDocument(longAuthContext);
261+
expect(handshakeDocument.client).to.not.have.property('env');
262+
});
263+
});
241264
});
242265

243266
context('when kubernetes and FAAS are both present', () => {
244-
const authContext = {
245-
connection: {},
246-
options: { ...CONNECT_DEFAULTS, metadata: { env: { name: 'aws.lambda' } } }
247-
};
267+
let authContext;
248268

249269
beforeEach(() => {
250270
process.env.KUBERNETES_SERVICE_HOST = 'I exist';
271+
authContext = {
272+
connection: {},
273+
options: {
274+
...CONNECT_DEFAULTS,
275+
extendedMetadata: addContainerMetadata({ env: { name: 'aws.lambda' } })
276+
}
277+
};
251278
});
252279

253280
afterEach(() => {
@@ -256,6 +283,7 @@ describe('Connect Tests', function () {
256283
} else {
257284
delete process.env.KUBERNETES_SERVICE_HOST;
258285
}
286+
authContext = {};
259287
});
260288

261289
it(`should include { orchestrator: 'kubernetes'} in client.env.container`, async () => {
@@ -267,6 +295,26 @@ describe('Connect Tests', function () {
267295
const handshakeDocument = await prepareHandshakeDocument(authContext);
268296
expect(handshakeDocument.client.env.name).to.equal('aws.lambda');
269297
});
298+
299+
context('when 512 byte size limit is exceeded', async () => {
300+
it(`should not have 'container' property in client.env`, async () => {
301+
// make metadata = 507 bytes, so it takes up entire LimitedSizeDocument
302+
const longAppName = 's'.repeat(447);
303+
const longAuthContext = {
304+
connection: {},
305+
options: {
306+
...CONNECT_DEFAULTS,
307+
extendedMetadata: {
308+
appName: longAppName,
309+
env: { name: 'aws.lambda' }
310+
} as unknown as Promise<Document>
311+
}
312+
};
313+
const handshakeDocument = await prepareHandshakeDocument(longAuthContext);
314+
expect(handshakeDocument.client.env.name).to.equal('aws.lambda');
315+
expect(handshakeDocument.client.env).to.not.have.property('container');
316+
});
317+
});
270318
});
271319

272320
context('when container nor FAAS env is not present (empty string case)', () => {

test/unit/cmap/connection_pool.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ describe('Connection Pool', function () {
2222
},
2323
s: {
2424
authProviders: new MongoClientAuthProviders()
25+
},
26+
options: {
27+
extendedMetadata: {}
2528
}
2629
}
2730
}

0 commit comments

Comments
 (0)