Skip to content

Commit

Permalink
fix(jdbc-mysql): MySQL high availability not working in native mode
Browse files Browse the repository at this point in the history
Fixes quarkusio#7936

I was able to reproduce the error and adding the missing proxy registration fixed it.

To test the fix, using the below mysql replication setup:

```
docker run \
--name mysql_primary \
 -p 3306:3306 \
 -e MYSQL_ROOT_PASSWORD=hibernate_orm_test \
 -e MYSQL_USER=hibernate_orm_test \
 -e MYSQL_PASSWORD=hibernate_orm_test \
 -e MYSQL_DATABASE=hibernate_orm_test \
 -e REPLICATION_USER=hibernate_orm_test \
 -e REPLICATION_PASSWORD=hibernate_orm_test \
 actency/docker-mysql-replication:5.7
```

And on another terminal tab, run the following command:

```
 docker run \
 --name mysql_secondary \
  -p 3307:3306 \
 -e MYSQL_ROOT_PASSWORD=hibernate_orm_test \
 -e MYSQL_USER=hibernate_orm_test \
 -e MYSQL_PASSWORD=hibernate_orm_test \
 -e MYSQL_DATABASE=hibernate_orm_test \
 -e REPLICATION_USER=hibernate_orm_test \
 -e REPLICATION_PASSWORD=hibernate_orm_test \
 --link mysql_primary:master \
 actency/docker-mysql-replication:5.7
```

