Skip to content

Commit b59c5ce

Browse files
feat(NODE-5994)!: Remove metadata-related properties from public driver API (#4716)
1 parent fb2824f commit b59c5ce

File tree

14 files changed

+316
-412
lines changed

14 files changed

+316
-412
lines changed

src/cmap/connect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ export async function prepareHandshakeDocument(
222222
const options = authContext.options;
223223
const compressors = options.compressors ? options.compressors : [];
224224
const { serverApi } = authContext.connection;
225-
const clientMetadata: Document = await options.extendedMetadata;
225+
const clientMetadata: Document = await options.metadata;
226226

227227
const handshakeDoc: HandshakeDocument = {
228228
[serverApi?.version || options.loadBalanced === true ? 'hello' : LEGACY_HELLO_COMMAND]: 1,

src/cmap/connection.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,8 @@ export interface ConnectionOptions
140140
socketTimeoutMS?: number;
141141
/** @internal */
142142
cancellationToken?: CancellationToken;
143-
metadata: ClientMetadata;
144143
/** @internal */
145-
extendedMetadata: Promise<Document>;
144+
metadata: Promise<ClientMetadata>;
146145
/** @internal */
147146
mongoLogger?: MongoLogger | undefined;
148147
}

src/cmap/connection_pool.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -601,17 +601,17 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
601601
}
602602

603603
private createConnection(callback: Callback<Connection>) {
604-
// Note that metadata and extendedMetadata may have changed on the client but have
605-
// been frozen here, so we pull the extendedMetadata promise always from the client
606-
// no mattter what options were set at the construction of the pool.
604+
// Note that metadata may have changed on the client but have
605+
// been frozen here, so we pull the metadata promise always from the client
606+
// no matter what options were set at the construction of the pool.
607607
const connectOptions: ConnectionOptions = {
608608
...this.options,
609609
id: this.connectionCounter.next().value,
610610
generation: this.generation,
611611
cancellationToken: this.cancellationToken,
612612
mongoLogger: this.mongoLogger,
613613
authProviders: this.server.topology.client.s.authProviders,
614-
extendedMetadata: this.server.topology.client.options.extendedMetadata
614+
metadata: this.server.topology.client.options.metadata
615615
};
616616

617617
this.pending++;

src/cmap/handshake/client_metadata.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ export function isDriverInfoEqual(info1: DriverInfo, info2: DriverInfo): boolean
2727
}
2828

2929
/**
30-
* @public
31-
* @deprecated This interface will be made internal in the next major release.
30+
* @internal
3231
* @see https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.md#hello-command
3332
*/
3433
export interface ClientMetadata {
@@ -48,11 +47,14 @@ export interface ClientMetadata {
4847
};
4948
/** FaaS environment information */
5049
env?: {
51-
name: 'aws.lambda' | 'gcp.func' | 'azure.func' | 'vercel';
50+
name?: 'aws.lambda' | 'gcp.func' | 'azure.func' | 'vercel';
5251
timeout_sec?: Int32;
5352
memory_mb?: Int32;
5453
region?: string;
55-
url?: string;
54+
container?: {
55+
runtime?: string;
56+
orchestrator?: string;
57+
};
5658
};
5759
}
5860

@@ -103,10 +105,10 @@ type MakeClientMetadataOptions = Pick<MongoOptions, 'appName'>;
103105
* 3. Omit the `env` document entirely.
104106
* 4. Truncate `platform`. -- special we do not truncate this field
105107
*/
106-
export function makeClientMetadata(
108+
export async function makeClientMetadata(
107109
driverInfoList: DriverInfo[],
108110
{ appName = '' }: MakeClientMetadataOptions
109-
): ClientMetadata {
111+
): Promise<ClientMetadata> {
110112
const metadataDocument = new LimitedSizeDocument(512);
111113

112114
// Add app name first, it must be sent
@@ -178,19 +180,21 @@ export function makeClientMetadata(
178180
}
179181
}
180182
}
181-
return metadataDocument.toObject() as ClientMetadata;
183+
return await addContainerMetadata(metadataDocument.toObject() as ClientMetadata);
182184
}
183185

