Skip to content

Commit 6148c0c

Browse files
committed
fix(bigquery-jdbc): configure logging early to capture URL parsing warnings and errors
1 parent dcc2a68 commit 6148c0c

3 files changed

Lines changed: 81 additions & 10 deletions

File tree

java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryDriver.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,22 +130,19 @@ public Connection connect(String url, Properties info) throws SQLException {
130130
// strip 'jdbc:' from the URL, add any extra properties
131131
String connectionUri =
132132
BigQueryJdbcUrlUtility.appendPropertiesToURL(url.substring(5), this.toString(), info);
133-
DataSource ds;
134-
try {
135-
ds = DataSource.fromUrl(connectionUri);
136-
} catch (BigQueryJdbcRuntimeException e) {
137-
throw new BigQueryJdbcException("Failed to parse connection URL", e);
138-
}
139-
140133
// LogLevel
141-
String logLevelStr = ds.getLogLevel();
134+
String logLevelStr =
135+
BigQueryJdbcUrlUtility.parseUriPropertyWithoutValidation(
136+
connectionUri, BigQueryJdbcUrlUtility.LOG_LEVEL_PROPERTY_NAME);
142137
if (logLevelStr == null) {
143138
logLevelStr = System.getenv(BigQueryJdbcUrlUtility.LOG_LEVEL_ENV_VAR);
144139
}
145140
Level logLevel = BigQueryJdbcUrlUtility.parseLogLevel(logLevelStr);
146141

147142
// LogPath
148-
String logPath = ds.getLogPath();
143+
String logPath =
144+
BigQueryJdbcUrlUtility.parseUriPropertyWithoutValidation(
145+
connectionUri, BigQueryJdbcUrlUtility.LOG_PATH_PROPERTY_NAME);
149146
if (logPath == null) {
150147
logPath = System.getenv(BigQueryJdbcUrlUtility.LOG_PATH_ENV_VAR);
151148
}
@@ -155,6 +152,14 @@ public Connection connect(String url, Properties info) throws SQLException {
155152

156153
BigQueryJdbcRootLogger.setLevel(logLevel, logPath);
157154

155+
DataSource ds;
156+
try {
157+
ds = DataSource.fromUrl(connectionUri);
158+
} catch (BigQueryJdbcRuntimeException e) {
159+
LOG.severe("Failed to parse connection URL", e);
160+
throw new BigQueryJdbcException("Failed to parse connection URL", e);
161+
}
162+
158163
// Logging starts from here.
159164
BigQueryConnection connection = new BigQueryConnection(connectionUri, ds);
160165
LOG.info(

java-bigquery-jdbc/src/main/java/com/google/cloud/bigquery/jdbc/BigQueryJdbcUrlUtility.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,30 @@ static String parseUriProperty(String uri, String property) {
662662
return map.get(property);
663663
}
664664

665+
/**
666+
* Parses a URI property from the given URI without validating any other properties.
667+
*
668+
* @param uri The URI to parse.
669+
* @param property The name of the property to parse.
670+
* @return The String value of the property, or null if the property is not found.
671+
*/
672+
static String parseUriPropertyWithoutValidation(String uri, String property) {
673+
if (uri == null) {
674+
return null;
675+
}
676+
String searchKey = ";" + property.toUpperCase() + "=";
677+
String upperUri = uri.toUpperCase();
678+
int index = upperUri.indexOf(searchKey);
679+
if (index == -1) {
680+
return null;
681+
}
682+
int valueStart = index + searchKey.length();
683+
int valueEnd = uri.indexOf(';', valueStart);
684+
String value =
685+
(valueEnd == -1) ? uri.substring(valueStart) : uri.substring(valueStart, valueEnd);
686+
return CharEscapers.decodeUriPath(value.replace("+", "%2B"));
687+
}
688+
665689
/**
666690
* Parses the URL into a map of key-value pairs, validating that all keys are known properties.
667691
*

java-bigquery-jdbc/src/test/java/com/google/cloud/bigquery/jdbc/BigQueryDriverTest.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
import java.sql.DriverPropertyInfo;
2222
import java.sql.SQLException;
2323
import java.util.Properties;
24+
import java.util.logging.Level;
2425
import java.util.logging.Logger;
26+
import org.junit.jupiter.api.Assertions;
2527
import org.junit.jupiter.api.BeforeEach;
2628
import org.junit.jupiter.api.Test;
2729

28-
public class BigQueryDriverTest {
30+
public class BigQueryDriverTest extends BigQueryJdbcLoggingBaseTest {
2931

3032
static BigQueryDriver bigQueryDriver;
3133

@@ -104,4 +106,44 @@ public void testConnectWithInvalidUrlChainsNoException() throws SQLException {
104106
new Properties());
105107
assertThat(connection.isClosed()).isFalse();
106108
}
109+
110+
@Test
111+
public void testUnknownPropertyWarningIsLogged() throws SQLException {
112+
Connection connection =
113+
bigQueryDriver.connect(
114+
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;"
115+
+ "OAuthType=2;OAuthAccessToken=redactedToken;ProjectId=t;LogLevel=3;"
116+
+ "MyUnknownSetting=Value",
117+
new Properties());
118+
assertThat(connection.isClosed()).isFalse();
119+
120+
boolean foundWarning =
121+
capturedLogs.stream()
122+
.anyMatch(
123+
r ->
124+
r.getLevel() == Level.WARNING
125+
&& r.getMessage()
126+
.contains("Wrong value or unknown setting: MYUNKNOWNSETTING"));
127+
assertThat(foundWarning).isTrue();
128+
}
129+
130+
@Test
131+
public void testMalformedUrlExceptionIsLogged() {
132+
try {
133+
bigQueryDriver.connect(
134+
"jdbc:bigquery://https://www.googleapis.com/bigquery/v2:443;"
135+
+ "OAuthType=2;OAuthAccessToken=redactedToken;ProjectId=t;LogLevel=3;"
136+
+ "MalformedPropertyWithoutEquals",
137+
new Properties());
138+
Assertions.fail("Should have thrown BigQueryJdbcException");
139+
} catch (SQLException e) {
140+
boolean foundSevere =
141+
capturedLogs.stream()
142+
.anyMatch(
143+
r ->
144+
r.getLevel() == Level.SEVERE
145+
&& r.getMessage().contains("Failed to parse connection URL"));
146+
assertThat(foundSevere).isTrue();
147+
}
148+
}
107149
}

0 commit comments

Comments
 (0)