-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6d894d6
commit c623356
Showing
19 changed files
with
905 additions
and
203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { calculateObjectSize } from 'bson'; | ||
import * as os from 'os'; | ||
|
||
import type { MongoOptions } from '../../mongo_client'; | ||
import { deepCopy, DeepPartial } from '../../utils'; | ||
import { applyFaasEnvMetadata } from './faas_provider'; | ||
|
||
/** | ||
* @public | ||
* @see https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.rst#hello-command | ||
*/ | ||
export interface ClientMetadata { | ||
driver: { | ||
name: string; | ||
version: string; | ||
}; | ||
os: { | ||
type: string; | ||
name: NodeJS.Platform; | ||
architecture: string; | ||
version: string; | ||
}; | ||
platform: string; | ||
application?: { | ||
name: string; | ||
}; | ||
|
||
/** Data containing information about the environment, if the driver is running in a FAAS environment. */ | ||
env?: { | ||
name: 'aws.lambda' | 'gcp.func' | 'azure.func' | 'vercel'; | ||
timeout_sec?: number; | ||
memory_mb?: number; | ||
region?: string; | ||
url?: string; | ||
}; | ||
} | ||
|
||
/** @internal */ | ||
export type TruncatedClientMetadata = DeepPartial<ClientMetadata>; | ||
|
||
/** | ||
* @internal | ||
* truncates the client metadata according to the priority outlined here | ||
* https://github.com/mongodb/specifications/blob/master/source/mongodb-handshake/handshake.rst#limitations | ||
*/ | ||
export function truncateClientMetadata(metadata: ClientMetadata): TruncatedClientMetadata { | ||
const copiedMetadata: TruncatedClientMetadata = deepCopy(metadata); | ||
const truncations: Array<(arg0: TruncatedClientMetadata) => void> = [ | ||
m => delete m.platform, | ||
m => { | ||
if (m.env) { | ||
m.env = { name: m.env.name }; | ||
} | ||
}, | ||
m => { | ||
if (m.os) { | ||
m.os = { type: m.os.type }; | ||
} | ||
}, | ||
m => delete m.env, | ||
m => delete m.os, | ||
m => delete m.driver, | ||
m => delete m.application | ||
]; | ||
|
||
for (const truncation of truncations) { | ||
if (calculateObjectSize(copiedMetadata) <= 512) { | ||
return copiedMetadata; | ||
} | ||
truncation(copiedMetadata); | ||
} | ||
|
||
return copiedMetadata; | ||
} | ||
|
||
/** @public */ | ||
export interface ClientMetadataOptions { | ||
driverInfo?: { | ||
name?: string; | ||
version?: string; | ||
platform?: string; | ||
}; | ||
appName?: string; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
const NODE_DRIVER_VERSION = require('../../../package.json').version; | ||
|
||
export function makeClientMetadata( | ||
options: Pick<MongoOptions, 'appName' | 'driverInfo'> | ||
): ClientMetadata { | ||
const name = options.driverInfo.name ? `nodejs|${options.driverInfo.name}` : 'nodejs'; | ||
const version = options.driverInfo.version | ||
? `${NODE_DRIVER_VERSION}|${options.driverInfo.version}` | ||
: NODE_DRIVER_VERSION; | ||
const platform = options.driverInfo.platform | ||
? `Node.js ${process.version}, ${os.endianness()}|${options.driverInfo.platform}` | ||
: `Node.js ${process.version}, ${os.endianness()}`; | ||
|
||
const metadata: ClientMetadata = { | ||
driver: { | ||
name, | ||
version | ||
}, | ||
os: { | ||
type: os.type(), | ||
name: process.platform, | ||
architecture: process.arch, | ||
version: os.release() | ||
}, | ||
platform | ||
}; | ||
|
||
if (options.appName) { | ||
// MongoDB requires the appName not exceed a byte length of 128 | ||
const name = | ||
Buffer.byteLength(options.appName, 'utf8') <= 128 | ||
? options.appName | ||
: Buffer.from(options.appName, 'utf8').subarray(0, 128).toString('utf8'); | ||
metadata.application = { name }; | ||
} | ||
|
||
return applyFaasEnvMetadata(metadata); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { identity } from '../../utils'; | ||
import type { ClientMetadata } from './client_metadata'; | ||
|
||
export type FAASProvider = 'aws' | 'gcp' | 'azure' | 'vercel' | 'none'; | ||
|
||
export function determineCloudProvider(): FAASProvider { | ||
const awsPresent = process.env.AWS_EXECUTION_ENV || process.env.AWS_LAMBDA_RUNTIME_API; | ||
const azurePresent = process.env.FUNCTIONS_WORKER_RUNTIME; | ||
const gcpPresent = process.env.K_SERVICE || process.env.FUNCTION_NAME; | ||
const vercelPresent = process.env.VERCEL; | ||
|
||
const numberOfProvidersPresent = [awsPresent, azurePresent, gcpPresent, vercelPresent].filter( | ||
identity | ||
).length; | ||
|
||
if (numberOfProvidersPresent !== 1) { | ||
return 'none'; | ||
} | ||
|
||
if (awsPresent) return 'aws'; | ||
if (azurePresent) return 'azure'; | ||
if (gcpPresent) return 'gcp'; | ||
return 'vercel'; | ||
} | ||
|
||
function applyAzureMetadata(m: ClientMetadata): ClientMetadata { | ||
m.env = { name: 'azure.func' }; | ||
return m; | ||
} | ||
|
||
function applyGCPMetadata(m: ClientMetadata): ClientMetadata { | ||
m.env = { name: 'gcp.func' }; | ||
|
||
const memory_mb = Number.parseInt(process.env.FUNCTION_MEMORY_MB ?? ''); | ||
if (!Number.isNaN(memory_mb)) { | ||
m.env.memory_mb = memory_mb; | ||
} | ||
const timeout_sec = Number.parseInt(process.env.FUNCTION_TIMEOUT_SEC ?? ''); | ||
if (!Number.isNaN(timeout_sec)) { | ||
m.env.timeout_sec = timeout_sec; | ||
} | ||
if (process.env.FUNCTION_REGION) { | ||
m.env.region = process.env.FUNCTION_REGION; | ||
} | ||
|
||
return m; | ||
} | ||
|
||
function applyAWSMetadata(m: ClientMetadata): ClientMetadata { | ||
m.env = { name: 'aws.lambda' }; | ||
if (process.env.AWS_REGION) { | ||
m.env.region = process.env.AWS_REGION; | ||
} | ||
const memory_mb = Number.parseInt(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE ?? ''); | ||
if (!Number.isNaN(memory_mb)) { | ||
m.env.memory_mb = memory_mb; | ||
} | ||
return m; | ||
} | ||
|
||
function applyVercelMetadata(m: ClientMetadata): ClientMetadata { | ||
m.env = { name: 'vercel' }; | ||
if (process.env.VERCEL_URL) { | ||
m.env.url = process.env.VERCEL_URL; | ||
} | ||
if (process.env.VERCEL_REGION) { | ||
m.env.region = process.env.VERCEL_REGION; | ||
} | ||
return m; | ||
} | ||
|
||
export function applyFaasEnvMetadata(metadata: ClientMetadata): ClientMetadata { | ||
const handlerMap: Record<FAASProvider, (m: ClientMetadata) => ClientMetadata> = { | ||
aws: applyAWSMetadata, | ||
gcp: applyGCPMetadata, | ||
azure: applyAzureMetadata, | ||
vercel: applyVercelMetadata, | ||
none: identity | ||
}; | ||
const cloudProvider = determineCloudProvider(); | ||
|
||
const faasMetadataProvider = handlerMap[cloudProvider]; | ||
return faasMetadataProvider(metadata); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.