Skip to content

Commit 39cb4ed

Browse files
authored
[b/382467945] Move parts of JdbcHandle logic to a util class (#679)
1 parent 39b955b commit 39cb4ed

File tree

3 files changed

+142
-20
lines changed

3 files changed

+142
-20
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2022-2024 Google LLC
3+
* Copyright 2013-2021 CompilerWorks
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.google.edwmigration.dumper.application.dumper.handle;
18+
19+
import com.zaxxer.hikari.HikariConfig;
20+
import java.sql.Connection;
21+
import java.sql.SQLException;
22+
import javax.annotation.ParametersAreNonnullByDefault;
23+
import javax.sql.DataSource;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
26+
import org.springframework.jdbc.core.JdbcTemplate;
27+
28+
@ParametersAreNonnullByDefault
29+
public class HandleUtil {
30+
31+
private static final Logger LOG = LoggerFactory.getLogger(HandleUtil.class);
32+
33+
public static JdbcTemplate createJdbcTemplate(DataSource dataSource) {
34+
JdbcTemplate template = new JdbcTemplate(dataSource);
35+
template.setFetchSize(1024);
36+
return template;
37+
}
38+
39+
static void verifyJdbcConnection(DataSource dataSource) throws SQLException {
40+
LOG.debug("Testing connection to database using {}...", dataSource);
41+
try (Connection connection = dataSource.getConnection()) {
42+
LOG.debug("Obtained connection is: {}");
43+
if (connection == null) {
44+
LOG.error("DataSource failed to provide a connection (usually bad/mismatched JDBC URI).");
45+
// This used to be thrown by Preconditions and was kept for compatibility.
46+
// TODO: Replace with a better error.
47+
throw new NullPointerException();
48+
} else {
49+
LOG.debug("Connection test succeeded");
50+
}
51+
}
52+
}
53+
54+
public static HikariConfig createHikariConfig(DataSource dataSource, int threadPoolSize) {
55+
HikariConfig config = new HikariConfig();
56+
// providing "0" sets it to Integer.MAX_VALUE
57+
config.setConnectionTimeout(0);
58+
config.setDataSource(dataSource);
59+
// Question: If a connection goes out to lunch, causing getConnection() to block for a thread,
60+
// can that deadlock the dumper?
61+
config.setMaximumPoolSize(threadPoolSize);
62+
config.setMinimumIdle(0);
63+
return config;
64+
}
65+
66+
private HandleUtil() {}
67+
}

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/handle/JdbcHandle.java

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
*/
1717
package com.google.edwmigration.dumper.application.dumper.handle;
1818

19-
import com.google.common.base.Preconditions;
2019
import com.zaxxer.hikari.HikariConfig;
2120
import com.zaxxer.hikari.HikariDataSource;
2221
import java.io.IOException;
23-
import java.sql.Connection;
2422
import java.sql.SQLException;
2523
import javax.annotation.Nonnull;
2624
import javax.sql.DataSource;
@@ -40,30 +38,15 @@ public class JdbcHandle extends AbstractHandle {
4038
@Nonnull
4139
public static JdbcHandle newPooledJdbcHandle(@Nonnull DataSource dataSource, int threadPoolSize)
4240
throws SQLException {
43-
HikariConfig config = new HikariConfig();
44-
config.setDataSource(dataSource);
45-
config.setMinimumIdle(0);
46-
// Question: If a connection goes out to lunch, causing getConnection() to block for a thread,
47-
// can that deadlock the dumper?
48-
config.setMaximumPoolSize(threadPoolSize);
49-
config.setConnectionTimeout(0); // 0 equals Integer.MAX_VALUE
41+
HikariConfig config = HandleUtil.createHikariConfig(dataSource, threadPoolSize);
5042
return new JdbcHandle(new HikariDataSource(config));
5143
}
5244

5345
private final JdbcTemplate jdbcTemplate;
5446

5547
public JdbcHandle(@Nonnull DataSource dataSource) throws SQLException {
56-
Preconditions.checkNotNull(dataSource, "DataSource was null.");
57-
LOG.debug("Testing connection to database using " + dataSource + "...");
58-
try (Connection connection = dataSource.getConnection()) {
59-
Preconditions.checkNotNull(
60-
connection,
61-
"DataSource did not return a connection (Usually bad/mismatched JDBC URI?): %s",
62-
dataSource);
63-
LOG.debug("Connection test succeeded; obtained " + connection);
64-
}
65-
this.jdbcTemplate = new JdbcTemplate(dataSource);
66-
jdbcTemplate.setFetchSize(1024);
48+
HandleUtil.verifyJdbcConnection(dataSource);
49+
this.jdbcTemplate = HandleUtil.createJdbcTemplate(dataSource);
6750
}
6851

6952
@Nonnull
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2022-2024 Google LLC
3+
* Copyright 2013-2021 CompilerWorks
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.google.edwmigration.dumper.application.dumper.handle;
18+
19+
import static com.google.edwmigration.dumper.application.dumper.handle.HandleUtil.createHikariConfig;
20+
import static com.google.edwmigration.dumper.application.dumper.handle.HandleUtil.createJdbcTemplate;
21+
import static com.google.edwmigration.dumper.application.dumper.handle.HandleUtil.verifyJdbcConnection;
22+
import static org.junit.Assert.assertEquals;
23+
import static org.junit.Assert.assertThrows;
24+
import static org.mockito.Mockito.mock;
25+
import static org.mockito.Mockito.when;
26+
27+
import com.zaxxer.hikari.HikariConfig;
28+
import java.sql.SQLException;
29+
import javax.sql.DataSource;
30+
import org.junit.Test;
31+
import org.junit.runner.RunWith;
32+
import org.mockito.junit.MockitoJUnitRunner;
33+
import org.springframework.jdbc.core.JdbcTemplate;
34+
35+
@RunWith(MockitoJUnitRunner.class)
36+
public class HandleUtilTest {
37+
38+
@Test
39+
public void templateFromDataSource_success_fetchSizeMatches() {
40+
DataSource dataSource = mock(DataSource.class);
41+
42+
JdbcTemplate template = createJdbcTemplate(dataSource);
43+
44+
assertEquals(1024, template.getFetchSize());
45+
}
46+
47+
@Test
48+
public void verifyJdbcConnection_nullConnection_exceptionThrown() throws SQLException {
49+
DataSource dataSource = mock(DataSource.class);
50+
when(dataSource.getConnection()).thenReturn(null);
51+
52+
assertThrows(NullPointerException.class, () -> verifyJdbcConnection(dataSource));
53+
}
54+
55+
@Test
56+
public void withPoolConfig_success_poolSizeMatches() {
57+
DataSource dataSource = mock(DataSource.class);
58+
59+
HikariConfig config = createHikariConfig(dataSource, 2);
60+
61+
assertEquals(2, config.getMaximumPoolSize());
62+
}
63+
64+
@Test
65+
public void withPoolConfig_success_timeoutEqualsIntMax() {
66+
DataSource dataSource = mock(DataSource.class);
67+
68+
HikariConfig config = createHikariConfig(dataSource, 1);
69+
70+
assertEquals(Integer.MAX_VALUE, config.getConnectionTimeout());
71+
}
72+
}

0 commit comments

Comments
 (0)