MySqlFirehoseDatabaseConnector uses configured driver class name (#12049)

This commit is contained in:
Suneet Saldanha 2021-12-09 20:58:55 -08:00 committed by GitHub
parent 58245b4617
commit 25ac04e067
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 69 additions and 31 deletions

View File

@ -43,15 +43,13 @@ public final class ConnectionUriUtils
public static final String MARIADB_PREFIX = "jdbc:mariadb:"; public static final String MARIADB_PREFIX = "jdbc:mariadb:";
public static final String POSTGRES_DRIVER = "org.postgresql.Driver"; public static final String POSTGRES_DRIVER = "org.postgresql.Driver";
public static final String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
public static final String MYSQL_NON_REGISTERING_DRIVER = "com.mysql.jdbc.NonRegisteringDriver"; public static final String MYSQL_NON_REGISTERING_DRIVER = "com.mysql.jdbc.NonRegisteringDriver";
public static final String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
/** /**
* This method checks {@param actualProperties} against {@param allowedProperties} if they are not system properties. * This method checks {@param actualProperties} against {@param allowedProperties} if they are not system properties.
* A property is regarded as a system property if its name starts with a prefix in {@param systemPropertyPrefixes}. * A property is regarded as a system property if its name starts with a prefix in {@param systemPropertyPrefixes}.
* See org.apache.druid.server.initialization.JDBCAccessSecurityConfig for more details. * See org.apache.druid.server.initialization.JDBCAccessSecurityConfig for more details.
* * <p>
* If a non-system property that is not allowed is found, this method throws an {@link IllegalArgumentException}. * If a non-system property that is not allowed is found, this method throws an {@link IllegalArgumentException}.
*/ */
public static void throwIfPropertiesAreNotAllowed( public static void throwIfPropertiesAreNotAllowed(
@ -76,16 +74,16 @@ public final class ConnectionUriUtils
* This method tries to determine the correct type of database for a given JDBC connection string URI, then load the * This method tries to determine the correct type of database for a given JDBC connection string URI, then load the
* driver using reflection to parse the uri parameters, returning the set of keys which can be used for JDBC * driver using reflection to parse the uri parameters, returning the set of keys which can be used for JDBC
* parameter whitelist validation. * parameter whitelist validation.
* * <p>
* uris starting with {@link #MYSQL_PREFIX} will first try to use the MySQL Connector/J driver (5.x), then fallback * uris starting with {@link #MYSQL_PREFIX} will first try to use the MySQL Connector/J driver (5.x), then fallback
* to MariaDB Connector/J (version 2.x) which also accepts jdbc:mysql uris. This method does not attempt to use * to MariaDB Connector/J (version 2.x) which also accepts jdbc:mysql uris. This method does not attempt to use
* MariaDB Connector/J 3.x alpha driver (at the time of these javadocs, it only handles the jdbc:mariadb prefix) * MariaDB Connector/J 3.x alpha driver (at the time of these javadocs, it only handles the jdbc:mariadb prefix)
* * <p>
* uris starting with {@link #POSTGRES_PREFIX} will use the postgresql driver to parse the uri * uris starting with {@link #POSTGRES_PREFIX} will use the postgresql driver to parse the uri
* * <p>
* uris starting with {@link #MARIADB_PREFIX} will first try to use MariaDB Connector/J driver (2.x) then fallback to * uris starting with {@link #MARIADB_PREFIX} will first try to use MariaDB Connector/J driver (2.x) then fallback to
* MariaDB Connector/J 3.x driver. * MariaDB Connector/J 3.x driver.
* * <p>
* If the uri does not match any of these schemes, this method will return an empty set if unknown uris are allowed, * If the uri does not match any of these schemes, this method will return an empty set if unknown uris are allowed,
* or throw an exception if not. * or throw an exception if not.
*/ */
@ -185,7 +183,11 @@ public final class ConnectionUriUtils
Class<?> driverClass = Class.forName(MYSQL_NON_REGISTERING_DRIVER); Class<?> driverClass = Class.forName(MYSQL_NON_REGISTERING_DRIVER);
Method parseUrl = driverClass.getMethod("parseURL", String.class, Properties.class); Method parseUrl = driverClass.getMethod("parseURL", String.class, Properties.class);
// almost the same as postgres, but is an instance level method // almost the same as postgres, but is an instance level method
Properties properties = (Properties) parseUrl.invoke(driverClass.getConstructor().newInstance(), connectionUri, null); Properties properties = (Properties) parseUrl.invoke(
driverClass.getConstructor().newInstance(),
connectionUri,
null
);
if (properties == null) { if (properties == null) {
throw new IAE("Invalid URL format for MySQL: [%s]", connectionUri); throw new IAE("Invalid URL format for MySQL: [%s]", connectionUri);

View File

@ -121,6 +121,11 @@
<version>${mariadb.version}</version> <version>${mariadb.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -26,6 +26,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.druid.metadata.MetadataStorageConnectorConfig; import org.apache.druid.metadata.MetadataStorageConnectorConfig;
import org.apache.druid.metadata.SQLFirehoseDatabaseConnector; import org.apache.druid.metadata.SQLFirehoseDatabaseConnector;
import org.apache.druid.metadata.storage.mysql.MySQLConnectorDriverConfig;
import org.apache.druid.server.initialization.JdbcAccessSecurityConfig; import org.apache.druid.server.initialization.JdbcAccessSecurityConfig;
import org.apache.druid.utils.ConnectionUriUtils; import org.apache.druid.utils.ConnectionUriUtils;
import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.DBI;
@ -47,7 +48,8 @@ public class MySQLFirehoseDatabaseConnector extends SQLFirehoseDatabaseConnector
public MySQLFirehoseDatabaseConnector( public MySQLFirehoseDatabaseConnector(
@JsonProperty("connectorConfig") MetadataStorageConnectorConfig connectorConfig, @JsonProperty("connectorConfig") MetadataStorageConnectorConfig connectorConfig,
@JsonProperty("driverClassName") @Nullable String driverClassName, @JsonProperty("driverClassName") @Nullable String driverClassName,
@JacksonInject JdbcAccessSecurityConfig securityConfig @JacksonInject JdbcAccessSecurityConfig securityConfig,
@JacksonInject MySQLConnectorDriverConfig mySQLConnectorDriverConfig
) )
{ {
this.connectorConfig = connectorConfig; this.connectorConfig = connectorConfig;
@ -56,10 +58,8 @@ public class MySQLFirehoseDatabaseConnector extends SQLFirehoseDatabaseConnector
datasource.setDriverClassLoader(getClass().getClassLoader()); datasource.setDriverClassLoader(getClass().getClassLoader());
if (driverClassName != null) { if (driverClassName != null) {
datasource.setDriverClassName(driverClassName); datasource.setDriverClassName(driverClassName);
} else if (connectorConfig.getConnectURI().startsWith(ConnectionUriUtils.MARIADB_PREFIX)) {
datasource.setDriverClassName(ConnectionUriUtils.MARIADB_DRIVER);
} else { } else {
datasource.setDriverClassName(ConnectionUriUtils.MYSQL_DRIVER); datasource.setDriverClassName(mySQLConnectorDriverConfig.getDriverClassName());
} }
this.dbi = new DBI(datasource); this.dbi = new DBI(datasource);
} }

View File

@ -27,23 +27,33 @@ import nl.jqno.equalsverifier.EqualsVerifier;
import org.apache.druid.jackson.DefaultObjectMapper; import org.apache.druid.jackson.DefaultObjectMapper;
import org.apache.druid.java.util.common.StringUtils; import org.apache.druid.java.util.common.StringUtils;
import org.apache.druid.metadata.MetadataStorageConnectorConfig; import org.apache.druid.metadata.MetadataStorageConnectorConfig;
import org.apache.druid.metadata.storage.mysql.MySQLConnectorDriverConfig;
import org.apache.druid.metadata.storage.mysql.MySQLMetadataStorageModule; import org.apache.druid.metadata.storage.mysql.MySQLMetadataStorageModule;
import org.apache.druid.server.initialization.JdbcAccessSecurityConfig; import org.apache.druid.server.initialization.JdbcAccessSecurityConfig;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Set; import java.util.Set;
@RunWith(MockitoJUnitRunner.class)
public class MySQLFirehoseDatabaseConnectorTest public class MySQLFirehoseDatabaseConnectorTest
{ {
private static final ObjectMapper MAPPER = new DefaultObjectMapper();
private static final JdbcAccessSecurityConfig INJECTED_CONF = newSecurityConfigEnforcingAllowList(ImmutableSet.of()); private static final JdbcAccessSecurityConfig INJECTED_CONF = newSecurityConfigEnforcingAllowList(ImmutableSet.of());
static { @Mock
MAPPER.registerModules(new MySQLMetadataStorageModule().getJacksonModules()); private MySQLConnectorDriverConfig mySQLConnectorDriverConfig;
MAPPER.setInjectableValues(new InjectableValues.Std().addValue(JdbcAccessSecurityConfig.class, INJECTED_CONF));
@Before
public void setup()
{
Mockito.doReturn("com.mysql.jdbc.Driver").when(mySQLConnectorDriverConfig).getDriverClassName();
} }
@Rule @Rule
@ -52,6 +62,13 @@ public class MySQLFirehoseDatabaseConnectorTest
@Test @Test
public void testSerde() throws JsonProcessingException public void testSerde() throws JsonProcessingException
{ {
ObjectMapper mapper = new DefaultObjectMapper();
mapper.registerModules(new MySQLMetadataStorageModule().getJacksonModules());
mapper.setInjectableValues(new InjectableValues.Std().addValue(JdbcAccessSecurityConfig.class, INJECTED_CONF)
.addValue(
MySQLConnectorDriverConfig.class,
mySQLConnectorDriverConfig
));
MetadataStorageConnectorConfig connectorConfig = new MetadataStorageConnectorConfig() MetadataStorageConnectorConfig connectorConfig = new MetadataStorageConnectorConfig()
{ {
@Override @Override
@ -63,18 +80,23 @@ public class MySQLFirehoseDatabaseConnectorTest
MySQLFirehoseDatabaseConnector connector = new MySQLFirehoseDatabaseConnector( MySQLFirehoseDatabaseConnector connector = new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
INJECTED_CONF INJECTED_CONF,
mySQLConnectorDriverConfig
);
MySQLFirehoseDatabaseConnector andBack = mapper.readValue(
mapper.writeValueAsString(connector),
MySQLFirehoseDatabaseConnector.class
); );
MySQLFirehoseDatabaseConnector andBack = MAPPER.readValue(MAPPER.writeValueAsString(connector), MySQLFirehoseDatabaseConnector.class);
Assert.assertEquals(connector, andBack); Assert.assertEquals(connector, andBack);
// test again with classname // test again with classname
connector = new MySQLFirehoseDatabaseConnector( connector = new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
"some.class.name.Driver", "some.class.name.Driver",
INJECTED_CONF INJECTED_CONF,
mySQLConnectorDriverConfig
); );
andBack = MAPPER.readValue(MAPPER.writeValueAsString(connector), MySQLFirehoseDatabaseConnector.class); andBack = mapper.readValue(mapper.writeValueAsString(connector), MySQLFirehoseDatabaseConnector.class);
Assert.assertEquals(connector, andBack); Assert.assertEquals(connector, andBack);
} }
@ -105,7 +127,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -126,7 +149,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -150,7 +174,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -173,7 +198,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -196,12 +222,12 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@Test @Test
public void testFailOnlyInvalidProperty() public void testFailOnlyInvalidProperty()
{ {
@ -222,7 +248,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -246,7 +273,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -270,7 +298,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -304,7 +333,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
securityConfig securityConfig,
mySQLConnectorDriverConfig
); );
} }
@ -326,7 +356,8 @@ public class MySQLFirehoseDatabaseConnectorTest
new MySQLFirehoseDatabaseConnector( new MySQLFirehoseDatabaseConnector(
connectorConfig, connectorConfig,
null, null,
new JdbcAccessSecurityConfig() new JdbcAccessSecurityConfig(),
mySQLConnectorDriverConfig
); );
} }