Skip to content

Commit 4e4760d

Browse files
authored
fix: error retrieving keep alive settings (#395)
1 parent c6478cb commit 4e4760d

9 files changed

Lines changed: 104 additions & 13 deletions

common/lib/profile/driver_configuration_profiles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { AwsPoolConfig } from "../aws_pool_config";
2727
import { StaleDnsPluginFactory } from "../plugins/stale_dns/stale_dns_plugin_factory";
2828

2929
export class DriverConfigurationProfiles {
30-
private static readonly MONITORING_CONNECTION_PREFIX = "monitoring-";
30+
private static readonly MONITORING_CONNECTION_PREFIX = "monitoring_";
3131
private static readonly activeProfiles: Map<string, ConfigurationProfile> = new Map<string, ConfigurationProfile>();
3232
private static readonly presets: Map<string, ConfigurationProfile> = new Map<string, ConfigurationProfile>([
3333
[

mysql/lib/dialect/mysql2_driver_dialect.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ export class MySQL2DriverDialect implements DriverDialect {
7676
}
7777

7878
setKeepAliveProperties(props: Map<string, any>, keepAliveProps: any) {
79-
if (keepAliveProps && keepAliveProps.get(MySQL2DriverDialect.KEEP_ALIVE_PROPERTY_NAME)) {
79+
if (keepAliveProps instanceof Map) {
80+
keepAliveProps = Object.fromEntries(keepAliveProps);
81+
}
82+
83+
if (keepAliveProps && keepAliveProps[MySQL2DriverDialect.KEEP_ALIVE_PROPERTY_NAME] !== undefined) {
8084
throw new UnsupportedMethodError("Keep alive configuration is not supported for MySQL2.");
8185
}
8286
}

pg/lib/dialect/node_postgres_driver_dialect.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class NodePostgresDriverDialect implements DriverDialect {
4141
const driverProperties = WrapperProperties.removeWrapperProperties(props);
4242
this.setKeepAliveProperties(driverProperties, props.get(WrapperProperties.KEEPALIVE_PROPERTIES.name));
4343
this.setConnectTimeout(driverProperties, props.get(WrapperProperties.WRAPPER_CONNECT_TIMEOUT.name));
44-
this.setQueryTimeout(driverProperties, props.get(WrapperProperties.WRAPPER_QUERY_TIMEOUT.name));
44+
this.setQueryTimeout(driverProperties, undefined, props.get(WrapperProperties.WRAPPER_QUERY_TIMEOUT.name));
4545
const targetClient = new pkgPg.Client(Object.fromEntries(driverProperties.entries()));
4646
await targetClient.connect();
4747
return Promise.resolve(new PgClientWrapper(targetClient, hostInfo, props));
@@ -83,13 +83,17 @@ export class NodePostgresDriverDialect implements DriverDialect {
8383
return;
8484
}
8585

86-
const keepAlive = keepAliveProps.get(NodePostgresDriverDialect.KEEP_ALIVE_PROPERTY_NAME);
87-
const keepAliveInitialDelayMillis = keepAliveProps.get(NodePostgresDriverDialect.KEEP_ALIVE_INITIAL_DELAY_MILLIS_PROPERTY_NAME);
86+
if (keepAliveProps instanceof Map) {
87+
keepAliveProps = Object.fromEntries(keepAliveProps);
88+
}
89+
90+
const keepAlive = keepAliveProps[NodePostgresDriverDialect.KEEP_ALIVE_PROPERTY_NAME];
91+
const keepAliveInitialDelayMillis = keepAliveProps[NodePostgresDriverDialect.KEEP_ALIVE_INITIAL_DELAY_MILLIS_PROPERTY_NAME];
8892

89-
if (keepAlive) {
93+
if (keepAlive !== undefined) {
9094
props.set(NodePostgresDriverDialect.KEEP_ALIVE_PROPERTY_NAME, keepAlive);
9195
}
92-
if (keepAliveInitialDelayMillis) {
96+
if (keepAliveInitialDelayMillis !== undefined) {
9397
props.set(NodePostgresDriverDialect.KEEP_ALIVE_INITIAL_DELAY_MILLIS_PROPERTY_NAME, keepAliveInitialDelayMillis);
9498
}
9599
}

tests/unit/aurora_connection_tracker.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import { ClientWrapper } from "../../common/lib/client_wrapper";
2929
import { HostInfo } from "../../common/lib/host_info";
3030
import { MySQLClientWrapper } from "../../common/lib/mysql_client_wrapper";
3131
import { jest } from "@jest/globals";
32+
import { DriverDialect } from "../../common/lib/driver_dialect/driver_dialect";
33+
import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect";
3234

3335
const props = new Map<string, any>();
3436
const SQL_ARGS = ["sql"];
@@ -48,8 +50,9 @@ const mockRdsUtils = mock(RdsUtils);
4850
const mockClient = mock(AwsClient);
4951
const mockHostInfo = mock(HostInfo);
5052

53+
const mockDriverDialect: DriverDialect = mock(MySQL2DriverDialect);
5154
const mockClientInstance = instance(mockClient);
52-
const mockClientWrapper: ClientWrapper = new MySQLClientWrapper(undefined, mockHostInfo, props);
55+
const mockClientWrapper: ClientWrapper = new MySQLClientWrapper(undefined, mockHostInfo, props, mockDriverDialect);
5356

5457
mockClientInstance.targetClient = mockClientWrapper;
5558

tests/unit/aurora_initial_connection_strategy_plugin.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { AwsWrapperError } from "../../common/lib/utils/errors";
3030
import { MySQLClientWrapper } from "../../common/lib/mysql_client_wrapper";
3131
import { jest } from "@jest/globals";
3232
import { PgClientWrapper } from "../../common/lib/pg_client_wrapper";
33+
import { DriverDialect } from "../../common/lib/driver_dialect/driver_dialect";
34+
import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect";
3335

3436
const mockPluginService = mock(PluginService);
3537
const mockHostListProviderService = mock<HostListProviderService>();
@@ -48,6 +50,7 @@ const hostInfo = hostInfoBuilder.withHost("host").build();
4850

4951
const writerHostInfo = hostInfoBuilder.withHost("host").withRole(HostRole.WRITER).build();
5052
const readerHostInfo = hostInfoBuilder.withHost("host").withHost(HostRole.READER).build();
53+
const mockDriverDialect: DriverDialect = mock(MySQL2DriverDialect);
5154

5255
describe("Aurora initial connection strategy plugin", () => {
5356
let props: Map<string, any>;
@@ -62,8 +65,8 @@ describe("Aurora initial connection strategy plugin", () => {
6265
plugin.initHostProvider(hostInfo, props, instance(mockHostListProviderService), mockFunc);
6366
WrapperProperties.OPEN_CONNECTION_RETRY_TIMEOUT_MS.set(props, 1000);
6467

65-
writerClient = new MySQLClientWrapper(undefined, writerHostInfo, new Map<string, any>());
66-
readerClient = new MySQLClientWrapper(undefined, readerHostInfo, new Map<string, any>());
68+
writerClient = new MySQLClientWrapper(undefined, writerHostInfo, new Map<string, any>(), mockDriverDialect);
69+
readerClient = new MySQLClientWrapper(undefined, readerHostInfo, new Map<string, any>(), mockDriverDialect);
6770
});
6871

6972
afterEach(() => {

tests/unit/database_dialect.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,7 @@ describe("test database dialects", () => {
278278
databaseType,
279279
expectedDialect!.dialects,
280280
props,
281-
mockDriverDialect,
282-
null
281+
mockDriverDialect
283282
);
284283
await pluginService.updateDialect(mockClientWrapper);
285284
expect(pluginService.getDialect()).toBe(expectedDialectClass);

tests/unit/driver_dialect.test.ts

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License").
5+
You may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import { mock } from "ts-mockito";
18+
import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect";
19+
import { HostInfo } from "../../common/lib/host_info";
20+
import { UnsupportedMethodError } from "../../common/lib/utils/errors";
21+
import { NodePostgresDriverDialect } from "../../pg/lib/dialect/node_postgres_driver_dialect";
22+
23+
const mockHostInfo: HostInfo = mock(HostInfo);
24+
const emptyProps: Map<string, any> = new Map<string, any>();
25+
26+
describe("driverDialectTest", () => {
27+
it("test_connectWithKeepAliveProps_MySQL_shouldThrow", async () => {
28+
const keepAliveProps = new Map<string, any>([
29+
["keepAlive", true],
30+
["keepAliveInitialDelayMillis", 1234]
31+
]);
32+
33+
const props = new Map<string, any>([["wrapperKeepAliveProperties", keepAliveProps]]);
34+
35+
const dialect = new MySQL2DriverDialect();
36+
const unsupportedError = new UnsupportedMethodError("Keep alive configuration is not supported for MySQL2.");
37+
38+
await expect(dialect.connect(mockHostInfo, props)).rejects.toThrow(unsupportedError);
39+
40+
const keepAliveObj = {
41+
keepAlive: true,
42+
keepAliveInitialDelayMillis: 1234
43+
};
44+
45+
const propsWithObj = new Map<string, any>([["wrapperKeepAliveProperties", keepAliveObj]]);
46+
47+
await expect(dialect.connect(mockHostInfo, propsWithObj)).rejects.toThrow(unsupportedError);
48+
});
49+
50+
it("test_connectWithKeepAliveProps_PG_shouldSucceed", async () => {
51+
const keepAliveMap = new Map<string, any>([
52+
["keepAlive", true],
53+
["keepAliveInitialDelayMillis", 1234]
54+
]);
55+
56+
const dialect = new NodePostgresDriverDialect();
57+
58+
dialect.setKeepAliveProperties(emptyProps, keepAliveMap);
59+
expect(emptyProps.get("keepAlive")).toBe(true);
60+
expect(emptyProps.get("keepAliveInitialDelayMillis")).toBe(1234);
61+
62+
emptyProps.clear();
63+
64+
const keepAliveObj = {
65+
keepAlive: true,
66+
keepAliveInitialDelayMillis: 1234
67+
};
68+
69+
dialect.setKeepAliveProperties(emptyProps, keepAliveObj);
70+
expect(emptyProps.get("keepAlive")).toBe(true);
71+
expect(emptyProps.get("keepAliveInitialDelayMillis")).toBe(1234);
72+
});
73+
});

tests/unit/failover_plugin.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ import { Messages } from "../../common/lib/utils/messages";
3838
import { HostChangeOptions } from "../../common/lib/host_change_options";
3939
import { NullTelemetryFactory } from "../../common/lib/utils/telemetry/null_telemetry_factory";
4040
import { MySQLClientWrapper } from "../../common/lib/mysql_client_wrapper";
41+
import { DriverDialect } from "../../common/lib/driver_dialect/driver_dialect";
42+
import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect";
4143

4244
const builder = new HostInfoBuilder({ hostAvailabilityStrategy: new SimpleHostAvailabilityStrategy() });
4345

@@ -52,8 +54,9 @@ let mockWriterFailoverHandlerInstance;
5254
const mockWriterFailoverHandler: ClusterAwareWriterFailoverHandler = mock(ClusterAwareWriterFailoverHandler);
5355
const mockReaderResult: ReaderFailoverResult = mock(ReaderFailoverResult);
5456
const mockWriterResult: WriterFailoverResult = mock(WriterFailoverResult);
57+
const mockDriverDialect: DriverDialect = mock(MySQL2DriverDialect);
5558

56-
const mockClientWrapper = new MySQLClientWrapper(undefined, mockHostInfo, new Map<string, any>());
59+
const mockClientWrapper = new MySQLClientWrapper(undefined, mockHostInfo, new Map<string, any>(), mockDriverDialect);
5760

5861
const properties: Map<string, any> = new Map();
5962

tests/unit/writer_failover_handler.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { WriterFailoverResult } from "../../common/lib/plugins/failover/writer_f
2828
import { ClientWrapper } from "../../common/lib/client_wrapper";
2929
import { PgDatabaseDialect } from "../../pg/lib/dialect/pg_database_dialect";
3030
import { MySQLClientWrapper } from "../../common/lib/mysql_client_wrapper";
31+
import { DriverDialect } from "../../common/lib/driver_dialect/driver_dialect";
3132
import { MySQL2DriverDialect } from "../../mysql/lib/dialect/mysql2_driver_dialect";
3233

3334
const builder = new HostInfoBuilder({ hostAvailabilityStrategy: new SimpleHostAvailabilityStrategy() });
@@ -45,6 +46,7 @@ const mockClient = mock(AwsPGClient); // Using AwsPGClient in order to have abst
4546
const mockClientInstance = instance(mockClient);
4647
const mockPluginService = mock(PluginService);
4748
const mockReaderFailover = mock(ClusterAwareReaderFailoverHandler);
49+
const mockDriverDialect: DriverDialect = mock(MySQL2DriverDialect);
4850

4951
const mockTargetClient = { client: 123 };
5052
const mockClientWrapper: ClientWrapper = new MySQLClientWrapper(

0 commit comments

Comments
 (0)