From 3acde059a9b744c6fa551344dff826bc2ffa7c39 Mon Sep 17 00:00:00 2001 From: Alena Khineika Date: Thu, 1 Aug 2024 13:43:31 +0200 Subject: [PATCH] refactor(telemetry): use resolved srv from topology VSCODE-563 (#765) --- package-lock.json | 11 ++- package.json | 1 - src/telemetry/connectionTelemetry.ts | 27 ++----- .../telemetry/connectionTelemetry.test.ts | 80 ++++++++++++++++++- 4 files changed, 95 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 377eb20f4..566ca0dc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,6 @@ "numeral": "^2.0.6", "react": "^17.0.2", "react-dom": "^17.0.2", - "resolve-mongodb-srv": "^1.1.5", "ts-log": "^2.2.5", "uuid": "^8.3.2", "vscode-languageclient": "^8.1.0", @@ -19768,6 +19767,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/resolve-mongodb-srv/-/resolve-mongodb-srv-1.1.5.tgz", "integrity": "sha512-flu1XTSLDJHvTnWu2aJh2w9jgGPcNYJn2obMkuzXiyWSz0MLXu9IRCjvirJ4zRoCPHJJPt3uLQVNJTrzFRWd1w==", + "optional": true, "dependencies": { "whatwg-url": "^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0" }, @@ -19779,6 +19779,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "optional": true, "dependencies": { "punycode": "^2.1.1" }, @@ -19790,6 +19791,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "optional": true, "engines": { "node": ">=12" } @@ -19798,6 +19800,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "optional": true, "dependencies": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" @@ -39164,6 +39167,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/resolve-mongodb-srv/-/resolve-mongodb-srv-1.1.5.tgz", "integrity": "sha512-flu1XTSLDJHvTnWu2aJh2w9jgGPcNYJn2obMkuzXiyWSz0MLXu9IRCjvirJ4zRoCPHJJPt3uLQVNJTrzFRWd1w==", + "optional": true, "requires": { "whatwg-url": "^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0" }, @@ -39172,6 +39176,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "optional": true, "requires": { "punycode": "^2.1.1" } @@ -39179,12 +39184,14 @@ "webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "optional": true }, "whatwg-url": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "optional": true, "requires": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" diff --git a/package.json b/package.json index d1c2d4cd8..82c58dec3 100644 --- a/package.json +++ b/package.json @@ -1104,7 +1104,6 @@ "numeral": "^2.0.6", "react": "^17.0.2", "react-dom": "^17.0.2", - "resolve-mongodb-srv": "^1.1.5", "ts-log": "^2.2.5", "uuid": "^8.3.2", "vscode-languageclient": "^8.1.0", diff --git a/src/telemetry/connectionTelemetry.ts b/src/telemetry/connectionTelemetry.ts index 58cf32dc5..24617ce6e 100644 --- a/src/telemetry/connectionTelemetry.ts +++ b/src/telemetry/connectionTelemetry.ts @@ -1,11 +1,8 @@ import type { DataService } from 'mongodb-data-service'; -import { getCloudInfo } from 'mongodb-cloud-info'; import mongoDBBuildInfo from 'mongodb-build-info'; -import resolveMongodbSrv from 'resolve-mongodb-srv'; import { ConnectionTypes } from '../connectionController'; import { createLogger } from '../logging'; -import ConnectionString from 'mongodb-connection-string-url'; import type { TopologyType } from 'mongodb'; const log = createLogger('connection telemetry helper'); @@ -40,22 +37,10 @@ export type HostInformation = { public_cloud_name?: string; }; -async function getHostnameForConnection( - connectionStringData: ConnectionString -): Promise { - if (connectionStringData.isSRV) { - const uri = await resolveMongodbSrv(connectionStringData.toString()).catch( - () => null - ); - if (!uri) { - return null; - } - connectionStringData = new ConnectionString(uri, { - looseValidation: true, - }); - } - - const [hostname] = (connectionStringData.hosts[0] ?? '').split(':'); +function getHostnameForConnection(dataService: DataService): string | null { + const lastSeenTopology = dataService.getLastSeenTopology(); + const resolvedHost = lastSeenTopology?.servers.values().next().value.address; + const [hostname] = (resolvedHost ?? '').split(':'); return hostname; } @@ -64,6 +49,7 @@ async function getPublicCloudInfo(host: string): Promise<{ is_public_cloud?: boolean; }> { try { + const { getCloudInfo } = await import('mongodb-cloud-info'); const { isAws, isAzure, isGcp } = await getCloudInfo(host); let publicCloudName; @@ -84,6 +70,7 @@ async function getPublicCloudInfo(host: string): Promise<{ public_cloud_name: publicCloudName, }; } catch (err) { + // Cannot resolve dns used by mongodb-cloud-info in the browser environment. return {}; } } @@ -144,7 +131,7 @@ export async function getConnectionTelemetryProperties( const authMechanism = connectionString.searchParams.get('authMechanism'); const username = connectionString.username ? 'DEFAULT' : 'NONE'; const authStrategy = authMechanism ?? username; - const resolvedHostname = await getHostnameForConnection(connectionString); + const resolvedHostname = getHostnameForConnection(dataService); const { dataLake, genuineMongoDB, host, build, isAtlas, isLocalAtlas } = await dataService.instance(); const atlasHostname = isAtlas ? resolvedHostname : null; diff --git a/src/test/suite/telemetry/connectionTelemetry.test.ts b/src/test/suite/telemetry/connectionTelemetry.test.ts index 47d51dde6..bddf1763e 100644 --- a/src/test/suite/telemetry/connectionTelemetry.test.ts +++ b/src/test/suite/telemetry/connectionTelemetry.test.ts @@ -16,14 +16,17 @@ suite('ConnectionTelemetry Controller Test Suite', function () { const sandbox = sinon.createSandbox(); let dataServiceStub; let getConnectionStringStub; + let getLastSeenTopology; let instanceStub; before(() => { getConnectionStringStub = sandbox.stub(); + getLastSeenTopology = sandbox.stub(); instanceStub = sandbox.stub(); dataServiceStub = { getCurrentTopologyType: sandbox.stub(), getConnectionString: getConnectionStringStub, + getLastSeenTopology: getLastSeenTopology, instance: instanceStub, } as unknown as DataService; }); @@ -51,6 +54,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://13.64.151.161') ); + getLastSeenTopology.returns({ + servers: new Map().set('13.64.151.161', { + address: '13.64.151.161', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -80,6 +88,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -111,6 +124,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -145,6 +163,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://test-data-sets-a011bb.mongodb.net') ); + getLastSeenTopology.returns({ + servers: new Map().set('test-data-sets-00-02-a011bb.mongodb.net', { + address: 'test-data-sets-00-02-a011bb.mongodb.net', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -153,7 +176,7 @@ suite('ConnectionTelemetry Controller Test Suite', function () { expect(instanceTelemetry.is_atlas).to.equal(true); expect(instanceTelemetry.atlas_hostname).to.equal( - 'test-data-sets-a011bb.mongodb.net' + 'test-data-sets-00-02-a011bb.mongodb.net' ); expect(instanceTelemetry.is_atlas_url).to.equal(true); expect(instanceTelemetry.is_local_atlas).to.equal(false); @@ -178,6 +201,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://example.mongo.ondigitalocean.com:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('example.mongo.ondigitalocean.com:27017', { + address: 'example.mongo.ondigitalocean.com:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -209,6 +237,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -239,6 +272,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -269,6 +307,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -299,6 +342,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://example.mongo.ondigitalocean.com:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('example.mongo.ondigitalocean.com:27017', { + address: 'example.mongo.ondigitalocean.com:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -327,6 +375,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -361,6 +414,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://127.0.0.1') ); + getLastSeenTopology.returns({ + servers: new Map().set('127.0.0.1', { + address: '127.0.0.1', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -397,6 +455,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://127.0.0.1') ); + getLastSeenTopology.returns({ + servers: new Map().set('127.0.0.1', { + address: '127.0.0.1', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -427,6 +490,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://artishok:pass@localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -455,6 +523,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { getConnectionStringStub.returns( new ConnectionString('mongodb://localhost:27017') ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub, @@ -485,6 +558,11 @@ suite('ConnectionTelemetry Controller Test Suite', function () { 'mongodb://foo:bar@localhost:27017/?authSource=source&authMechanism=SCRAM-SHA-1' ) ); + getLastSeenTopology.returns({ + servers: new Map().set('localhost:27017', { + address: 'localhost:27017', + }), + }); const instanceTelemetry = await getConnectionTelemetryProperties( dataServiceStub,