use of com.mysql.cj.jdbc.ha.ReplicationConnection in project aws-mysql-jdbc by awslabs.
the class StatementRegressionTest method testBug21876798.
/**
* Tests fix for Bug#21876798 - CONNECTOR/J WITH MYSQL FABRIC AND SPRING PRODUCES PROXY ERROR.
*
* Although this is a Fabric related bug we are able reproduce it using a couple of multi-host connections.
*
* @throws Exception
*/
@Test
public void testBug21876798() throws Exception {
createTable("testBug21876798", "(tst INT, val INT)");
for (int tst = 0; tst < 4; tst++) {
boolean useServerPrepStmts = (tst & 0x1) != 0;
boolean rewriteBatchedStatements = (tst & 0x2) != 0;
Properties props = new Properties();
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useServerPrepStmts));
props.setProperty(PropertyKey.rewriteBatchedStatements.getKeyName(), Boolean.toString(rewriteBatchedStatements));
String testCase = String.format("Case: %d [ %s | %s ]", tst, useServerPrepStmts ? "useSPS" : "-", rewriteBatchedStatements ? "rwBatchedStmts" : "-");
Connection highLevelConn = getLoadBalancedConnection(props);
assertTrue(highLevelConn.getClass().getName().startsWith("com.sun.proxy") || highLevelConn.getClass().getName().startsWith("$Proxy"), testCase);
Connection lowLevelConn = getSourceReplicaReplicationConnection(props);
// This simulates the behavior from Fabric connections that are causing the problem.
((ReplicationConnection) lowLevelConn).setProxy((JdbcConnection) highLevelConn);
// Insert data. We need at least 4 rows to force rewriting batch statements.
this.pstmt = lowLevelConn.prepareStatement("INSERT INTO testBug21876798 VALUES (?, ?)");
for (int i = 1; i <= 4; i++) {
this.pstmt.setInt(1, tst);
this.pstmt.setInt(2, i);
this.pstmt.addBatch();
}
this.pstmt.executeBatch();
// Check if data was inserted correctly.
this.rs = this.stmt.executeQuery("SELECT val FROM testBug21876798 WHERE tst = " + tst);
for (int i = 1; i <= 4; i++) {
assertTrue(this.rs.next(), testCase + "/Row#" + i);
assertEquals(i, this.rs.getInt(1), testCase + "/Row#" + i);
}
assertFalse(this.rs.next(), testCase);
// Update data. We need at least 4 rows to force rewriting batch statements.
this.pstmt = lowLevelConn.prepareStatement("UPDATE testBug21876798 SET val = ? WHERE tst = ? AND val = ?");
for (int i = 1; i <= 4; i++) {
this.pstmt.setInt(1, -i);
this.pstmt.setInt(2, tst);
this.pstmt.setInt(3, i);
this.pstmt.addBatch();
}
this.pstmt.executeBatch();
// Check if data was updated correctly.
this.rs = this.stmt.executeQuery("SELECT val FROM testBug21876798 WHERE tst = " + tst);
for (int i = 1; i <= 4; i++) {
assertTrue(this.rs.next(), testCase + "/Row#" + i);
assertEquals(-i, this.rs.getInt(1), testCase + "/Row#" + i);
}
assertFalse(this.rs.next(), testCase);
lowLevelConn.close();
highLevelConn.close();
}
}
use of com.mysql.cj.jdbc.ha.ReplicationConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug11879.
/**
* Tests fix for BUG#11879 -- ReplicationConnection won't switch to replica, throws "Catalog can't be null" exception.
*
* @throws Exception
*/
@Test
public void testBug11879() throws Exception {
Connection replConn = null;
try {
Properties props = new Properties();
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
replConn = getSourceReplicaReplicationConnection(props);
replConn.setReadOnly(true);
replConn.setReadOnly(false);
} finally {
if (replConn != null) {
replConn.close();
}
}
}
use of com.mysql.cj.jdbc.ha.ReplicationConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug15570.
/**
* Tests fix for BUG#15570 - ReplicationConnection incorrectly copies state, doesn't transfer connection context correctly when transitioning between the
* same read-only states.
*
* (note, this test will fail if the test user doesn't have permission to "USE 'mysql'".
*
* @throws Exception
*/
@Test
public void testBug15570() throws Exception {
Connection replConn = null;
try {
Properties props = new Properties();
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
replConn = getSourceReplicaReplicationConnection(props);
boolean dbMapsToSchema = ((JdbcConnection) replConn).getPropertySet().<DatabaseTerm>getEnumProperty(PropertyKey.databaseTerm).getValue() == DatabaseTerm.SCHEMA;
int sourceConnectionId = Integer.parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString());
replConn.setReadOnly(false);
assertEquals(sourceConnectionId, Integer.parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString()));
String currentDb = dbMapsToSchema ? replConn.getSchema() : replConn.getCatalog();
if (dbMapsToSchema) {
replConn.setSchema(currentDb);
assertEquals(currentDb, replConn.getSchema());
} else {
replConn.setCatalog(currentDb);
assertEquals(currentDb, replConn.getCatalog());
}
replConn.setReadOnly(true);
int replicaConnectionId = Integer.parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString());
// The following test is okay for now, as the chance of MySQL wrapping the connection id counter during our testsuite is very small.
// As per Bug#21286268 fix a Replication connection first initializes the Replicas sub-connection, then the Sources.
assertTrue(sourceConnectionId > replicaConnectionId, "Source id " + sourceConnectionId + " is not newer than replica id " + replicaConnectionId);
assertEquals(currentDb, dbMapsToSchema ? replConn.getSchema() : replConn.getCatalog());
String newDb = "mysql";
if (dbMapsToSchema) {
replConn.setSchema(newDb);
assertEquals(newDb, replConn.getSchema());
} else {
replConn.setCatalog(newDb);
assertEquals(newDb, replConn.getCatalog());
}
replConn.setReadOnly(true);
assertEquals(newDb, dbMapsToSchema ? replConn.getSchema() : replConn.getCatalog());
replConn.setReadOnly(false);
assertEquals(sourceConnectionId, Integer.parseInt(getSingleIndexedValueWithQuery(replConn, 1, "SELECT CONNECTION_ID()").toString()));
} finally {
if (replConn != null) {
replConn.close();
}
}
}
use of com.mysql.cj.jdbc.ha.ReplicationConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testReplicationConnectionGroupHostManagement.
@Test
public void testReplicationConnectionGroupHostManagement() throws Exception {
String replicationGroup1 = "rg1";
Properties props = new Properties();
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
props.setProperty(PropertyKey.replicationConnectionGroup.getKeyName(), replicationGroup1);
props.setProperty(PropertyKey.retriesAllDown.getKeyName(), "3");
props.setProperty(PropertyKey.loadBalanceHostRemovalGracePeriod.getKeyName(), "1");
ReplicationConnection conn2 = this.getUnreliableReplicationConnection(new String[] { "first", "second", "third" }, props);
assertNotNull(this.conn, "Connection should not be null");
conn2.setAutoCommit(false);
String port = getPort(props);
String firstHost = "first:" + port;
String secondHost = "second:" + port;
String thirdHost = "third:" + port;
// "first" should be source, "second" and "third" should be replicas.
assertEquals(1, ReplicationConnectionGroupManager.getConnectionCountWithHostAsSource(replicationGroup1, firstHost));
assertEquals(0, ReplicationConnectionGroupManager.getConnectionCountWithHostAsReplica(replicationGroup1, firstHost));
// remove "third" from replica pool:
conn2.removeReplica(thirdHost);
assertEquals(0, ReplicationConnectionGroupManager.getConnectionCountWithHostAsSource(replicationGroup1, thirdHost));
assertEquals(0, ReplicationConnectionGroupManager.getConnectionCountWithHostAsReplica(replicationGroup1, thirdHost));
// add "third" back into replica pool:
conn2.addReplicaHost(thirdHost);
assertEquals(0, ReplicationConnectionGroupManager.getConnectionCountWithHostAsSource(replicationGroup1, thirdHost));
assertEquals(1, ReplicationConnectionGroupManager.getConnectionCountWithHostAsReplica(replicationGroup1, thirdHost));
conn2.setReadOnly(false);
assertEquals(0, ReplicationConnectionGroupManager.getNumberOfSourcePromotion(replicationGroup1));
// failover to "second" as source
ReplicationConnectionGroupManager.promoteReplicaToSource(replicationGroup1, secondHost);
assertEquals(1, ReplicationConnectionGroupManager.getNumberOfSourcePromotion(replicationGroup1));
// "first" is still a source:
assertEquals(1, ReplicationConnectionGroupManager.getConnectionCountWithHostAsSource(replicationGroup1, firstHost));
assertEquals(0, ReplicationConnectionGroupManager.getConnectionCountWithHostAsReplica(replicationGroup1, firstHost));
assertEquals(1, ReplicationConnectionGroupManager.getConnectionCountWithHostAsSource(replicationGroup1, secondHost));
assertEquals(0, ReplicationConnectionGroupManager.getConnectionCountWithHostAsReplica(replicationGroup1, secondHost));
ReplicationConnectionGroupManager.removeSourceHost(replicationGroup1, firstHost);
conn2.createStatement().execute("SELECT 1");
assertFalse(conn2.isClosed());
conn2.commit();
// validate that queries are successful:
conn2.createStatement().execute("SELECT 1");
assertTrue(conn2.isHostSource(secondHost));
// source is now offline
UnreliableSocketFactory.downHost("second");
try {
Statement lstmt = conn2.createStatement();
lstmt.execute("SELECT 1");
fail("Should fail here due to closed connection");
} catch (SQLException sqlEx) {
assertEquals("08S01", sqlEx.getSQLState());
}
}
use of com.mysql.cj.jdbc.ha.ReplicationConnection in project aws-mysql-jdbc by awslabs.
the class BaseTestCase method getUnreliableReplicationConnection.
protected ReplicationConnection getUnreliableReplicationConnection(Set<MockConnectionConfiguration> configs, Properties props) throws Exception {
props = getHostFreePropertiesFromTestsuiteUrl(props);
props.setProperty(PropertyKey.socketFactory.getKeyName(), "testsuite.UnreliableSocketFactory");
HostInfo defaultHost = mainConnectionUrl.getMainHost();
String db = defaultHost.getDatabase();
String port = String.valueOf(defaultHost.getPort());
String host = defaultHost.getHost();
UnreliableSocketFactory.flushAllStaticData();
StringBuilder hostString = new StringBuilder();
String glue = "";
for (MockConnectionConfiguration config : configs) {
UnreliableSocketFactory.mapHost(config.hostName, host);
hostString.append(glue);
glue = ",";
if (config.port == null) {
config.port = (port == null ? "3306" : port);
}
hostString.append(config.getAddress());
if (config.isDowned) {
UnreliableSocketFactory.downHost(config.hostName);
}
}
return (ReplicationConnection) getConnectionWithProps(ConnectionUrl.Type.REPLICATION_CONNECTION.getScheme() + "//" + hostString.toString() + "/" + db, props);
}
Aggregations