Skip to content
This repository was archived by the owner on Mar 23, 2026. It is now read-only.

Commit 2200d63

Browse files
committed
feat(jdbc): extract and centralize connection configuration in DataSource
1 parent 0b0c1ce commit 2200d63

5 files changed

Lines changed: 665 additions & 543 deletions

File tree

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

Lines changed: 143 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
134134
Integer httpConnectTimeout;
135135
Integer httpReadTimeout;
136136
String requestReason;
137+
Long connectionPoolSize;
138+
Long listenerPoolSize;
137139

138140
BigQueryConnection(String url) throws IOException {
139141
this.connectionUrl = url;
@@ -142,49 +144,48 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
142144
this.sqlWarnings = new ArrayList<>();
143145
this.transactionStarted = false;
144146
this.isClosed = false;
145-
this.labels = BigQueryJdbcUrlUtility.parseLabels(url, connectionClassName);
147+
DataSource ds = DataSource.fromUrl(url);
148+
149+
this.labels = ds.getLabels() != null ? ds.getLabels() : new java.util.HashMap<>();
146150
this.maxBytesBilled =
147-
BigQueryJdbcUrlUtility.parseMaximumBytesBilled(url, this.connectionClassName);
148-
this.retryTimeoutInSeconds =
149-
BigQueryJdbcUrlUtility.parseRetryTimeoutInSecs(url, this.connectionClassName);
151+
ds.getMaximumBytesBilled() != null
152+
? ds.getMaximumBytesBilled()
153+
: BigQueryJdbcUrlUtility.DEFAULT_MAX_BYTES_BILLED_VALUE;
154+
this.retryTimeoutInSeconds = ds.getTimeout();
150155
this.retryTimeoutDuration = Duration.ofMillis(retryTimeoutInSeconds * 1000L);
151-
this.retryInitialDelayInSeconds =
152-
BigQueryJdbcUrlUtility.parseRetryInitialDelayInSecs(url, this.connectionClassName);
156+
this.retryInitialDelayInSeconds = ds.getRetryInitialDelay();
153157
this.retryInitialDelayDuration = Duration.ofMillis(retryInitialDelayInSeconds * 1000L);
154-
this.retryMaxDelayInSeconds =
155-
BigQueryJdbcUrlUtility.parseRetryMaxDelayInSecs(url, this.connectionClassName);
158+
this.retryMaxDelayInSeconds = ds.getRetryMaxDelay();
156159
this.retryMaxDelayDuration = Duration.ofMillis(retryMaxDelayInSeconds * 1000L);
157-
this.jobTimeoutInSeconds =
158-
BigQueryJdbcUrlUtility.parseJobTimeout(url, this.connectionClassName);
160+
this.jobTimeoutInSeconds = ds.getJobTimeout();
159161
this.authProperties =
160-
BigQueryJdbcOAuthUtility.parseOAuthProperties(url, this.connectionClassName);
162+
BigQueryJdbcOAuthUtility.parseOAuthProperties(ds, this.connectionClassName);
161163
this.catalog =
162-
BigQueryJdbcUrlUtility.parseStringProperty(
163-
url,
164-
BigQueryJdbcUrlUtility.PROJECT_ID_PROPERTY_NAME,
165-
BigQueryOptions.getDefaultProjectId(),
166-
this.connectionClassName);
167-
this.universeDomain =
168-
BigQueryJdbcUrlUtility.parseStringProperty(
169-
url,
170-
BigQueryJdbcUrlUtility.UNIVERSE_DOMAIN_OVERRIDE_PROPERTY_NAME,
171-
BigQueryJdbcUrlUtility.DEFAULT_UNIVERSE_DOMAIN_VALUE,
172-
this.connectionClassName);
173-
this.overrideProperties =
174-
BigQueryJdbcUrlUtility.parseOverrideProperties(url, this.connectionClassName);
175-
if (universeDomain != null) {
164+
ds.getProjectId() != null ? ds.getProjectId() : BigQueryOptions.getDefaultProjectId();
165+
this.universeDomain = ds.getUniverseDomain();
166+
167+
this.overrideProperties = new java.util.HashMap<>();
168+
if (ds.getOAuth2TokenUri() != null) {
176169
this.overrideProperties.put(
177-
BigQueryJdbcUrlUtility.UNIVERSE_DOMAIN_OVERRIDE_PROPERTY_NAME, universeDomain);
170+
BigQueryJdbcUrlUtility.OAUTH2_TOKEN_URI_PROPERTY_NAME, ds.getOAuth2TokenUri());
171+
}
172+
if (ds.getEndpointOverrides() != null) {
173+
this.overrideProperties.put(
174+
BigQueryJdbcUrlUtility.ENDPOINT_OVERRIDES_PROPERTY_NAME, ds.getEndpointOverrides());
175+
}
176+
if (ds.getPrivateServiceConnect() != null) {
177+
this.overrideProperties.put(
178+
BigQueryJdbcUrlUtility.PRIVATE_SERVICE_CONNECT_PROPERTY_NAME,
179+
ds.getPrivateServiceConnect());
180+
}
181+
if (this.universeDomain != null) {
182+
this.overrideProperties.put(
183+
BigQueryJdbcUrlUtility.UNIVERSE_DOMAIN_OVERRIDE_PROPERTY_NAME, this.universeDomain);
178184
}
179185
this.credentials =
180186
BigQueryJdbcOAuthUtility.getCredentials(
181187
authProperties, overrideProperties, this.connectionClassName);
182-
String defaultDatasetString =
183-
BigQueryJdbcUrlUtility.parseStringProperty(
184-
url,
185-
BigQueryJdbcUrlUtility.DEFAULT_DATASET_PROPERTY_NAME,
186-
null,
187-
this.connectionClassName);
188+
String defaultDatasetString = ds.getDefaultDataset();
188189
if (defaultDatasetString == null || defaultDatasetString.trim().isEmpty()) {
189190
this.defaultDataset = null;
190191
} else {
@@ -199,94 +200,77 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
199200
+ " projectId.datasetId");
200201
}
201202
}
202-
this.location =
203-
BigQueryJdbcUrlUtility.parseStringProperty(
204-
url, BigQueryJdbcUrlUtility.LOCATION_PROPERTY_NAME, null, this.connectionClassName);
205-
this.enableHighThroughputAPI =
206-
BigQueryJdbcUrlUtility.parseBooleanProperty(
207-
url,
208-
BigQueryJdbcUrlUtility.ENABLE_HTAPI_PROPERTY_NAME,
209-
BigQueryJdbcUrlUtility.DEFAULT_ENABLE_HTAPI_VALUE,
210-
this.connectionClassName);
211-
this.highThroughputMinTableSize =
212-
BigQueryJdbcUrlUtility.parseIntProperty(
213-
url,
214-
BigQueryJdbcUrlUtility.HTAPI_MIN_TABLE_SIZE_PROPERTY_NAME,
215-
BigQueryJdbcUrlUtility.DEFAULT_HTAPI_MIN_TABLE_SIZE_VALUE,
216-
this.connectionClassName);
217-
this.highThroughputActivationRatio =
218-
BigQueryJdbcUrlUtility.parseIntProperty(
219-
url,
220-
BigQueryJdbcUrlUtility.HTAPI_ACTIVATION_RATIO_PROPERTY_NAME,
221-
BigQueryJdbcUrlUtility.DEFAULT_HTAPI_ACTIVATION_RATIO_VALUE,
222-
this.connectionClassName);
223-
this.useQueryCache =
224-
BigQueryJdbcUrlUtility.parseBooleanProperty(
225-
url,
226-
BigQueryJdbcUrlUtility.USE_QUERY_CACHE_PROPERTY_NAME,
227-
BigQueryJdbcUrlUtility.DEFAULT_USE_QUERY_CACHE,
228-
this.connectionClassName);
229-
this.useStatelessQueryMode =
230-
BigQueryJdbcUrlUtility.parseJobCreationMode(url, this.connectionClassName);
231-
this.queryDialect =
232-
BigQueryJdbcUrlUtility.parseStringProperty(
233-
url,
234-
BigQueryJdbcUrlUtility.QUERY_DIALECT_PROPERTY_NAME,
235-
BigQueryJdbcUrlUtility.DEFAULT_QUERY_DIALECT_VALUE,
236-
this.connectionClassName);
237-
this.allowLargeResults =
238-
BigQueryJdbcUrlUtility.parseBooleanProperty(
239-
url,
240-
BigQueryJdbcUrlUtility.ALLOW_LARGE_RESULTS_PROPERTY_NAME,
241-
BigQueryJdbcUrlUtility.DEFAULT_ALLOW_LARGE_RESULTS,
242-
this.connectionClassName);
243-
this.destinationTable =
244-
BigQueryJdbcUrlUtility.parseStringProperty(
245-
url,
246-
BigQueryJdbcUrlUtility.LARGE_RESULTS_TABLE_PROPERTY_NAME,
247-
null,
248-
this.connectionClassName);
249-
this.destinationDataset =
250-
BigQueryJdbcUrlUtility.parseStringProperty(
251-
url,
252-
BigQueryJdbcUrlUtility.LARGE_RESULTS_DATASET_PROPERTY_NAME,
253-
null,
254-
this.connectionClassName);
255-
this.destinationDatasetExpirationTime =
256-
BigQueryJdbcUrlUtility.parseLongProperty(
257-
url,
258-
BigQueryJdbcUrlUtility.DESTINATION_DATASET_EXPIRATION_TIME_PROPERTY_NAME,
259-
BigQueryJdbcUrlUtility.DEFAULT_DESTINATION_DATASET_EXPIRATION_TIME_VALUE,
260-
this.connectionClassName);
261-
this.kmsKeyName =
262-
BigQueryJdbcUrlUtility.parseStringProperty(
263-
url, BigQueryJdbcUrlUtility.KMS_KEY_NAME_PROPERTY_NAME, null, this.connectionClassName);
264-
Map<String, String> proxyProperties =
265-
BigQueryJdbcProxyUtility.parseProxyProperties(url, this.connectionClassName);
266-
this.sslTrustStorePath =
267-
BigQueryJdbcUrlUtility.parseStringProperty(
268-
url,
269-
BigQueryJdbcUrlUtility.SSL_TRUST_STORE_PROPERTY_NAME,
270-
null,
271-
this.connectionClassName);
272-
this.sslTrustStorePassword =
273-
BigQueryJdbcUrlUtility.parseStringProperty(
274-
url,
275-
BigQueryJdbcUrlUtility.SSL_TRUST_STORE_PWD_PROPERTY_NAME,
276-
null,
277-
this.connectionClassName);
278-
this.httpConnectTimeout =
279-
BigQueryJdbcUrlUtility.parseIntProperty(
280-
url,
281-
BigQueryJdbcUrlUtility.HTTP_CONNECT_TIMEOUT_PROPERTY_NAME,
282-
null,
283-
this.connectionClassName);
284-
this.httpReadTimeout =
285-
BigQueryJdbcUrlUtility.parseIntProperty(
286-
url,
287-
BigQueryJdbcUrlUtility.HTTP_READ_TIMEOUT_PROPERTY_NAME,
288-
null,
289-
this.connectionClassName);
203+
this.location = ds.getLocation();
204+
this.enableHighThroughputAPI = ds.getEnableHighThroughputAPI();
205+
this.highThroughputMinTableSize = ds.getHighThroughputMinTableSize();
206+
this.highThroughputActivationRatio = ds.getHighThroughputActivationRatio();
207+
this.useQueryCache = ds.getUseQueryCache();
208+
Integer jobCreationMode = ds.getJobCreationMode();
209+
if (jobCreationMode == null || jobCreationMode == 2) {
210+
this.useStatelessQueryMode = true;
211+
} else if (jobCreationMode == 1) {
212+
this.useStatelessQueryMode = false;
213+
} else {
214+
throw new NumberFormatException(
215+
String.format(
216+
"Invalid value for %s. Use 1 for JOB_CREATION_REQUIRED and 2 for"
217+
+ " JOB_CREATION_OPTIONAL.",
218+
BigQueryJdbcUrlUtility.JOB_CREATION_MODE_PROPERTY_NAME));
219+
}
220+
221+
this.queryDialect = ds.getQueryDialect();
222+
this.allowLargeResults = ds.getAllowLargeResults();
223+
this.destinationTable = ds.getDestinationTable();
224+
this.destinationDataset = ds.getDestinationDataset();
225+
this.destinationDatasetExpirationTime = ds.getDestinationDatasetExpirationTime();
226+
this.kmsKeyName = ds.getKmsKeyName();
227+
Map<String, String> proxyProperties = new java.util.HashMap<>();
228+
if (ds.getProxyHost() != null)
229+
proxyProperties.put(BigQueryJdbcUrlUtility.PROXY_HOST_PROPERTY_NAME, ds.getProxyHost());
230+
if (ds.getProxyPort() != null)
231+
proxyProperties.put(BigQueryJdbcUrlUtility.PROXY_PORT_PROPERTY_NAME, ds.getProxyPort());
232+
if (ds.getProxyUid() != null)
233+
proxyProperties.put(BigQueryJdbcUrlUtility.PROXY_USER_ID_PROPERTY_NAME, ds.getProxyUid());
234+
if (ds.getProxyPwd() != null)
235+
proxyProperties.put(BigQueryJdbcUrlUtility.PROXY_PASSWORD_PROPERTY_NAME, ds.getProxyPwd());
236+
String proxyHost = ds.getProxyHost();
237+
String proxyPort = ds.getProxyPort();
238+
String proxyUid = ds.getProxyUid();
239+
String proxyPwd = ds.getProxyPwd();
240+
241+
if (proxyPort != null
242+
&& !java.util.regex.Pattern.compile(
243+
"^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$")
244+
.matcher(proxyPort)
245+
.find()) {
246+
throw new IllegalArgumentException(
247+
"Illegal port number provided %s. Please provide a valid port number.");
248+
}
249+
250+
boolean isMissingProxyHostOrPortWhenProxySet =
251+
(proxyHost == null && proxyPort != null) || (proxyHost != null && proxyPort == null);
252+
if (isMissingProxyHostOrPortWhenProxySet) {
253+
throw new IllegalArgumentException(
254+
"Both ProxyHost and ProxyPort parameters need to be specified. No defaulting behavior"
255+
+ " occurs.");
256+
}
257+
boolean isMissingProxyUidOrPwdWhenAuthSet =
258+
(proxyUid == null && proxyPwd != null) || (proxyUid != null && proxyPwd == null);
259+
if (isMissingProxyUidOrPwdWhenAuthSet) {
260+
throw new IllegalArgumentException(
261+
"Both ProxyUid and ProxyPwd parameters need to be specified for authentication.");
262+
}
263+
boolean isProxyAuthSetWithoutProxySettings = proxyUid != null && proxyHost == null;
264+
if (isProxyAuthSetWithoutProxySettings) {
265+
throw new IllegalArgumentException(
266+
"Proxy authentication provided via connection string with no proxy host or port set.");
267+
}
268+
269+
this.sslTrustStorePath = ds.getSSLTrustStorePath();
270+
this.sslTrustStorePassword = ds.getSSLTrustStorePassword();
271+
this.httpConnectTimeout = ds.getHttpConnectTimeout();
272+
this.httpReadTimeout = ds.getHttpReadTimeout();
273+
290274
this.httpTransportOptions =
291275
BigQueryJdbcProxyUtility.getHttpTransportOptions(
292276
proxyProperties,
@@ -301,75 +285,46 @@ public class BigQueryConnection extends BigQueryNoOpsConnection {
301285
this.sslTrustStorePath,
302286
this.sslTrustStorePassword,
303287
this.connectionClassName);
304-
this.enableSession =
305-
BigQueryJdbcUrlUtility.parseBooleanProperty(
306-
url,
307-
BigQueryJdbcUrlUtility.ENABLE_SESSION_PROPERTY_NAME,
308-
BigQueryJdbcUrlUtility.DEFAULT_ENABLE_SESSION_VALUE,
309-
this.connectionClassName);
310-
this.unsupportedHTAPIFallback =
311-
BigQueryJdbcUrlUtility.parseBooleanProperty(
312-
url,
313-
BigQueryJdbcUrlUtility.UNSUPPORTED_HTAPI_FALLBACK_PROPERTY_NAME,
314-
BigQueryJdbcUrlUtility.DEFAULT_UNSUPPORTED_HTAPI_FALLBACK_VALUE,
315-
this.connectionClassName);
316-
this.maxResults =
317-
BigQueryJdbcUrlUtility.parseLongProperty(
318-
url,
319-
BigQueryJdbcUrlUtility.MAX_RESULTS_PROPERTY_NAME,
320-
BigQueryJdbcUrlUtility.DEFAULT_MAX_RESULTS_VALUE,
321-
this.connectionClassName);
322-
Map<String, String> queryPropertiesMap =
323-
BigQueryJdbcUrlUtility.parseQueryProperties(url, this.connectionClassName);
288+
this.enableSession = ds.getEnableSession();
289+
this.unsupportedHTAPIFallback = ds.getUnsupportedHTAPIFallback();
290+
this.maxResults = ds.getMaxResults();
291+
Map<String, String> queryPropertiesMap = ds.getQueryProperties();
324292
this.sessionInfoConnectionProperty = getSessionPropertyFromQueryProperties(queryPropertiesMap);
325293
this.queryProperties = convertMapToConnectionPropertiesList(queryPropertiesMap);
326294
this.enableWriteAPI =
327-
BigQueryJdbcUrlUtility.parseBooleanProperty(
328-
url,
329-
BigQueryJdbcUrlUtility.ENABLE_WRITE_API_PROPERTY_NAME,
330-
BigQueryJdbcUrlUtility.DEFAULT_ENABLE_WRITE_API_VALUE,
331-
this.connectionClassName);
295+
ds.getEnableWriteAPI() != null
296+
? ds.getEnableWriteAPI()
297+
: BigQueryJdbcUrlUtility.DEFAULT_ENABLE_WRITE_API_VALUE;
332298
this.writeAPIActivationRowCount =
333-
BigQueryJdbcUrlUtility.parseIntProperty(
334-
url,
335-
BigQueryJdbcUrlUtility.SWA_ACTIVATION_ROW_COUNT_PROPERTY_NAME,
336-
BigQueryJdbcUrlUtility.DEFAULT_SWA_ACTIVATION_ROW_COUNT_VALUE,
337-
this.connectionClassName);
299+
ds.getSwaActivationRowCount() != null
300+
? ds.getSwaActivationRowCount()
301+
: BigQueryJdbcUrlUtility.DEFAULT_SWA_ACTIVATION_ROW_COUNT_VALUE;
338302
this.writeAPIAppendRowCount =
339-
BigQueryJdbcUrlUtility.parseIntProperty(
340-
url,
341-
BigQueryJdbcUrlUtility.SWA_APPEND_ROW_COUNT_PROPERTY_NAME,
342-
BigQueryJdbcUrlUtility.DEFAULT_SWA_APPEND_ROW_COUNT_VALUE,
343-
this.connectionClassName);
303+
ds.getSwaAppendRowCount() != null
304+
? ds.getSwaAppendRowCount()
305+
: BigQueryJdbcUrlUtility.DEFAULT_SWA_APPEND_ROW_COUNT_VALUE;
306+
307+
String additionalProjectsStr = ds.getAdditionalProjects();
344308
this.additionalProjects =
345-
BigQueryJdbcUrlUtility.parseStringListProperty(
346-
url,
347-
BigQueryJdbcUrlUtility.ADDITIONAL_PROJECTS_PROPERTY_NAME,
348-
this.connectionClassName);
309+
(additionalProjectsStr == null || additionalProjectsStr.isEmpty())
310+
? java.util.Collections.emptyList()
311+
: java.util.Arrays.asList(additionalProjectsStr.split(","));
312+
349313
this.filterTablesOnDefaultDataset =
350-
BigQueryJdbcUrlUtility.parseBooleanProperty(
351-
url,
352-
BigQueryJdbcUrlUtility.FILTER_TABLES_ON_DEFAULT_DATASET_PROPERTY_NAME,
353-
BigQueryJdbcUrlUtility.DEFAULT_FILTER_TABLES_ON_DEFAULT_DATASET_VALUE,
354-
this.connectionClassName);
314+
ds.getFilterTablesOnDefaultDataset() != null
315+
? ds.getFilterTablesOnDefaultDataset()
316+
: BigQueryJdbcUrlUtility.DEFAULT_FILTER_TABLES_ON_DEFAULT_DATASET_VALUE;
355317
this.requestGoogleDriveScope =
356-
BigQueryJdbcUrlUtility.parseIntProperty(
357-
url,
358-
BigQueryJdbcUrlUtility.REQUEST_GOOGLE_DRIVE_SCOPE_PROPERTY_NAME,
359-
BigQueryJdbcUrlUtility.DEFAULT_REQUEST_GOOGLE_DRIVE_SCOPE_VALUE,
360-
this.connectionClassName);
318+
ds.getRequestGoogleDriveScope() != null
319+
? ds.getRequestGoogleDriveScope()
320+
: BigQueryJdbcUrlUtility.DEFAULT_REQUEST_GOOGLE_DRIVE_SCOPE_VALUE;
361321
this.metadataFetchThreadCount =
362-
BigQueryJdbcUrlUtility.parseIntProperty(
363-
url,
364-
BigQueryJdbcUrlUtility.METADATA_FETCH_THREAD_COUNT_PROPERTY_NAME,
365-
BigQueryJdbcUrlUtility.DEFAULT_METADATA_FETCH_THREAD_COUNT_VALUE,
366-
this.connectionClassName);
367-
this.requestReason =
368-
BigQueryJdbcUrlUtility.parseStringProperty(
369-
url,
370-
BigQueryJdbcUrlUtility.REQUEST_REASON_PROPERTY_NAME,
371-
null,
372-
this.connectionClassName);
322+
ds.getMetadataFetchThreadCount() != null
323+
? ds.getMetadataFetchThreadCount()
324+
: BigQueryJdbcUrlUtility.DEFAULT_METADATA_FETCH_THREAD_COUNT_VALUE;
325+
this.requestReason = ds.getRequestReason();
326+
this.connectionPoolSize = ds.getConnectionPoolSize();
327+
this.listenerPoolSize = ds.getListenerPoolSize();
373328

374329
HEADER_PROVIDER = createHeaderProvider();
375330
this.bigQuery = getBigQueryConnection();
@@ -760,6 +715,14 @@ Integer getHttpReadTimeout() {
760715
return httpReadTimeout;
761716
}
762717

718+
Long getConnectionPoolSize() {
719+
return connectionPoolSize;
720+
}
721+
722+
Long getListenerPoolSize() {
723+
return listenerPoolSize;
724+
}
725+
763726
@Override
764727
public boolean isValid(int timeout) throws SQLException {
765728
if (timeout < 0) {

0 commit comments

Comments
 (0)