184186
let dockerPromise: Promise<boolean>;
187+
type ContainerMetadata = NonNullable<NonNullable<ClientMetadata['env']>['container']>;
185188
/** @internal */
186-
async function getContainerMetadata() {
187-
const containerMetadata: Record<string, any> = {};
189+
async function getContainerMetadata(): Promise<ContainerMetadata> {
188190
dockerPromise ??= fileIsAccessible('/.dockerenv');
189191
const isDocker = await dockerPromise;
190192

191193
const { KUBERNETES_SERVICE_HOST = '' } = process.env;
192194
const isKubernetes = KUBERNETES_SERVICE_HOST.length > 0 ? true : false;
193195

196+
const containerMetadata: ContainerMetadata = {};
197+
194198
if (isDocker) containerMetadata.runtime = 'docker';
195199
if (isKubernetes) containerMetadata.orchestrator = 'kubernetes';
196200

@@ -202,15 +206,16 @@ async function getContainerMetadata() {
202206
* Re-add each metadata value.
203207
* Attempt to add new env container metadata, but keep old data if it does not fit.
204208
*/
205-
export async function addContainerMetadata(
206-
originalMetadata: ClientMetadata
207-
): Promise<ClientMetadata> {
209+
async function addContainerMetadata(originalMetadata: ClientMetadata): Promise<ClientMetadata> {
208210
const containerMetadata = await getContainerMetadata();
209211
if (Object.keys(containerMetadata).length === 0) return originalMetadata;
210212

211213
const extendedMetadata = new LimitedSizeDocument(512);
212214

213-
const extendedEnvMetadata = { ...originalMetadata?.env, container: containerMetadata };
215+
const extendedEnvMetadata: NonNullable<ClientMetadata['env']> = {
216+
...originalMetadata?.env,
217+
container: containerMetadata
218+
};
214219

215220
for (const [key, val] of Object.entries(originalMetadata)) {
216221
if (key !== 'env') {

src/mongo_client.ts

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { AuthMechanism } from './cmap/auth/providers';
1616
import type { LEGAL_TCP_SOCKET_OPTIONS, LEGAL_TLS_SOCKET_OPTIONS } from './cmap/connect';
1717
import type { Connection } from './cmap/connection';
1818
import {
19-
addContainerMetadata,
2019
type ClientMetadata,
2120
isDriverInfoEqual,
2221
makeClientMetadata
@@ -407,31 +406,12 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
407406
* The consolidate, parsed, transformed and merged options.
408407
*/
409408
public readonly options: Readonly<
410-
Omit<
411-
MongoOptions,
412-
| 'monitorCommands'
413-
| 'ca'
414-
| 'crl'
415-
| 'key'
416-
| 'cert'
417-
| 'driverInfo'
418-
| 'additionalDriverInfo'
419-
| 'metadata'
420-
| 'extendedMetadata'
421-
>
409+
Omit<MongoOptions, 'monitorCommands' | 'ca' | 'crl' | 'key' | 'cert' | 'driverInfo'>
422410
> &
423-
Pick<
424-
MongoOptions,
425-
| 'monitorCommands'
426-
| 'ca'
427-
| 'crl'
428-
| 'key'
429-
| 'cert'
430-
| 'driverInfo'
431-
| 'additionalDriverInfo'
432-
| 'metadata'
433-
| 'extendedMetadata'
434-
>;
411+
Pick<MongoOptions, 'monitorCommands' | 'ca' | 'crl' | 'key' | 'cert' | 'driverInfo'> & {
412+
/** @internal */
413+
metadata: Promise<ClientMetadata>;
414+
};
435415

436416
private driverInfoList: DriverInfo[] = [];
437417

@@ -502,10 +482,9 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
502482
if (isDuplicateDriverInfo) return;
503483

504484
this.driverInfoList.push(driverInfo);
505-
this.options.metadata = makeClientMetadata(this.driverInfoList, this.options);
506-
this.options.extendedMetadata = addContainerMetadata(this.options.metadata)
485+
this.options.metadata = makeClientMetadata(this.driverInfoList, this.options)
507486
.then(undefined, squashError)
508-
.then(result => result ?? {}); // ensure Promise<Document>
487+
.then(result => result ?? ({} as ClientMetadata)); // ensure Promise<Document>
509488
}
510489

511490
/** @internal */
@@ -1099,12 +1078,8 @@ export interface MongoOptions
10991078
compressors: CompressorName[];
11001079
writeConcern: WriteConcern;
11011080
dbName: string;
1102-
/** @deprecated - Will be made internal in a future major release. */
1103-
metadata: ClientMetadata;
1104-
/** @deprecated - Will be made internal in a future major release. */
1105-
extendedMetadata: Promise<Document>;
1106-
/** @deprecated - Will be made internal in a future major release. */
1107-
additionalDriverInfo: DriverInfo[];
1081+
/** @internal */
1082+
metadata: Promise<ClientMetadata>;
11081083
/** @internal */
11091084
autoEncrypter?: AutoEncrypter;
11101085
/** @internal */

src/sdam/topology.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,7 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
150150
/** Indicates that a client should directly connect to a node without attempting to discover its topology type */
151151
directConnection: boolean;
152152
loadBalanced: boolean;
153-
metadata: ClientMetadata;
154-
extendedMetadata: Promise<Document>;
153+
metadata: Promise<ClientMetadata>;
155154
serverMonitoringMode: ServerMonitoringMode;
156155
/** MongoDB server API version */
157156
serverApi?: ServerApi;
@@ -750,10 +749,6 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
750749
if (typeof callback === 'function') callback(undefined, true);
751750
}
752751

753-
get clientMetadata(): ClientMetadata {
754-
return this.s.options.metadata;
755-
}
756-
757752
isConnected(): boolean {
758753
return this.s.state === STATE_CONNECTED;
759754
}

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ import {
1515
} from '../../../src';
1616
import { connect } from '../../../src/cmap/connect';
1717
import { Connection } from '../../../src/cmap/connection';
18-
import {
19-
addContainerMetadata,
20-
makeClientMetadata
21-
} from '../../../src/cmap/handshake/client_metadata';
18+
import { makeClientMetadata } from '../../../src/cmap/handshake/client_metadata';
2219
import { MongoDBResponse } from '../../../src/cmap/wire_protocol/responses';
2320
import { LEGACY_HELLO_COMMAND } from '../../../src/constants';
2421
import { Topology } from '../../../src/sdam/topology';
@@ -51,8 +48,7 @@ describe('Connection', function () {
5148
...commonConnectOptions,
5249
connectionType: Connection,
5350
...this.configuration.options,
54-
metadata: makeClientMetadata([], {}),
55-
extendedMetadata: addContainerMetadata(makeClientMetadata([], {}))
51+
metadata: makeClientMetadata([], {})
5652
};
5753

5854
let conn;
@@ -74,8 +70,7 @@ describe('Connection', function () {
7470
connectionType: Connection,
7571
...this.configuration.options,
7672
monitorCommands: true,
77-
metadata: makeClientMetadata([], {}),
78-
extendedMetadata: addContainerMetadata(makeClientMetadata([], {}))
73+
metadata: makeClientMetadata([], {})
7974
};
8075

8176
let conn;
@@ -106,8 +101,7 @@ describe('Connection', function () {
106101
connectionType: Connection,
107102
...this.configuration.options,
108103
monitorCommands: true,
109-
metadata: makeClientMetadata([], {}),
110-
extendedMetadata: addContainerMetadata(makeClientMetadata([], {}))
104+
metadata: makeClientMetadata([], {})
111105
};
112106

113107
let conn;

test/integration/mongodb-handshake/mongodb-handshake.prose.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ describe('Handshake Prose Tests', function () {
149149
it('includes both container and FAAS provider information in the client metadata', async function () {
150150
client = this.configuration.newClient();
151151
await client.connect();
152-
expect(client.topology?.s.options.extendedMetadata).to.exist;
153-
const { env } = await client.topology.s.options.extendedMetadata;
152+
expect(client.topology?.s.options.metadata).to.exist;
153+
const { env } = await client.topology.s.options.metadata;
154154

155155
expect(env).to.deep.equal({
156156
region: 'us-east-2',

0 commit comments

Comments
 (0)