Skip to content

Commit 8d51f4b

Browse files
committed
feat(NODE-7009): add client metadata on demand
1 parent 52ed3d1 commit 8d51f4b

File tree

6 files changed

+189
-1
lines changed

6 files changed

+189
-1
lines changed

src/mongo_client.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { type TokenCache } from './cmap/auth/mongodb_oidc/token_cache';
1414
import { AuthMechanism } from './cmap/auth/providers';
1515
import type { LEGAL_TCP_SOCKET_OPTIONS, LEGAL_TLS_SOCKET_OPTIONS } from './cmap/connect';
1616
import type { Connection } from './cmap/connection';
17-
import type { ClientMetadata } from './cmap/handshake/client_metadata';
17+
import { type ClientMetadata, makeClientMetadata } from './cmap/handshake/client_metadata';
1818
import type { CompressorName } from './cmap/wire_protocol/compression';
1919
import { parseOptions, resolveSRVRecord } from './connection_string';
2020
import { MONGO_CLIENT_EVENTS } from './constants';
@@ -455,6 +455,15 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> implements
455455
await this.close();
456456
}
457457

458+
/**
459+
* Append metadata to the client metadata after instantiation.
460+
* @param driverInfo - Information abou the application or libraary.
461+
*/
462+
appendMetadata(driverInfo: DriverInfo) {
463+
this.s.options.driverInfo = driverInfo;
464+
this.s.options.metadata = makeClientMetadata(this.s.options);
465+
}
466+
458467
/** @internal */
459468
private checkForNonGenuineHosts() {
460469
const documentDBHostnames = this.options.hosts.filter((hostAddress: HostAddress) =>

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,11 @@ describe('Handshake Prose Tests', function () {
194194
});
195195
});
196196
});
197+
198+
describe('Client Metadata Update Prose Tests', function () {
199+
let client: MongoClient;
200+
201+
afterEach(async function () {
202+
await client?.close();
203+
});
204+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { join } from 'path';
2+
3+
import { loadSpecTests } from '../../spec';
4+
import { runUnifiedSuite } from '../../tools/unified-spec-runner/runner';
5+
6+
describe('MongoDB Handshake Tests (Unified)', function () {
7+
runUnifiedSuite(loadSpecTests(join('mongodb-handshake')));
8+
});
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
{
2+
"description": "client metadata is not propagated to the server",
3+
"schemaVersion": "1.9",
4+
"runOnRequirements": [
5+
{
6+
"minServerVersion": "6.0"
7+
}
8+
],
9+
"createEntities": [
10+
{
11+
"client": {
12+
"id": "client",
13+
"observeEvents": [
14+
"commandSucceededEvent",
15+
"commandFailedEvent",
16+
"connectionClosedEvent",
17+
"connectionCreatedEvent"
18+
]
19+
}
20+
},
21+
{
22+
"database": {
23+
"id": "database",
24+
"client": "client",
25+
"databaseName": "test"
26+
}
27+
}
28+
],
29+
"tests": [
30+
{
31+
"description": "metadata append does not create new connections or close existing ones and no hello command is sent",
32+
"operations": [
33+
{
34+
"name": "runCommand",
35+
"object": "database",
36+
"arguments": {
37+
"commandName": "ping",
38+
"command": {
39+
"ping": 1
40+
}
41+
},
42+
"expectResult": {
43+
"ok": 1
44+
}
45+
},
46+
{
47+
"name": "appendMetadata",
48+
"object": "client",
49+
"arguments": {
50+
"driverInfoOptions": {
51+
"name": "framework",
52+
"version": "2.0",
53+
"platform": "Framework Platform"
54+
}
55+
}
56+
},
57+
{
58+
"name": "runCommand",
59+
"object": "database",
60+
"arguments": {
61+
"commandName": "ping",
62+
"command": {
63+
"ping": 1
64+
}
65+
},
66+
"expectResult": {
67+
"ok": 1
68+
}
69+
}
70+
],
71+
"expectEvents": [
72+
{
73+
"client": "client",
74+
"eventType": "cmap",
75+
"events": [
76+
{
77+
"connectionCreatedEvent": {}
78+
}
79+
]
80+
},
81+
{
82+
"client": "client",
83+
"eventType": "command",
84+
"events": [
85+
{
86+
"commandSucceededEvent": {
87+
"commandName": "ping"
88+
}
89+
},
90+
{
91+
"commandSucceededEvent": {
92+
"commandName": "ping"
93+
}
94+
}
95+
]
96+
}
97+
]
98+
}
99+
]
100+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
description: client metadata is not propagated to the server
2+
schemaVersion: '1.9'
3+
runOnRequirements:
4+
- minServerVersion: '6.0'
5+
createEntities:
6+
- client:
7+
id: &client client
8+
observeEvents:
9+
- commandSucceededEvent
10+
- commandFailedEvent
11+
- connectionClosedEvent
12+
- connectionCreatedEvent
13+
- database:
14+
id: &database database
15+
client: *client
16+
databaseName: test
17+
tests:
18+
# Test that appending metadata after `MongoClient` initialization does not close existing
19+
# connections, create new ones, and that no new `hello` command is sent.
20+
- description: metadata append does not create new connections or close existing ones and no hello command is sent
21+
operations:
22+
- name: runCommand
23+
object: *database
24+
arguments:
25+
commandName: ping
26+
command:
27+
ping: 1
28+
expectResult:
29+
ok: 1
30+
- name: appendMetadata
31+
object: *client
32+
arguments:
33+
driverInfoOptions:
34+
name: framework
35+
version: '2.0'
36+
platform: Framework Platform
37+
- name: runCommand
38+
object: *database
39+
arguments:
40+
commandName: ping
41+
command:
42+
ping: 1
43+
expectResult:
44+
ok: 1
45+
expectEvents:
46+
- client: *client
47+
eventType: cmap
48+
events:
49+
# Expect only one connection to be created for the first 'ping' command.
50+
- connectionCreatedEvent: { }
51+
- client: *client
52+
eventType: command
53+
events:
54+
- commandSucceededEvent:
55+
commandName: ping
56+
- commandSucceededEvent:
57+
commandName: ping
58+

test/tools/unified-spec-runner/operations.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@ operations.set('recordTopologyDescription', async ({ entities, operation }) => {
665665
entities.set(id, description!);
666666
});
667667

668+
operations.set('appendMetadata', async ({ entities, operation }) => {
669+
const client = entities.getEntity('client', operation.object);
670+
client.appendMetadata(operation.arguments.driverInfoOptions);
671+
});
672+
668673
operations.set('assertTopologyType', async ({ entities, operation }) => {
669674
const {
670675
topologyDescription,

0 commit comments

Comments
 (0)