use of com.mysql.cj.conf.ConnectionUrl in project gocd by gocd.
the class MySQLBackupProcessor method createProcessExecutor.
private ProcessExecutor createProcessExecutor(File targetDir, DbProperties dbProperties) {
ConnectionUrl connectionUrlInstance = ConnectionUrl.getConnectionUrlInstance(dbProperties.url(), dbProperties.connectionProperties());
LinkedHashMap<String, String> env = new LinkedHashMap<>();
if (isNotBlank(dbProperties.password())) {
env.put("MYSQL_PWD", dbProperties.password());
}
// override with any user specified environment
env.putAll(dbProperties.extraBackupEnv());
ArrayList<String> argv = new ArrayList<>();
argv.add("mysqldump");
String dbName = connectionUrlInstance.getDatabase();
HostInfo mainHost = connectionUrlInstance.getMainHost();
if (mainHost != null) {
argv.add("--host=" + mainHost.getHost());
argv.add("--port=" + mainHost.getPort());
}
if (isNotBlank(dbProperties.user())) {
argv.add("--user=" + dbProperties.user());
}
// append any user specified args for mysqldump
if (isNotBlank(dbProperties.extraBackupCommandArgs())) {
Collections.addAll(argv, Commandline.translateCommandline(dbProperties.extraBackupCommandArgs()));
}
argv.add("--result-file=" + new File(targetDir, "db." + dbName).toString());
argv.add(connectionUrlInstance.getDatabase());
ProcessExecutor processExecutor = new ProcessExecutor();
processExecutor.redirectOutputAlsoTo(Slf4jStream.of(getClass()).asDebug());
processExecutor.redirectErrorAlsoTo(Slf4jStream.of(getClass()).asDebug());
processExecutor.environment(env);
processExecutor.command(argv);
return processExecutor;
}
use of com.mysql.cj.conf.ConnectionUrl in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug99076.
/**
* Tests fix for Bug#99076 (31083755), Unclear exception/error when connecting with jdbc:mysql to a mysqlx port.
*
* @throws Exception
*/
@Test
public void testBug99076() throws Exception {
assumeTrue(versionMeetsMinimum(8, 0, 16), "MySQL 8.0.16+ is required to run this test.");
String xUrl = System.getProperty(PropertyDefinitions.SYSP_testsuite_url_mysqlx);
assumeTrue(xUrl != null && xUrl.length() != 0, PropertyDefinitions.SYSP_testsuite_url_mysqlx + " must be set to run this test.");
final ConnectionUrl conUrl = ConnectionUrl.getConnectionUrlInstance(xUrl, null);
final HostInfo hostInfo = conUrl.getMainHost();
final String host = hostInfo.getHost();
final int port = hostInfo.getPort();
assertThrows(SQLNonTransientConnectionException.class, "Unsupported protocol version: 11\\. Likely connecting to an X Protocol port\\.", () -> getConnectionWithProps("jdbc:mysql://" + host + ":" + port, ""));
}
use of com.mysql.cj.conf.ConnectionUrl in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug22678872.
/**
* Tests fix for Bug#22678872 - NPE DURING UPDATE WITH FABRIC.
*
* Although the bug was reported against a Fabric connection, it can't be systematically reproduced there. A deep analysis revealed that the bug occurs due
* to a defect in the dynamic hosts management of replication connections, specifically when one or both of the internal hosts lists (sources and/or
* replicas)
* becomes empty. As such, the bug is reproducible and tested resorting to replication connections and dynamic hosts management of replication connections
* only.
* This test reproduces the relevant steps involved in the original stack trace, originated in the FabricMySQLConnectionProxy.getActiveConnection() code:
* - The replication connections are initialized with the same properties as in a Fabric connection.
* - Hosts are removed using the same options as in a Fabric connection.
* - The method tested after any host change is Connection.setAutoCommit(), which is the method that triggered the original NPE.
*
* @throws Exception
*/
@Test
public void testBug22678872() throws Exception {
final Properties connProps = getPropertiesFromTestsuiteUrl();
final String host = connProps.getProperty(PropertyKey.HOST.getKeyName(), "localhost");
final String port = connProps.getProperty(PropertyKey.PORT.getKeyName(), "3306");
final String hostPortPair = host + ":" + port;
final String database = connProps.getProperty(PropertyKey.DBNAME.getKeyName());
final String username = connProps.getProperty(PropertyKey.USER.getKeyName());
final String password = connProps.getProperty(PropertyKey.PASSWORD.getKeyName(), "");
final String connectionTimeZone = connProps.getProperty(PropertyKey.connectionTimeZone.getKeyName());
final Map<String, String> props = new HashMap<>();
props.put(PropertyKey.USER.getKeyName(), username);
props.put(PropertyKey.PASSWORD.getKeyName(), password);
props.put(PropertyKey.DBNAME.getKeyName(), database);
props.put(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.put(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
// Speed up the test execution.
props.put(PropertyKey.loadBalanceHostRemovalGracePeriod.getKeyName(), "0");
// Replicate the properties used in FabricMySQLConnectionProxy.getActiveConnection().
props.put(PropertyKey.retriesAllDown.getKeyName(), "1");
props.put(PropertyKey.allowSourceDownConnections.getKeyName(), "true");
props.put(PropertyKey.allowReplicaDownConnections.getKeyName(), "true");
props.put(PropertyKey.readFromSourceWhenNoReplicas.getKeyName(), "true");
if (connectionTimeZone != null) {
props.put(PropertyKey.connectionTimeZone.getKeyName(), connectionTimeZone);
}
ConnectionUrl replConnectionUrl = new ReplicationConnectionUrl(Collections.<HostInfo>emptyList(), Collections.<HostInfo>emptyList(), props);
String replConnGroup = "";
final List<HostInfo> emptyHostsList = Collections.emptyList();
final List<HostInfo> singleHostList = Collections.singletonList(replConnectionUrl.getHostOrSpawnIsolated(hostPortPair));
/*
* Case A:
* - Initialize a replication connection with sources and replicas lists empty.
*/
replConnGroup = "Bug22678872A";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
assertThrows(SQLException.class, "A replication connection cannot be initialized without source hosts and replica hosts, simultaneously\\.", new Callable<Void>() {
public Void call() throws Exception {
ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(emptyHostsList, emptyHostsList, props));
return null;
}
});
/*
* Case B:
* - Initialize a replication connection with one source and no replicas.
* - Then remove the source and add it back as a replica, followed by a promotion to source.
*/
replConnGroup = "Bug22678872B";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
final ReplicationConnection testConnB = ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(singleHostList, emptyHostsList, props));
// Connected to a source host.
assertTrue(testConnB.isSourceConnection());
assertFalse(testConnB.isReadOnly());
// This was the method that triggered the original NPE.
testConnB.setAutoCommit(false);
ReplicationConnectionGroupManager.removeSourceHost(replConnGroup, hostPortPair, false);
assertThrows(SQLException.class, "The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists\\.", new Callable<Void>() {
public Void call() throws Exception {
// JDBC interface method throws SQLException.
testConnB.setAutoCommit(false);
return null;
}
});
assertThrows(IllegalStateException.class, "The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists\\.", new Callable<Void>() {
public Void call() throws Exception {
// Some Connector/J internal methods don't throw compatible exceptions. They have to be wrapped.
testConnB.isSourceConnection();
return null;
}
});
ReplicationConnectionGroupManager.addReplicaHost(replConnGroup, hostPortPair);
// Connected to a replica host.
assertFalse(testConnB.isSourceConnection());
assertTrue(testConnB.isReadOnly());
testConnB.setAutoCommit(false);
ReplicationConnectionGroupManager.promoteReplicaToSource(replConnGroup, hostPortPair);
// Connected to a source host.
assertTrue(testConnB.isSourceConnection());
assertFalse(testConnB.isReadOnly());
testConnB.setAutoCommit(false);
testConnB.close();
/*
* Case C:
* - Initialize a replication connection with no sources and one replica.
* - Then remove the replica and add it back, followed by a promotion to source.
*/
replConnGroup = "Bug22678872C";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
final ReplicationConnection testConnC = ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(emptyHostsList, singleHostList, props));
// Connected to a replica host.
assertFalse(testConnC.isSourceConnection());
assertTrue(testConnC.isReadOnly());
testConnC.setAutoCommit(false);
ReplicationConnectionGroupManager.removeReplicaHost(replConnGroup, hostPortPair, true);
assertThrows(SQLException.class, "The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists\\.", new Callable<Void>() {
public Void call() throws Exception {
testConnC.setAutoCommit(false);
return null;
}
});
ReplicationConnectionGroupManager.addReplicaHost(replConnGroup, hostPortPair);
// Connected to a replica host.
assertFalse(testConnC.isSourceConnection());
assertTrue(testConnC.isReadOnly());
testConnC.setAutoCommit(false);
ReplicationConnectionGroupManager.promoteReplicaToSource(replConnGroup, hostPortPair);
// Connected to a source host ...
assertTrue(testConnC.isSourceConnection());
// ... but the connection is read-only because it was initialized with no sources.
assertTrue(testConnC.isReadOnly());
testConnC.setAutoCommit(false);
testConnC.close();
/*
* Case D:
* - Initialize a replication connection with one source and one replica.
* - Then remove the source host, followed by removing the replica host.
* - Finally add the replica host back and promote it to source.
*/
replConnGroup = "Bug22678872D";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
final ReplicationConnection testConnD = ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(singleHostList, singleHostList, props));
// Connected to a source host.
assertTrue(testConnD.isSourceConnection());
assertFalse(testConnD.isReadOnly());
testConnD.setAutoCommit(false);
ReplicationConnectionGroupManager.removeSourceHost(replConnGroup, hostPortPair, false);
// Connected to a replica host.
assertFalse(testConnD.isSourceConnection());
assertTrue(testConnD.isReadOnly());
testConnD.setAutoCommit(false);
ReplicationConnectionGroupManager.removeReplicaHost(replConnGroup, hostPortPair, true);
assertThrows(SQLException.class, "The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists\\.", new Callable<Void>() {
public Void call() throws Exception {
testConnD.setAutoCommit(false);
return null;
}
});
ReplicationConnectionGroupManager.addReplicaHost(replConnGroup, hostPortPair);
// Connected to a replica host.
assertFalse(testConnD.isSourceConnection());
assertTrue(testConnD.isReadOnly());
testConnD.setAutoCommit(false);
ReplicationConnectionGroupManager.promoteReplicaToSource(replConnGroup, hostPortPair);
// Connected to a source host.
assertTrue(testConnD.isSourceConnection());
assertFalse(testConnD.isReadOnly());
testConnD.setAutoCommit(false);
testConnD.close();
/*
* Case E:
* - Initialize a replication connection with one source and one replica.
* - Set read-only.
* - Then remove the replica host, followed by removing the source host.
* - Finally add the replica host back and promote it to source.
*/
replConnGroup = "Bug22678872E";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
final ReplicationConnection testConnE = ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(singleHostList, singleHostList, props));
// Connected to a source host.
assertTrue(testConnE.isSourceConnection());
assertFalse(testConnE.isReadOnly());
testConnE.setAutoCommit(false);
testConnE.setReadOnly(true);
// Connected to a replica host.
assertFalse(testConnE.isSourceConnection());
assertTrue(testConnE.isReadOnly());
testConnE.setAutoCommit(false);
ReplicationConnectionGroupManager.removeReplicaHost(replConnGroup, hostPortPair, true);
// Connected to a source host...
assertTrue(testConnE.isSourceConnection());
// ... but the connection is read-only because that's how it was previously set.
assertTrue(testConnE.isReadOnly());
testConnE.setAutoCommit(false);
ReplicationConnectionGroupManager.removeSourceHost(replConnGroup, hostPortPair, false);
assertThrows(SQLException.class, "The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists\\.", new Callable<Void>() {
public Void call() throws Exception {
testConnE.setAutoCommit(false);
return null;
}
});
ReplicationConnectionGroupManager.addReplicaHost(replConnGroup, hostPortPair);
// Connected to a replica host.
assertFalse(testConnE.isSourceConnection());
assertTrue(testConnE.isReadOnly());
testConnE.setAutoCommit(false);
ReplicationConnectionGroupManager.promoteReplicaToSource(replConnGroup, hostPortPair);
// Connected to a source host...
assertTrue(testConnE.isSourceConnection());
// ... but the connection is read-only because that's how it was previously set.
assertTrue(testConnE.isReadOnly());
testConnE.setAutoCommit(false);
testConnE.close();
/*
* Case F:
* - Initialize a replication connection with one source and one replica.
* - Then remove the replica host, followed by removing the source host.
* - Finally add the replica host back and promote it to source.
*/
replConnGroup = "Bug22678872F";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
final ReplicationConnection testConnF = ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(singleHostList, singleHostList, props));
// Connected to a source host.
assertTrue(testConnF.isSourceConnection());
assertFalse(testConnF.isReadOnly());
testConnF.setAutoCommit(false);
ReplicationConnectionGroupManager.removeReplicaHost(replConnGroup, hostPortPair, true);
// Connected to a source host.
assertTrue(testConnF.isSourceConnection());
assertFalse(testConnF.isReadOnly());
testConnF.setAutoCommit(false);
ReplicationConnectionGroupManager.removeSourceHost(replConnGroup, hostPortPair, false);
assertThrows(SQLException.class, "The replication connection is an inconsistent state due to non existing hosts in both its internal hosts lists\\.", new Callable<Void>() {
public Void call() throws Exception {
testConnF.setAutoCommit(false);
return null;
}
});
ReplicationConnectionGroupManager.addReplicaHost(replConnGroup, hostPortPair);
// Connected to a replica host.
assertFalse(testConnF.isSourceConnection());
assertTrue(testConnF.isReadOnly());
testConnF.setAutoCommit(false);
ReplicationConnectionGroupManager.promoteReplicaToSource(replConnGroup, hostPortPair);
// Connected to a source host.
assertTrue(testConnF.isSourceConnection());
assertFalse(testConnF.isReadOnly());
testConnF.setAutoCommit(false);
testConnF.close();
/*
* Case G:
* This covers one corner case where the attribute ReplicationConnectionProxy.currentConnection can still be null even when there are known hosts. It
* results from a combination of empty hosts lists with downed hosts:
* - Start with one host in each list.
* - Switch to the replicas connection (set read-only).
* - Remove the source host.
* - Make the replica only unavailable.
* - Promote the replica host to source.
* - (At this point the active connection is "null")
* - Finally bring up the host again and check the connection status.
*/
// Use the UnreliableSocketFactory to control when the host must be downed.
props.remove(PropertyKey.replicationConnectionGroup.getKeyName());
props.put(PropertyKey.socketFactory.getKeyName(), "testsuite.UnreliableSocketFactory");
replConnectionUrl = new ReplicationConnectionUrl(Collections.<HostInfo>emptyList(), Collections.<HostInfo>emptyList(), props);
final String newHost = "bug22678872";
final String newHostPortPair = newHost + ":" + port;
final String hostConnected = UnreliableSocketFactory.getHostConnectedStatus(newHost);
final String hostNotConnected = UnreliableSocketFactory.getHostFailedStatus(newHost);
final List<HostInfo> newSingleHostList = Collections.singletonList(replConnectionUrl.getHostOrSpawnIsolated(newHostPortPair));
UnreliableSocketFactory.flushAllStaticData();
UnreliableSocketFactory.mapHost(newHost, host);
replConnGroup = "Bug22678872G";
props.put(PropertyKey.replicationConnectionGroup.getKeyName(), replConnGroup);
final ReplicationConnection testConnG = ReplicationConnectionProxy.createProxyInstance(new ReplicationConnectionUrl(newSingleHostList, newSingleHostList, props));
// Connected to a source host.
assertTrue(testConnG.isSourceConnection());
assertFalse(testConnG.isReadOnly());
testConnG.setAutoCommit(false);
// Two successful connections.
testBug22678872CheckConnectionsHistory(hostConnected, hostConnected);
testConnG.setReadOnly(true);
// Connected to a replica host.
assertFalse(testConnG.isSourceConnection());
assertTrue(testConnG.isReadOnly());
testConnG.setAutoCommit(false);
ReplicationConnectionGroupManager.removeSourceHost(replConnGroup, newHostPortPair, false);
// Connected to a replica host.
assertFalse(testConnG.isSourceConnection());
assertTrue(testConnG.isReadOnly());
testConnG.setAutoCommit(false);
// The host (currently a replica) goes down before being promoted to source.
UnreliableSocketFactory.downHost(newHost);
assertThrows(SQLException.class, "(?s)Communications link failure.*", new Callable<Void>() {
public Void call() throws Exception {
testConnG.promoteReplicaToSource(newHostPortPair);
return null;
}
});
// One failed connection attempt.
testBug22678872CheckConnectionsHistory(hostNotConnected);
// Actually not connected, but the promotion to source succeeded.
assertFalse(testConnG.isSourceConnection());
assertThrows(SQLException.class, "The connection is unusable at the current state\\. There may be no hosts to connect to or all hosts this " + "connection knows may be down at the moment\\.", new Callable<Void>() {
public Void call() throws Exception {
testConnG.setAutoCommit(false);
return null;
}
});
// Another failed connection attempt.
testBug22678872CheckConnectionsHistory(hostNotConnected);
assertThrows(SQLException.class, "(?s)Communications link failure.*", new Callable<Void>() {
public Void call() throws Exception {
// Triggers a reconnection that fails. The read-only state change is canceled by the exception.
testConnG.setReadOnly(false);
return null;
}
});
// This throws a comm failure because it tried to connect to the existing server and failed. The internal read-only state didn't change.
// Another failed connection attempt.
testBug22678872CheckConnectionsHistory(hostNotConnected);
// The host (currently a source) is up again.
UnreliableSocketFactory.dontDownHost(newHost);
// Triggers a reconnection that succeeds.
testConnG.setAutoCommit(false);
// One successful connection.
testBug22678872CheckConnectionsHistory(hostConnected);
// Connected to a source host...
assertTrue(testConnG.isSourceConnection());
// ... but the connection is read-only because that's how it was previously set.
assertTrue(testConnG.isReadOnly());
testConnG.setAutoCommit(false);
testConnG.close();
}
use of com.mysql.cj.conf.ConnectionUrl in project aws-mysql-jdbc by awslabs.
the class AuroraTopologyServiceTest method testForceUpdateQueryFailureWithSQLException.
@Test
public void testForceUpdateQueryFailureWithSQLException() throws SQLException {
final JdbcConnection mockConn = Mockito.mock(ConnectionImpl.class);
final String url = "jdbc:mysql:aws://my-cluster-name.cluster-XYZ.us-east-2.rds.amazonaws.com:1234/test";
final ConnectionUrl conStr = ConnectionUrl.getConnectionUrlInstance(url, new Properties());
final HostInfo mainHost = conStr.getMainHost();
final HostInfo clusterInstanceInfo = new HostInfo(conStr, "?.XYZ.us-east-2.rds.amazonaws.com", mainHost.getPort(), mainHost.getUser(), mainHost.getPassword(), mainHost.isPasswordless(), mainHost.getHostProperties());
spyProvider.setClusterInstanceTemplate(clusterInstanceInfo);
when(mockConn.createStatement()).thenThrow(SQLException.class);
assertThrows(SQLException.class, () -> spyProvider.getTopology(mockConn, true));
}
use of com.mysql.cj.conf.ConnectionUrl in project aws-mysql-jdbc by awslabs.
the class AuroraTopologyServiceTest method testProviderRefreshesTopology.
@Test
public void testProviderRefreshesTopology() throws SQLException, InterruptedException {
final JdbcConnection mockConn = Mockito.mock(ConnectionImpl.class);
final Statement mockStatement = Mockito.mock(StatementImpl.class);
final ResultSet mockResultSet = Mockito.mock(ResultSetImpl.class);
stubTopologyQuery(mockConn, mockStatement, mockResultSet);
final String url = "jdbc:mysql:aws://my-cluster-name.cluster-XYZ.us-east-2.rds.amazonaws.com:1234/test";
final ConnectionUrl conStr = ConnectionUrl.getConnectionUrlInstance(url, new Properties());
final HostInfo mainHost = conStr.getMainHost();
final HostInfo clusterInstanceInfo = new HostInfo(conStr, "?.XYZ.us-east-2.rds.amazonaws.com", mainHost.getPort(), mainHost.getUser(), mainHost.getPassword(), mainHost.isPasswordless(), mainHost.getHostProperties());
spyProvider.setClusterInstanceTemplate(clusterInstanceInfo);
spyProvider.setRefreshRate(1);
spyProvider.getTopology(mockConn, false);
Thread.sleep(2);
spyProvider.getTopology(mockConn, false);
verify(spyProvider, times(2)).queryForTopology(mockConn);
}
Aggregations