Skip to content

Commit fa2f56a

Browse files
committed
fix: runtime dependencies
chore: improve logutils to be more robust when determining path to log message files chore: create custom config classes for clients
1 parent 45bd1e4 commit fa2f56a

25 files changed

+13281
-13764
lines changed

common/lib/authentication/aws_secrets_manager_plugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export class AwsSecretsManagerPlugin extends AbstractConnectionPlugin implements
146146
AwsSecretsManagerPlugin.secretsCache.set(JSON.stringify(this.secretKey), this.secret);
147147
} catch (error: any) {
148148
if (error instanceof SecretsManagerServiceException) {
149-
logAndThrowError(Messages.get("AwsSecretsManagerConnectionPlugin.failedToFetchDbCredentials"));
149+
logAndThrowError(Messages.get("AwsSecretsManagerConnectionPlugin.failedToFetchDbCredentials", error.message));
150150
} else if (error instanceof Error && error.message.includes("AWS SDK error")) {
151151
logAndThrowError(Messages.get("AwsSecretsManagerConnectionPlugin.endpointOverrideInvalidConnection", error.message));
152152
} else {

common/lib/aws_client.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,23 @@ export abstract class AwsClient extends EventEmitter implements SessionStateClie
154154

155155
abstract setReadOnly(readOnly: boolean): Promise<any | void>;
156156

157-
abstract isReadOnly(): boolean;
157+
abstract isReadOnly(): boolean | undefined;
158158

159159
abstract setAutoCommit(autoCommit: boolean): Promise<any | void>;
160160

161-
abstract getAutoCommit(): boolean;
161+
abstract getAutoCommit(): boolean | undefined;
162162

163163
abstract setTransactionIsolation(level: TransactionIsolationLevel): Promise<any | void>;
164164

165-
abstract getTransactionIsolation(): TransactionIsolationLevel;
165+
abstract getTransactionIsolation(): TransactionIsolationLevel | undefined;
166166

167167
abstract setSchema(schema: any): Promise<any | void>;
168168

169-
abstract getSchema(): string;
169+
abstract getSchema(): string | undefined;
170170

171171
abstract setCatalog(catalog: string): Promise<any | void>;
172172

173-
abstract getCatalog(): string;
173+
abstract getCatalog(): string | undefined;
174174

175175
abstract end(): Promise<any>;
176176

common/lib/session_state_client.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,21 @@ import { TransactionIsolationLevel } from "./utils/transaction_isolation_level";
1919
export interface SessionStateClient {
2020
setReadOnly(readOnly: boolean): Promise<any | void>;
2121

22-
isReadOnly(): boolean;
22+
isReadOnly(): boolean | undefined;
2323

2424
setAutoCommit(autoCommit: boolean): Promise<any | void>;
2525

26-
getAutoCommit(): boolean;
26+
getAutoCommit(): boolean | undefined;
2727

2828
setTransactionIsolation(level: TransactionIsolationLevel): Promise<any | void>;
2929

30-
getTransactionIsolation(): TransactionIsolationLevel;
30+
getTransactionIsolation(): TransactionIsolationLevel | undefined;
3131

3232
setSchema(schema: any): Promise<any | void>;
3333

34-
getSchema(): string;
34+
getSchema(): string | undefined;
3535

3636
setCatalog(catalog: string): Promise<any | void>;
3737

38-
getCatalog(): string;
38+
getCatalog(): string | undefined;
3939
}

common/lib/utils/locales/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"HostListProviderService.notFound": "HostListProviderService not found.",
1919
"HostInfo.noHostParameter": "Host parameter must be set, HostInfo not found or not provided.",
2020
"HostInfo.weightLessThanZero": "A HostInfo object was created with a weight value less than 0.",
21-
"AwsSecretsManagerConnectionPlugin.failedToFetchDbCredentials": "Was not able to either fetch or read the database credentials from AWS Secrets Manager. Ensure the correct secretId and region properties have been provided.",
21+
"AwsSecretsManagerConnectionPlugin.failedToFetchDbCredentials": "Was not able to either fetch or read the database credentials from AWS Secrets Manager due to error: %s. Ensure the correct secretId and region properties have been provided.",
2222
"AwsSecretsManagerConnectionPlugin.missingRequiredConfigParameter": "Configuration parameter '%s' is required.",
2323
"AwsSecretsManagerConnectionPlugin.unhandledError": "Unhandled error: '%s'",
2424
"AwsSecretsManagerConnectionPlugin.endpointOverrideInvalidConnection": "A connection to the provided endpoint could not be established: '%s'.",

common/lib/utils/messages.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,46 @@
1717
import path from "path";
1818
import { I18n } from "i18n";
1919
import { fileURLToPath } from "url";
20+
import fs from "fs";
21+
22+
const getModuleDir = () => {
23+
if (typeof __dirname !== "undefined") {
24+
return __dirname;
25+
}
26+
return path.dirname(fileURLToPath(import.meta.url));
27+
};
28+
29+
const findLocalesDir = (baseDir: string): string => {
30+
const localesDir = path.join(baseDir, "locales");
31+
if (fs.existsSync(localesDir)) {
32+
return localesDir;
33+
}
34+
35+
// baseDir wasn't correctly constructed, attempt to resolve path to locales using relative path.
36+
const pathFromRoot = "../../../common/lib/utils/locales";
37+
const packageDir = path.resolve(baseDir, pathFromRoot);
38+
if (fs.existsSync(packageDir)) {
39+
return packageDir;
40+
}
41+
42+
fs.mkdirSync(localesDir, { recursive: true });
43+
return localesDir;
44+
};
2045

2146
export class Messages {
22-
static __filename = fileURLToPath(import.meta.url);
23-
static __dirname = path.dirname(Messages.__filename);
47+
static __dirname = getModuleDir();
48+
private static _i18n: I18n | null = null;
2449

25-
static i18n = new I18n({
26-
locales: ["en"],
27-
directory: path.join(Messages.__dirname, "locales")
28-
});
50+
static get i18n(): I18n {
51+
if (!Messages._i18n) {
52+
const localesDir = findLocalesDir(Messages.__dirname);
53+
Messages._i18n = new I18n({
54+
locales: ["en"],
55+
directory: localesDir
56+
});
57+
}
58+
return Messages._i18n;
59+
}
2960

3061
static get(key: string, ...val: string[]) {
3162
return Messages.i18n.__(key, ...val);

common/lib/wrapper_property.ts

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,173 @@ import { DatabaseDialect } from "./database_dialect/database_dialect";
1919
import { ClusterTopologyMonitorImpl } from "./host_list_provider/monitoring/cluster_topology_monitor";
2020
import { BlueGreenStatusProvider } from "./plugins/bluegreen/blue_green_status_provider";
2121

22+
export interface AwsClientConfig {
23+
/** Comma separated list of connection plugin codes */
24+
plugins?: string;
25+
/** This flag is enabled by default, meaning that the plugins order will be automatically adjusted. Disable it at your own risk or if you really need plugins to be executed in a particular order. */
26+
autoSortWrapperPluginOrder?: boolean;
27+
/** A unique identifier for the supported database dialect. */
28+
dialect?: string;
29+
/** The connection provider used to create connections. */
30+
connectionProvider?: ConnectionProvider;
31+
/** Timeout in milliseconds for the wrapper to execute queries against MySQL database engines */
32+
mysqlQueryTimeout?: number;
33+
/** Timeout in milliseconds for the wrapper to create a connection. */
34+
wrapperConnectTimeout?: number;
35+
/** Timeout in milliseconds for the wrapper to execute queries. */
36+
wrapperQueryTimeout?: number;
37+
/** Enables session state transfer to a new connection. */
38+
transferSessionStateOnSwitch?: boolean;
39+
/** Enables resetting a connection's session state before closing it. */
40+
resetSessionStateOnClose?: boolean;
41+
/** Enables to rollback a current transaction being in progress when switching to a new connection. */
42+
rollbackOnSwitch?: boolean;
43+
/** An override for specifying the default host availability change strategy. */
44+
defaultHostAvailabilityStrategy?: string;
45+
/** Max number of retries for checking a host's availability. */
46+
hostAvailabilityStrategyMaxRetries?: number;
47+
/** The initial backoff time in seconds. */
48+
hostAvailabilityStrategyInitialBackoffTimeSec?: number;
49+
/** Interval in millis between measuring response time to a database host. */
50+
responseMeasurementIntervalMs?: number;
51+
/** Overrides the host that is used to generate the IAM token */
52+
iamHost?: string;
53+
/** Overrides default port that is used to generate the IAM token */
54+
iamDefaultPort?: number;
55+
/** Overrides AWS region that is used to generate the IAM token */
56+
iamRegion?: string;
57+
/** The ARN of the IAM Role that is to be assumed. */
58+
iamRoleArn?: string;
59+
/** The ARN of the identity provider */
60+
iamIdpArn?: string;
61+
/** IAM token cache expiration in seconds */
62+
iamTokenExpiration?: number;
63+
/** The federated user name */
64+
idpUsername?: string;
65+
/** The federated user password */
66+
idpPassword?: string;
67+
/** The hosting URL of the Identity Provider */
68+
idpEndpoint?: string;
69+
/** The hosting port of the Identity Provider */
70+
idpPort?: number;
71+
/** The ID of the AWS application configured on Okta */
72+
appId?: string;
73+
/** The relaying party identifier */
74+
rpIdentifier?: string;
75+
/** The IAM user used to access the database */
76+
dbUser?: string;
77+
/** The options to be passed into the httpsAgent */
78+
httpsAgentOptions?: Record<string, any>;
79+
/** The name or the ARN of the secret to retrieve. */
80+
secretId?: string;
81+
/** The region of the secret to retrieve. */
82+
secretRegion?: string;
83+
/** The endpoint of the secret to retrieve. */
84+
secretEndpoint?: string;
85+
/** Cluster topology refresh rate in millis during a writer failover process. During the writer failover process, cluster topology may be refreshed at a faster pace than normal to speed up discovery of the newly promoted writer. */
86+
failoverClusterTopologyRefreshRateMs?: number;
87+
/** Maximum allowed time for the failover process. */
88+
failoverTimeoutMs?: number;
89+
/** Interval of time to wait between attempts to reconnect to a failed writer during a writer failover process. */
90+
failoverWriterReconnectIntervalMs?: number;
91+
/** Reader connection attempt timeout during a reader failover process. */
92+
failoverReaderConnectTimeoutMs?: number;
93+
/** Enable/disable cluster-aware failover logic. */
94+
enableClusterAwareFailover?: boolean;
95+
/** Set host role to follow during failover. */
96+
failoverMode?: string;
97+
/** The strategy that should be used to select a new reader host while opening a new connection. */
98+
failoverReaderHostSelectorStrategy?: string;
99+
/** Cluster topology refresh rate in millis. The cached topology for the cluster will be invalidated after the specified time, after which it will be updated during the next interaction with the connection. */
100+
clusterTopologyRefreshRateMs?: number;
101+
/** Cluster topology high refresh rate in millis. */
102+
clusterTopologyHighRefreshRateMs?: number;
103+
/** A unique identifier for the cluster. Connections with the same cluster id share a cluster topology cache. If unspecified, a cluster id is automatically created for AWS RDS clusters. */
104+
clusterId?: string;
105+
/** The cluster instance DNS pattern that will be used to build a complete instance endpoint. A "?" character in this pattern should be used as a placeholder for cluster instance names. This pattern is required to be specified for IP address or custom domain connections to AWS RDS clusters. Otherwise, if unspecified, the pattern will be automatically created for AWS RDS clusters. */
106+
clusterInstanceHostPattern?: string;
107+
/** Set to true if you are providing a connection string with multiple comma-delimited hosts and your cluster has only one writer. The writer must be the first host in the connection string */
108+
singleWriterConnectionString?: boolean;
109+
/** The strategy that should be used to select a new reader host. */
110+
readerHostSelectorStrategy?: string;
111+
/** Maximum allowed time for the retries opening a connection. */
112+
openConnectionRetryTimeoutMs?: number;
113+
/** Time between each retry of opening a connection. */
114+
openConnectionRetryIntervalMs?: number;
115+
/** Interval in millis between sending SQL to the server and the first probe to database host. */
116+
failureDetectionTime?: number;
117+
/** Enable enhanced failure detection logic. */
118+
failureDetectionEnabled?: boolean;
119+
/** Interval in millis between probes to database host. */
120+
failureDetectionInterval?: number;
121+
/** Number of failed connection checks before considering database host unhealthy. */
122+
failureDetectionCount?: number;
123+
/** Interval in milliseconds for a monitor to be considered inactive and to be disposed. */
124+
monitorDisposalTime?: number;
125+
/** Comma separated list of database host-weight pairs in the format of `<host>:<weight>`. */
126+
roundRobinHostWeightPairs?: string;
127+
/** The default weight for any hosts that have not been configured with the `roundRobinHostWeightPairs` parameter. */
128+
roundRobinDefaultWeight?: number;
129+
/** Enables telemetry and observability of the wrapper */
130+
enableTelemetry?: boolean;
131+
/** Force submitting traces related to calls as top level traces. */
132+
telemetrySubmitToplevel?: boolean;
133+
/** Method to export telemetry traces of the wrapper. */
134+
telemetryTracesBackend?: string;
135+
/** Method to export telemetry metrics of the wrapper. */
136+
telemetryMetricsBackend?: string;
137+
/** Post an additional top-level trace for failover process. */
138+
telemetryFailoverAdditionalTopTrace?: boolean;
139+
/** If the cache of transaction router info is empty and a new connection is made, this property toggles whether the plugin will wait and synchronously fetch transaction router info before selecting a transaction router to connect to, or to fall back to using the provided DB Shard Group endpoint URL. */
140+
limitlessWaitForTransactionRouterInfo?: boolean;
141+
/** Interval in millis between retries fetching Limitless Transaction Router information. */
142+
limitlessGetTransactionRouterInfoRetryIntervalMs?: number;
143+
/** Max number of connection retries fetching Limitless Transaction Router information. */
144+
limitlessGetTransactionRouterInfoMaxRetries?: number;
145+
/** Interval in millis between polling for Limitless Transaction Routers to the database. */
146+
limitlessTransactionRouterMonitorIntervalMs?: number;
147+
/** Max number of connection retries the Limitless Connection Plugin will attempt. */
148+
limitlessConnectMaxRetries?: number;
149+
/** Interval in milliseconds for an Limitless router monitor to be considered inactive and to be disposed. */
150+
limitlessTransactionRouterMonitorDisposalTimeMs?: number;
151+
/** Map containing any keepAlive properties that the target driver accepts in the client configuration. */
152+
wrapperKeepAliveProperties?: Map<string, any>;
153+
/** A reference to a custom database dialect object. */
154+
customDatabaseDialect?: DatabaseDialect;
155+
/** A reference to a custom AwsCredentialsProviderHandler object. */
156+
customAwsCredentialProviderHandler?: any;
157+
/** Name of the AWS Profile to use for IAM or SecretsManager auth. */
158+
awsProfile?: string;
159+
/** Driver configuration profile name */
160+
profileName?: string;
161+
/** Controls how frequently custom endpoint monitors fetch custom endpoint info, in milliseconds. */
162+
customEndpointInfoRefreshRateMs?: number;
163+
/** Controls whether to wait for custom endpoint info to become available before connecting or executing a method. Waiting is only necessary if a connection to a given custom endpoint has not been opened or used recently. Note that disabling this may result in occasional connections to instances outside of the custom endpoint. */
164+
waitForCustomEndpointInfo?: boolean;
165+
/** Controls the maximum amount of time that the plugin will wait for custom endpoint info to be made available by the custom endpoint monitor, in milliseconds. */
166+
waitForCustomEndpointInfoTimeoutMs?: number;
167+
/** Controls how long a monitor should run without use before expiring and being removed, in milliseconds. */
168+
customEndpointMonitorExpirationMs?: number;
169+
/** The region of the cluster's custom endpoints. If not specified, the region will be parsed from the URL. */
170+
customEndpointRegion?: string;
171+
/** Enables replacing a green host name with the original hostname after a blue/green switchover and the green name no longer resolves. */
172+
enableGreenHostReplacement?: boolean;
173+
/** Connect timeout in milliseconds during Blue/Green Deployment switchover. */
174+
bgConnectTimeoutMs?: number;
175+
/** Blue/Green Deployment ID */
176+
bgdId?: string;
177+
/** Baseline Blue/Green Deployment status checking interval in milliseconds. */
178+
bgBaselineMs?: number;
179+
/** Increased Blue/Green Deployment status checking interval in milliseconds. */
180+
bgIncreasedMs?: number;
181+
/** High Blue/Green Deployment status checking interval in milliseconds. */
182+
bgHighMs?: number;
183+
/** Blue/Green Deployment switchover timeout in milliseconds. */
184+
bgSwitchoverTimeoutMs?: number;
185+
/** Enables Blue/Green Deployment switchover to suspend new blue connection requests while the switchover process is in progress. */
186+
bgSuspendNewBlueConnections?: boolean;
187+
}
188+
22189
export class WrapperProperty<T> {
23190
name: string;
24191
description: string;

0 commit comments

Comments
 (0)