-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathTestedDataSourceProvider.java
More file actions
132 lines (106 loc) · 4.87 KB
/
Copy pathTestedDataSourceProvider.java
File metadata and controls
132 lines (106 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package org.utplsql.cli.datasource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.utplsql.api.EnvironmentVariableUtil;
import org.utplsql.cli.ConnectionConfig;
import org.utplsql.cli.exception.DatabaseConnectionFailed;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestedDataSourceProvider {
interface ConnectStringPossibility {
String getConnectString(ConnectionConfig config);
String getMaskedConnectString(ConnectionConfig config);
}
private static final Logger logger = LoggerFactory.getLogger(TestedDataSourceProvider.class);
private final ConnectionConfig config;
private final List<ConnectStringPossibility> possibilities = new ArrayList<>();
private final int maxConnections;
public TestedDataSourceProvider(ConnectionConfig config, int maxConnections) {
this.config = config;
this.maxConnections = maxConnections;
possibilities.add(new ThickConnectStringPossibility());
possibilities.add(new ThinConnectStringPossibility());
}
public DataSource getDataSource() throws SQLException {
InitializableOracleDataSource ds = new InitializableOracleDataSource();
setInitSqlFrom_NLS_LANG(ds);
setThickOrThinJdbcUrl(ds);
return ds;
}
private void setThickOrThinJdbcUrl(InitializableOracleDataSource ds) throws SQLException {
List<String> errors = new ArrayList<>();
Throwable lastException = null;
// With external authentication (Oracle Wallet) the driver looks up the credentials itself
if (!config.isExternalAuthentication()) {
ds.setUser(config.getUser());
ds.setPassword(config.getPassword());
}
for (ConnectStringPossibility possibility : possibilities) {
logger.debug("Try connecting {}", possibility.getMaskedConnectString(config));
ds.setURL(possibility.getConnectString(config));
try (Connection ignored = ds.getConnection()) {
logger.info("Use connection string {}", possibility.getMaskedConnectString(config));
return;
} catch (Error | Exception e) {
errors.add(possibility.getMaskedConnectString(config) + ": " + e.getMessage());
lastException = e;
}
}
errors.forEach(System.out::println);
throw new DatabaseConnectionFailed(lastException);
}
private void setInitSqlFrom_NLS_LANG(InitializableOracleDataSource ds) {
String nls_lang = EnvironmentVariableUtil.getEnvValue("NLS_LANG");
if (nls_lang != null) {
Pattern pattern = Pattern.compile("^([a-zA-Z ]+)?_?([a-zA-Z ]+)?\\.?([a-zA-Z0-9]+)?$");
Matcher matcher = pattern.matcher(nls_lang);
List<String> sqlCommands = new ArrayList<>(2);
if (matcher.matches()) {
if (matcher.group(1) != null) {
sqlCommands.add(String.format("ALTER SESSION SET NLS_LANGUAGE='%s'", matcher.group(1)));
}
if (matcher.group(2) != null) {
sqlCommands.add(String.format("ALTER SESSION SET NLS_TERRITORY='%s'", matcher.group(2)));
}
if (!sqlCommands.isEmpty()) {
StringBuilder sb = new StringBuilder();
sb.append("BEGIN\n");
for (String command : sqlCommands) {
sb.append(String.format("EXECUTE IMMEDIATE q'[%s]';\n", command));
}
sb.append("END;");
logger.debug("NLS settings: {}", sb);
ds.setConnectionInitSql(sb.toString());
}
}
}
}
private static class ThickConnectStringPossibility implements ConnectStringPossibility {
@Override
public String getConnectString(ConnectionConfig config) {
return "jdbc:oracle:oci8:@" + config.getConnect();
}
@Override
public String getMaskedConnectString(ConnectionConfig config) {
return "jdbc:oracle:oci8:" + maskedCredentials(config) + "@" + config.getConnect();
}
}
private static class ThinConnectStringPossibility implements ConnectStringPossibility {
@Override
public String getConnectString(ConnectionConfig config) {
return "jdbc:oracle:thin:@" + config.getConnect();
}
@Override
public String getMaskedConnectString(ConnectionConfig config) {
return "jdbc:oracle:thin:" + maskedCredentials(config) + "@" + config.getConnect();
}
}
private static String maskedCredentials(ConnectionConfig config) {
return config.isExternalAuthentication() ? "/" : "****/****";
}
}