diff --git a/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriver.java b/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriver.java index 216c37fb5d32d..18faf3990206c 100644 --- a/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriver.java +++ b/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriver.java @@ -80,7 +80,7 @@ public ArrowFlightConnection connect(final String url, final Properties info) this, factory, url, - properties, + lowerCasePropertyKeys(properties), new RootAllocator(Long.MAX_VALUE)); } catch (final FlightRuntimeException e) { throw new SQLException("Failed to connect.", e); @@ -251,4 +251,10 @@ private Map getUrlsArgs(String url) return resultMap; } + + private Properties lowerCasePropertyKeys(final Properties properties) { + final Properties resultProperty = new Properties(); + properties.forEach((k, v) -> resultProperty.put(k.toString().toLowerCase(), v)); + return resultProperty; + } } diff --git a/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowFlightConnectionConfigImpl.java b/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowFlightConnectionConfigImpl.java index 57fd816d9dce3..b8d4e7240a122 100644 --- a/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowFlightConnectionConfigImpl.java +++ b/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/ArrowFlightConnectionConfigImpl.java @@ -201,10 +201,13 @@ public enum ArrowFlightConnectionProperty implements ConnectionProperty { */ public Object get(final Properties properties) { Preconditions.checkNotNull(properties, "Properties cannot be null."); - Preconditions.checkState( - properties.containsKey(camelName) || !required, - format("Required property not provided: <%s>.", this)); - return properties.getOrDefault(camelName, defaultValue); + Object value = properties.get(camelName.toLowerCase()); + if (required) { + Preconditions.checkNotNull(value, format("Required property not provided: <%s>.", this)); + return value; + } else { + return value != null ? value : defaultValue; + } } /** diff --git a/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/UrlParser.java b/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/UrlParser.java index fbef721793b02..787a22312609f 100644 --- a/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/UrlParser.java +++ b/java/flight/flight-jdbc-driver/src/main/java/org/apache/arrow/driver/jdbc/utils/UrlParser.java @@ -32,18 +32,18 @@ public class UrlParser { */ public static Map parse(String url, String separator) { Map resultMap = new HashMap<>(); - String[] keyValues = url.split(separator); + if (url != null) { + String[] keyValues = url.split(separator); - for (String keyValue : keyValues) { - int separatorKey = keyValue.indexOf("="); // Find the first equal sign to split key and value. - String key = keyValue.substring(0, separatorKey); - String value = ""; - if (!keyValue.endsWith("=")) { // Avoid crashes for empty values. - value = keyValue.substring(separatorKey + 1); + for (String keyValue : keyValues) { + int separatorKey = keyValue.indexOf("="); // Find the first equal sign to split key and value. + if (separatorKey != -1) { // Avoid crashes when not finding an equal sign in the property value. + String key = keyValue.substring(0, separatorKey); + String value = keyValue.substring(separatorKey + 1); + resultMap.put(key, value); + } } - resultMap.put(key, value); } - return resultMap; } } diff --git a/java/flight/flight-jdbc-driver/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriverTest.java b/java/flight/flight-jdbc-driver/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriverTest.java index d39ec61f3099e..6aa0062f706e1 100644 --- a/java/flight/flight-jdbc-driver/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriverTest.java +++ b/java/flight/flight-jdbc-driver/src/test/java/org/apache/arrow/driver/jdbc/ArrowFlightJdbcDriverTest.java @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.Map; +import java.util.Properties; import org.apache.arrow.driver.jdbc.authentication.UserPasswordAuthentication; import org.apache.arrow.driver.jdbc.utils.ArrowFlightConnectionConfigImpl.ArrowFlightConnectionProperty; import org.apache.arrow.driver.jdbc.utils.MockFlightSqlProducer; @@ -116,7 +117,38 @@ public void testShouldConnectWhenProvidedWithValidUrl() throws Exception { dataSource.getConfig().getHost() + ":" + dataSource.getConfig().getPort() + "?" + "useEncryption=false", - dataSource.getProperties(dataSource.getConfig().getUser(), dataSource.getConfig().getPassword()))) { + dataSource.getProperties(dataSource.getConfig().getUser(), dataSource.getConfig().getPassword()))) { + assert connection.isValid(300); + } + } + + @Test + public void testConnectWithInsensitiveCasePropertyKeys() throws Exception { + // Get the Arrow Flight JDBC driver by providing a URL with insensitive case property keys. + final Driver driver = new ArrowFlightJdbcDriver(); + + try (Connection connection = + driver.connect("jdbc:arrow-flight://" + + dataSource.getConfig().getHost() + ":" + + dataSource.getConfig().getPort() + "?" + + "UseEncryptiOn=false", + dataSource.getProperties(dataSource.getConfig().getUser(), dataSource.getConfig().getPassword()))) { + assert connection.isValid(300); + } + } + + @Test + public void testConnectWithInsensitiveCasePropertyKeys2() throws Exception { + // Get the Arrow Flight JDBC driver by providing a property object with insensitive case keys. + final Driver driver = new ArrowFlightJdbcDriver(); + Properties properties = + dataSource.getProperties(dataSource.getConfig().getUser(), dataSource.getConfig().getPassword()); + properties.put("UseEncryptiOn", "false"); + + try (Connection connection = + driver.connect("jdbc:arrow-flight://" + + dataSource.getConfig().getHost() + ":" + + dataSource.getConfig().getPort(), properties)) { assert connection.isValid(300); } }