Skip to content

Commit d3e03f5

Browse files
committed
Simple approach on doing multiple connection tries
First we now try to use thick-connection, if that's not possible we use thin. Also introduction of immutable ConnectionConfig object - we'll need that in future.
1 parent 6ebc001 commit d3e03f5

File tree

6 files changed

+163
-14
lines changed

6 files changed

+163
-14
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.utplsql.cli;
2+
3+
import java.util.regex.Matcher;
4+
import java.util.regex.Pattern;
5+
6+
public class ConnectionConfig {
7+
8+
private final String user;
9+
private final String password;
10+
private final String connect;
11+
12+
public ConnectionConfig( String connectString ) {
13+
Matcher m = Pattern.compile("^([^/]+)/([^@]+)@(.*)$").matcher(connectString);
14+
if ( m.find() ) {
15+
user = m.group(1);
16+
password = m.group(2);
17+
connect = m.group(3);
18+
}
19+
else
20+
throw new IllegalArgumentException("Not a valid connectString: '" + connectString + "'");
21+
}
22+
23+
public String getConnect() {
24+
return connect;
25+
}
26+
27+
public String getUser() {
28+
return user;
29+
}
30+
31+
public String getPassword() {
32+
return password;
33+
}
34+
35+
public String getConnectString() {
36+
return user + "/" + password + "@" + connect;
37+
}
38+
}

src/main/java/org/utplsql/cli/ConnectionInfo.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import com.beust.jcommander.IStringConverter;
44
import com.zaxxer.hikari.HikariDataSource;
5+
import org.utplsql.cli.datasource.DataSourceProvider;
56

6-
import java.io.File;
77
import java.sql.Connection;
88
import java.sql.PreparedStatement;
99
import java.sql.ResultSet;
@@ -12,20 +12,12 @@
1212
public class ConnectionInfo {
1313

1414
private String databaseVersion;
15-
16-
static {
17-
String oracleHome = System.getenv("ORACLE_HOME");
18-
if (oracleHome != null) {
19-
System.setProperty("oracle.net.tns_admin",
20-
String.join(File.separator, oracleHome, "NETWORK", "ADMIN"));
21-
}
22-
}
23-
24-
private HikariDataSource pds = new HikariDataSource();
15+
private HikariDataSource pds;
16+
private ConnectionConfig config;
2517

2618
public ConnectionInfo(String connectionInfo) {
27-
28-
pds.setJdbcUrl("jdbc:oracle:thin:" + connectionInfo);
19+
config = new ConnectionConfig(connectionInfo);
20+
pds = new HikariDataSource();
2921
pds.setAutoCommit(false);
3022
}
3123

@@ -34,6 +26,9 @@ public void setMaxConnections( int maxConnections ) {
3426
}
3527

3628
public Connection getConnection() throws SQLException {
29+
if ( pds.getJdbcUrl() == null ) {
30+
new DataSourceProvider(config).testAndSetJdbcUrl(pds);
31+
}
3732
return pds.getConnection();
3833
}
3934

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.utplsql.cli;
2+
3+
public class ConnectionInfoBuilder {
4+
5+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package org.utplsql.cli.datasource;
2+
3+
import com.zaxxer.hikari.HikariDataSource;
4+
import org.utplsql.cli.ConnectionConfig;
5+
import org.utplsql.cli.exception.DatabaseConnectionFailed;
6+
7+
import java.io.File;
8+
import java.sql.Connection;
9+
import java.sql.SQLException;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
13+
public class DataSourceProvider {
14+
15+
interface ConnectStringPossibility {
16+
String getConnectString(ConnectionConfig config);
17+
String getMaskedConnectString(ConnectionConfig config);
18+
}
19+
20+
static {
21+
String oracleHome = System.getenv("ORACLE_HOME");
22+
if (oracleHome != null && System.getProperty("oracle.net.tns_admin") == null) {
23+
System.setProperty("oracle.net.tns_admin",
24+
String.join(File.separator, oracleHome, "NETWORK", "ADMIN"));
25+
}
26+
}
27+
28+
private final ConnectionConfig config;
29+
private List<ConnectStringPossibility> possibilities = new ArrayList<>();
30+
31+
public DataSourceProvider(ConnectionConfig config) {
32+
this.config = config;
33+
34+
possibilities.add(new ThickConnectStringPossibility());
35+
possibilities.add(new ThinConnectStringPossibility());
36+
}
37+
38+
public HikariDataSource getDataSource() throws SQLException {
39+
40+
HikariDataSource ds = new HikariDataSource();
41+
42+
testAndSetJdbcUrl(ds);
43+
44+
return ds;
45+
}
46+
47+
public void testAndSetJdbcUrl( HikariDataSource ds ) throws SQLException
48+
{
49+
List<String> errors = new ArrayList<>();
50+
Throwable lastException = null;
51+
for (ConnectStringPossibility possibility : possibilities) {
52+
ds.setJdbcUrl(possibility.getConnectString(config));
53+
try (Connection con = ds.getConnection()) {
54+
return;
55+
} catch (UnsatisfiedLinkError | Exception e) {
56+
errors.add(possibility.getMaskedConnectString(config) + ": " + e.getMessage());
57+
lastException = e;
58+
}
59+
}
60+
61+
errors.forEach(System.out::println);
62+
throw new DatabaseConnectionFailed(lastException);
63+
}
64+
65+
private static class ThickConnectStringPossibility implements ConnectStringPossibility {
66+
@Override
67+
public String getConnectString(ConnectionConfig config) {
68+
return "jdbc:oracle:oci8:" + config.getConnectString();
69+
}
70+
71+
@Override
72+
public String getMaskedConnectString(ConnectionConfig config) {
73+
return "jdbc:oracle:oci8:****/****@" + config.getConnect();
74+
}
75+
}
76+
77+
private static class ThinConnectStringPossibility implements ConnectStringPossibility {
78+
@Override
79+
public String getConnectString(ConnectionConfig config) {
80+
return "jdbc:oracle:thin:" + config.getConnectString();
81+
}
82+
83+
@Override
84+
public String getMaskedConnectString(ConnectionConfig config) {
85+
return "jdbc:oracle:thin:****/****@" + config.getConnect();
86+
}
87+
}
88+
}

src/main/java/org/utplsql/cli/exception/DatabaseConnectionFailed.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
public class DatabaseConnectionFailed extends SQLException {
66

7-
public DatabaseConnectionFailed(SQLException cause ) {
7+
public DatabaseConnectionFailed(Throwable cause ) {
88
super( "Could not establish connection to database. Reason: " + cause.getMessage(), cause);
99
}
1010
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.utplsql.cli;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.utplsql.cli.datasource.DataSourceProvider;
5+
6+
import javax.sql.DataSource;
7+
import java.io.IOException;
8+
import java.sql.SQLException;
9+
10+
import static org.junit.jupiter.api.Assertions.assertNotNull;
11+
12+
public class DataSourceProviderIT {
13+
14+
@Test
15+
public void connectToDatabase() throws IOException, SQLException {
16+
17+
ConnectionConfig config = new ConnectionConfig(RunCommandTestHelper.getConnectionString());
18+
19+
DataSource dataSource = new DataSourceProvider(config).getDataSource();
20+
21+
assertNotNull(dataSource);
22+
}
23+
}

0 commit comments

Comments
 (0)