Open another terminal tab and launch jdbc-mysql integration tests with the following command
`cd integration-tests/jpa-mysql` and then open the configuration file and edit the jdbc url so that it points to:
```
jdbc:mysql:replication://localhost:3306,localhost:3307/hibernate_orm_test?connectTimeout=5000&socketTimeout=5000&retriesAllDown=3&allowMasterDownConnections=true&allowSlaveDownConnections=true&loadBalanceBlacklistTimeout=10000&readFromMasterWhenNoSlaves=true`
```

Then running
```
mvn clean install -Dnative -Dtest-mysql
```

Should pass successfully which was not the case previously as it was throwing missing proxy registration errors
  • Loading branch information
machi1990 committed Mar 22, 2020
1 parent 27ba363 commit 7ea24f5
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
package io.quarkus.jdbc.mysql.deployment;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.mysql.cj.MysqlConnection;
import com.mysql.cj.WarningListener;
import com.mysql.cj.conf.PropertySet;
import com.mysql.cj.jdbc.JdbcConnection;
import com.mysql.cj.jdbc.JdbcPreparedStatement;
import com.mysql.cj.jdbc.JdbcPropertySet;
import com.mysql.cj.jdbc.JdbcStatement;
import com.mysql.cj.jdbc.ha.LoadBalancedConnection;
import com.mysql.cj.jdbc.ha.ReplicationConnection;
import com.mysql.cj.jdbc.result.ResultSetInternalMethods;
import com.mysql.cj.protocol.Resultset;

import io.quarkus.agroal.deployment.JdbcDriverBuildItem;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.processor.BuiltinScope;
Expand All @@ -13,6 +32,7 @@
import io.quarkus.deployment.builditem.NativeImageEnableAllCharsetsBuildItem;
import io.quarkus.deployment.builditem.NativeImageEnableAllTimeZonesBuildItem;
import io.quarkus.deployment.builditem.SslNativeConfigBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageProxyDefinitionBuildItem;
import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem;
import io.quarkus.jdbc.mysql.runtime.MySQLAgroalConnectionConfigurer;
import io.quarkus.jdbc.mysql.runtime.MySQLRecorder;
Expand Down Expand Up @@ -62,4 +82,30 @@ NativeImageEnableAllCharsetsBuildItem enableAllCharsets() {
NativeImageEnableAllTimeZonesBuildItem enableAllTimeZones() {
return new NativeImageEnableAllTimeZonesBuildItem();
}

@BuildStep
List<NativeImageProxyDefinitionBuildItem> registerProxies() {
List<NativeImageProxyDefinitionBuildItem> proxies = new ArrayList<>();
proxies.add(new NativeImageProxyDefinitionBuildItem(JdbcConnection.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(MysqlConnection.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(Statement.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(AutoCloseable.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(JdbcStatement.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(Connection.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(ResultSet.class.getName()));
proxies.add(
new NativeImageProxyDefinitionBuildItem(JdbcPreparedStatement.class.getName(), JdbcStatement.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(JdbcPropertySet.class.getName(), PropertySet.class.getName(),
Serializable.class.getName()));
proxies.add(
new NativeImageProxyDefinitionBuildItem(Resultset.class.getName(), ResultSetInternalMethods.class.getName()));
proxies.add(new NativeImageProxyDefinitionBuildItem(LoadBalancedConnection.class.getName(),
JdbcConnection.class.getName()));
proxies.add(
new NativeImageProxyDefinitionBuildItem(ReplicationConnection.class.getName(), JdbcConnection.class.getName()));
proxies.add(
new NativeImageProxyDefinitionBuildItem(ResultSetInternalMethods.class.getName(),
WarningListener.class.getName(), Resultset.class.getName()));
return proxies;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package io.quarkus.jdbc.mysql.deployment;

import java.sql.Wrapper;

import com.mysql.cj.conf.url.FailoverConnectionUrl;
import com.mysql.cj.conf.url.FailoverDnsSrvConnectionUrl;
import com.mysql.cj.conf.url.LoadBalanceConnectionUrl;
import com.mysql.cj.conf.url.LoadBalanceDnsSrvConnectionUrl;
import com.mysql.cj.conf.url.ReplicationConnectionUrl;
import com.mysql.cj.conf.url.ReplicationDnsSrvConnectionUrl;
import com.mysql.cj.conf.url.SingleConnectionUrl;
import com.mysql.cj.conf.url.XDevApiConnectionUrl;
import com.mysql.cj.conf.url.XDevApiDnsSrvConnectionUrl;
import com.mysql.cj.exceptions.AssertionFailedException;
import com.mysql.cj.exceptions.CJCommunicationsException;
import com.mysql.cj.exceptions.CJConnectionFeatureNotAvailableException;
Expand All @@ -26,6 +37,10 @@
import com.mysql.cj.exceptions.UnableToConnectException;
import com.mysql.cj.exceptions.UnsupportedConnectionStringException;
import com.mysql.cj.exceptions.WrongArgumentException;
import com.mysql.cj.jdbc.Driver;
import com.mysql.cj.jdbc.ha.NdbLoadBalanceExceptionChecker;
import com.mysql.cj.jdbc.ha.StandardLoadBalanceExceptionChecker;
import com.mysql.cj.log.StandardLogger;
import com.mysql.cj.protocol.AsyncSocketFactory;
import com.mysql.cj.protocol.NamedPipeSocketFactory;
import com.mysql.cj.protocol.SocksProxySocketFactory;
Expand All @@ -39,28 +54,30 @@ public final class MySQLJDBCReflections {

@BuildStep
void registerDriverForReflection(BuildProducer<ReflectiveClassBuildItem> reflectiveClass) {
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, com.mysql.cj.jdbc.Driver.class.getName()));

reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, Driver.class.getName()));
reflectiveClass.produce(
new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.FailoverDnsSrvConnectionUrl.class.getName()));
new ReflectiveClassBuildItem(false, false, FailoverDnsSrvConnectionUrl.class.getName()));
reflectiveClass.produce(
new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.FailoverConnectionUrl.class.getName()));
new ReflectiveClassBuildItem(false, false, FailoverConnectionUrl.class.getName()));
reflectiveClass
.produce(new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.SingleConnectionUrl.class.getName()));
.produce(new ReflectiveClassBuildItem(false, false, SingleConnectionUrl.class.getName()));
reflectiveClass.produce(
new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.LoadBalanceConnectionUrl.class.getName()));
new ReflectiveClassBuildItem(false, false, LoadBalanceConnectionUrl.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false,
com.mysql.cj.conf.url.LoadBalanceDnsSrvConnectionUrl.class.getName()));
LoadBalanceDnsSrvConnectionUrl.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false,
com.mysql.cj.conf.url.ReplicationDnsSrvConnectionUrl.class.getName()));
ReplicationDnsSrvConnectionUrl.class.getName()));
reflectiveClass.produce(
new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.ReplicationConnectionUrl.class.getName()));
new ReflectiveClassBuildItem(false, false, ReplicationConnectionUrl.class.getName()));
reflectiveClass.produce(
new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.XDevApiConnectionUrl.class.getName()));
new ReflectiveClassBuildItem(false, false, XDevApiConnectionUrl.class.getName()));
reflectiveClass.produce(
new ReflectiveClassBuildItem(false, false, com.mysql.cj.conf.url.XDevApiDnsSrvConnectionUrl.class.getName()));
new ReflectiveClassBuildItem(false, false, XDevApiDnsSrvConnectionUrl.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false,
com.mysql.cj.jdbc.ha.LoadBalancedAutoCommitInterceptor.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, com.mysql.cj.log.StandardLogger.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, StandardLogger.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, Wrapper.class.getName()));
}

@BuildStep
Expand Down Expand Up @@ -103,5 +120,9 @@ void registerExceptionsForReflection(BuildProducer<ReflectiveClassBuildItem> ref
reflectiveClass
.produce(new ReflectiveClassBuildItem(false, false, UnsupportedConnectionStringException.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, WrongArgumentException.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, "com.mysql.cj.jdbc.MysqlXAException"));
reflectiveClass
.produce(new ReflectiveClassBuildItem(false, false, StandardLoadBalanceExceptionChecker.class.getName()));
reflectiveClass.produce(new ReflectiveClassBuildItem(false, false, NdbLoadBalanceExceptionChecker.class.getName()));
}
}

0 comments on commit 7ea24f5

Please sign in to comment.