Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2ec417e
Add AWS Authentication parameters to DSN UI (#115)
justing-bq Mar 8, 2023
4e8126f
Refactor MYSQL_PROXY (#118)
yanw-bq Mar 16, 2023
201ebb8
Further refactor MYSQL_PROXY (#119)
yanw-bq Mar 18, 2023
c8b1fde
AWS SDK helper class (#123)
yanw-bq Mar 29, 2023
3547f49
Implement IAM Authentication (#120)
justing-bq Mar 29, 2023
439a5f2
Add Authentication Parameters to ConnectionStringBuilder (#124)
justing-bq Mar 30, 2023
14d5806
Secrets Manager Proxy (#121)
yanw-bq Mar 30, 2023
2cae844
Secrets manager integration test (#127)
yanw-bq Apr 1, 2023
2752b3c
IAM Authentication Integration Tests (#126)
justing-bq Apr 1, 2023
8644fbb
Refactor Integration Tests (#128)
justing-bq Apr 4, 2023
306afd9
Fix installer (#129)
yanw-bq Apr 4, 2023
cfbdf15
Adjust DSN config UI for AWS Authentication (#130)
justing-bq Apr 5, 2023
99c1659
Documentation for AWS Authentication (#131)
justing-bq Apr 6, 2023
3d2d01c
rename windows installer (#132)
yanw-bq Apr 6, 2023
6f317f9
Update license (#133)
yanw-bq Apr 11, 2023
1ea8e3d
Parse Region from Secret if User does not provide Region (#134)
justing-bq Apr 12, 2023
7832b5c
Fix SQLCancel not going through proxy (#135)
yanw-bq Apr 12, 2023
97020b1
Fix typo in doc
Apr 12, 2023
b55d9c6
Implement ENABLE_STRICT_READER_FAILOVER user parameter (#136)
justing-bq Apr 13, 2023
1a69f6f
Override change_user() in IAM/Secrets Manager proxy (#137)
yanw-bq Apr 14, 2023
b1d097b
Fix failover timeout not obeyed (#138)
yanw-bq Apr 24, 2023
e7b7bf7
China endpoint support (#140)
yanw-bq Apr 26, 2023
1543087
Verify Writer Cluster Connections (#139)
justing-bq Apr 27, 2023
17a306c
Fix shadowing member variables causing null pointer exception (#148)
yanw-bq May 9, 2023
0a8aaca
Fix monitor timeout (#149)
yanw-bq May 11, 2023
8b9c4cd
rename a component that may have name collision issue on mac (#151)
yanw-bq May 12, 2023
a89dff1
Remove is_multi_writer flag and check for last updated writer
May 15, 2023
381794b
Merge branch 'dev' of github.com:awslabs/aws-mysql-odbc into is-multi…
May 15, 2023
b6f1cb0
Fix tests
May 15, 2023
725af3b
Remove uneeded line
May 16, 2023
790b2bb
Merge branch 'dev' into is-multi-writer-removal
alexr-bq May 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions driver/cluster_topology_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ CLUSTER_TOPOLOGY_INFO::CLUSTER_TOPOLOGY_INFO() {
CLUSTER_TOPOLOGY_INFO::CLUSTER_TOPOLOGY_INFO(const CLUSTER_TOPOLOGY_INFO& src_info)
: current_reader{src_info.current_reader},
last_updated{src_info.last_updated},
last_used_reader{src_info.last_used_reader},
is_multi_writer_cluster{src_info.is_multi_writer_cluster} {
last_used_reader{src_info.last_used_reader} {
for (auto host_info_source : src_info.writers) {
writers.push_back(std::make_shared<HOST_INFO>(*host_info_source)); //default copy
}
Expand Down
1 change: 0 additions & 1 deletion driver/cluster_topology_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class CLUSTER_TOPOLOGY_INFO {
std::shared_ptr<HOST_INFO> get_reader(int i);
std::vector<std::shared_ptr<HOST_INFO>> get_writers();
std::vector<std::shared_ptr<HOST_INFO>> get_readers();
bool is_multi_writer_cluster = false;

private:
int current_reader = -1;
Expand Down
4 changes: 1 addition & 3 deletions driver/failover_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,7 @@ bool FAILOVER_HANDLER::is_failover_enabled() {
return (dbc != nullptr && ds != nullptr &&
ds->enable_cluster_failover &&
m_is_cluster_topology_available &&
!m_is_rds_proxy &&
!m_is_multi_writer_cluster);
!m_is_rds_proxy);
}

bool FAILOVER_HANDLER::is_rds() { return m_is_rds; }
Expand All @@ -537,7 +536,6 @@ void FAILOVER_HANDLER::initialize_topology() {

current_topology = topology_service->get_topology(dbc->connection_proxy, false);
if (current_topology) {
m_is_multi_writer_cluster = current_topology->is_multi_writer_cluster;
m_is_cluster_topology_available = current_topology->total_hosts() > 0;
MYLOG_DBC_TRACE(dbc,
"[FAILOVER_HANDLER] m_is_cluster_topology_available=%s",
Expand Down
22 changes: 13 additions & 9 deletions driver/topology_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -279,27 +279,31 @@ std::shared_ptr<CLUSTER_TOPOLOGY_INFO> TOPOLOGY_SERVICE::query_for_topology(CONN
topology_info = std::make_shared<CLUSTER_TOPOLOGY_INFO>();
std::map<std::string, std::shared_ptr<HOST_INFO>> instances;
MYSQL_ROW row;
int writer_count = 0;
std::shared_ptr<HOST_INFO> latest_writer = nullptr;
while ((row = connection_proxy->fetch_row(result))) {
std::shared_ptr<HOST_INFO> host_info = create_host(row);
if (host_info) {
// Only mark the first/latest writer as true writer
if (host_info->is_host_writer()) {
if (writer_count > 0) {
host_info->mark_as_writer(false);
// Only mark the latest writer as true writer. Ignore other writers (possible stale records, multi-writer not supported)
// Date in lexographic order, so str comparison works for most recent date
if (!latest_writer || host_info->last_updated > latest_writer->last_updated) {
latest_writer = host_info;
}
writer_count++;
}
// Add to topology if instance not seen before
if (!TOPOLOGY_SERVICE::does_instance_exist(instances, host_info)) {
else if (!TOPOLOGY_SERVICE::does_instance_exist(instances, host_info)) {
// Add readers to topology if instance not seen before
topology_info->add_host(host_info);
}
}
}
if (latest_writer && !TOPOLOGY_SERVICE::does_instance_exist(instances, latest_writer))
{
topology_info->add_host(latest_writer);
}

connection_proxy->free_result(result);

topology_info->is_multi_writer_cluster = writer_count > 1;
if (writer_count == 0) {
if (!latest_writer) { // No writer found
MYLOG_TRACE(logger, dbc_id,
"[TOPOLOGY_SERVICE] The topology query returned an "
"invalid topology - no writer instance detected");
Expand Down
31 changes: 0 additions & 31 deletions unit_testing/failover_handler_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -345,37 +345,6 @@ TEST_F(FailoverHandlerTest, RDS_ReaderCluster) {
EXPECT_TRUE(failover_handler.is_failover_enabled());
}

TEST_F(FailoverHandlerTest, RDS_MultiWriterCluster) {
SQLCHAR server[] = "my-cluster-name.cluster-XYZ.us-east-2.rds.amazonaws.com";

ds_setattr_from_utf8(&ds->server, server);
ds->port = 1234;
ds->enable_cluster_failover = true;

EXPECT_CALL(*mock_connection_handler, do_connect_impl(dbc, ds, false, false)).WillOnce(Return(SQL_SUCCESS));

auto multi_writer_topology = std::make_shared<CLUSTER_TOPOLOGY_INFO>();
multi_writer_topology->add_host(writer_host);
multi_writer_topology->add_host(reader_host);
multi_writer_topology->is_multi_writer_cluster = true;

EXPECT_CALL(*mock_ts, get_topology(_, false))
.WillOnce(Return(multi_writer_topology));
EXPECT_CALL(*mock_ts, set_cluster_instance_template(_)).Times(AtLeast(1));
EXPECT_CALL(*mock_ts,
set_cluster_id(StrEq(
"my-cluster-name.cluster-XYZ.us-east-2.rds.amazonaws.com:1234")))
.Times(AtLeast(1));

FAILOVER_HANDLER failover_handler(dbc, ds, mock_connection_handler, mock_ts, mock_metrics);
failover_handler.init_connection();

EXPECT_TRUE(failover_handler.is_rds());
EXPECT_FALSE(failover_handler.is_rds_proxy());
EXPECT_TRUE(failover_handler.is_cluster_topology_available());
EXPECT_FALSE(failover_handler.is_failover_enabled());
}

TEST_F(FailoverHandlerTest, ReconnectWithFailoverSettings) {
SQLCHAR server[] = "10.10.10.10";
SQLCHAR host_pattern[] = "?.my-custom-domain.com";
Expand Down
19 changes: 8 additions & 11 deletions unit_testing/topology_service_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ namespace {
char* reader2[4] = { "replica-instance-2", "Replica", "2020-09-15 17:51:53.0", "13.5" };
char* writer[4] = { "writer-instance", WRITER_SESSION_ID, "2020-09-15 17:51:53.0", "13.5" };
char* writer1[4] = { "writer-instance-1", WRITER_SESSION_ID, "2020-09-15 17:51:53.0", "13.5" };
char* writer2[4] = { "writer-instance-2", WRITER_SESSION_ID, "2020-09-15 17:51:53.0", "13.5" };
char* writer3[4] = { "writer-instance-3", WRITER_SESSION_ID, "2020-09-15 17:51:53.0", "13.5" };
char* writer2[4] = { "writer-instance-2", WRITER_SESSION_ID, "2020-09-15 17:51:54.0", "13.5" };
char* writer3[4] = { "writer-instance-3", WRITER_SESSION_ID, "2020-09-15 17:51:55.0", "13.5" };
} // namespace

class TopologyServiceTest : public testing::Test {
Expand Down Expand Up @@ -101,7 +101,6 @@ TEST_F(TopologyServiceTest, TopologyQuery) {
std::shared_ptr<CLUSTER_TOPOLOGY_INFO> topology = ts->get_topology(mock_proxy);
ASSERT_NE(nullptr, topology);

EXPECT_FALSE(topology->is_multi_writer_cluster);
EXPECT_EQ(3, topology->total_hosts());
EXPECT_EQ(2, topology->num_readers());

Expand All @@ -116,7 +115,7 @@ TEST_F(TopologyServiceTest, TopologyQuery) {
EXPECT_EQ("13.5", writer_host->replica_lag);
}

TEST_F(TopologyServiceTest, MultiWriter) {
TEST_F(TopologyServiceTest, StaleRecord) {
EXPECT_CALL(*mock_proxy, query(StrEq(RETRIEVE_TOPOLOGY_SQL)))
.WillRepeatedly(Return(0));
EXPECT_CALL(*mock_proxy, fetch_row(_))
Expand All @@ -128,18 +127,17 @@ TEST_F(TopologyServiceTest, MultiWriter) {
std::shared_ptr<CLUSTER_TOPOLOGY_INFO> topology = ts->get_topology(mock_proxy);
ASSERT_NE(nullptr, topology);

EXPECT_TRUE(topology->is_multi_writer_cluster);
EXPECT_EQ(3, topology->total_hosts());
EXPECT_EQ(2, topology->num_readers()); // 2 writers are marked as readers
EXPECT_EQ(1, topology->total_hosts());
EXPECT_EQ(0, topology->num_readers());

std::shared_ptr<HOST_INFO> writer_host = topology->get_writer();
ASSERT_NE(nullptr, writer_host);

EXPECT_EQ("writer-instance-1.XYZ.us-east-2.rds.amazonaws.com", writer_host->get_host());
EXPECT_EQ("writer-instance-3.XYZ.us-east-2.rds.amazonaws.com", writer_host->get_host());
EXPECT_EQ(1234, writer_host->get_port());
EXPECT_EQ("writer-instance-1", writer_host->instance_name);
EXPECT_EQ("writer-instance-3", writer_host->instance_name);
EXPECT_EQ(WRITER_SESSION_ID, writer_host->session_id);
EXPECT_EQ("2020-09-15 17:51:53.0", writer_host->last_updated);
EXPECT_EQ("2020-09-15 17:51:55.0", writer_host->last_updated); // Only latest updated writer is counted
EXPECT_EQ("13.5", writer_host->replica_lag);
}

Expand All @@ -155,7 +153,6 @@ TEST_F(TopologyServiceTest, DuplicateInstances) {
std::shared_ptr<CLUSTER_TOPOLOGY_INFO> topology = ts->get_topology(mock_proxy);
ASSERT_NE(nullptr, topology);

EXPECT_TRUE(topology->is_multi_writer_cluster);
EXPECT_EQ(1, topology->total_hosts());
EXPECT_EQ(0, topology->num_readers());

Expand Down