1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.common.database;
22
23 import org.apache.commons.pool.impl.GenericObjectPool;
24 import org.waarp.common.database.properties.DbProperties;
25 import org.waarp.common.database.properties.H2Properties;
26 import org.waarp.common.database.properties.MariaDBProperties;
27 import org.waarp.common.database.properties.MySQLProperties;
28 import org.waarp.common.database.properties.OracleProperties;
29 import org.waarp.common.database.properties.PostgreSQLProperties;
30 import org.waarp.common.logging.WaarpLogger;
31 import org.waarp.common.logging.WaarpLoggerFactory;
32 import org.waarp.common.utility.SystemPropertyUtil;
33 import org.waarp.common.utility.Version;
34
35 import java.sql.Connection;
36 import java.sql.SQLException;
37
38
39
40
41 public class ConnectionFactory {
42
43
44
45
46 private static final WaarpLogger logger =
47 WaarpLoggerFactory.getLogger(ConnectionFactory.class);
48
49
50
51
52 private static ConnectionFactory instance;
53
54
55
56
57 private final DbProperties properties;
58
59
60
61
62
63 private final String server;
64
65
66
67
68
69 private final String user;
70
71
72
73
74
75 private final String password;
76
77 private static final boolean AUTOCOMMIT = true;
78
79 private static final boolean READONLY = false;
80
81 private static final int MAX_CONNECTIONS_DEFAULT = 10;
82 private static final int MAX_IDLE_DEFAULT = 2;
83
84 private int maxConnections = MAX_CONNECTIONS_DEFAULT;
85 private int maxIdle = MAX_IDLE_DEFAULT;
86
87
88
89
90 private final WaarpBasicDataSource ds;
91
92
93
94
95
96
97
98
99
100 protected static DbProperties propertiesFor(final String server)
101 throws UnsupportedOperationException {
102 if (server.contains(H2Properties.getProtocolID())) {
103 return new H2Properties();
104 } else if (server.contains(MariaDBProperties.getProtocolID())) {
105 return new MariaDBProperties();
106 } else if (server.contains(MySQLProperties.getProtocolID())) {
107 return new MySQLProperties();
108 } else if (server.contains(OracleProperties.getProtocolID())) {
109 return new OracleProperties();
110 } else if (server.contains(PostgreSQLProperties.getProtocolID())) {
111 return new PostgreSQLProperties();
112 } else {
113 throw new UnsupportedOperationException(
114 "The requested database is not supported");
115 }
116 }
117
118
119
120
121
122
123
124
125
126 public static void initialize(final String server, final String user,
127 final String password)
128 throws SQLException, UnsupportedOperationException {
129 if (instance == null) {
130 instance =
131 new ConnectionFactory(propertiesFor(server), server, user, password);
132 }
133 }
134
135
136
137
138
139 public static ConnectionFactory getInstance() {
140 return instance;
141 }
142
143
144
145
146
147
148
149
150 public Connection getConnection() throws SQLException {
151 if (ds == null) {
152 throw new SQLException("ConnectionFactory is not inialized.");
153 }
154 try {
155 return ds.getConnection();
156 } catch (final SQLException e) {
157 throw new SQLException("Cannot access database", e);
158 }
159 }
160
161
162
163
164
165
166
167 private ConnectionFactory(final DbProperties properties, final String server,
168 final String user, final String password)
169 throws SQLException {
170 this.server = server;
171 this.user = user;
172 this.password = password;
173 this.properties = properties;
174
175 if (Version.version().contains("-jre")) {
176 ds = new WaarpBasicDataSourceJava8();
177 } else {
178 ds = new WaarpBasicDataSourceJava6();
179 }
180
181
182 ds.setDriverClassName(this.properties.getDriverName());
183 ds.setUrl(this.server);
184 ds.setUsername(this.user);
185 ds.setPassword(this.password);
186 ds.setDefaultAutoCommit(AUTOCOMMIT);
187 ds.setDefaultReadOnly(READONLY);
188 ds.setValidationQuery(this.properties.getValidationQuery());
189
190
191 Connection con = null;
192
193 maxConnections = MAX_CONNECTIONS_DEFAULT;
194 try {
195 con = getConnection();
196
197
198 maxConnections = Math.min(properties.getMaximumConnections(con),
199 SystemPropertyUtil.get(
200 SystemPropertyUtil.WAARP_DATABASE_CONNECTION_MAX,
201 MAX_CONNECTIONS_DEFAULT));
202 } catch (final SQLException e) {
203 logger.warn(
204 "Cannot fetch maximum connection allowed from database" + " : {}",
205 e.getMessage());
206 } finally {
207 if (con != null) {
208 con.close();
209 }
210 }
211 setMaxConnections(maxConnections);
212 logger.info("{}", this);
213 }
214
215
216
217
218
219
220 public void setMaxConnections(final int max) {
221
222 maxConnections = Math.max(max, MAX_IDLE_DEFAULT);
223 ds.setMaxActive(maxConnections);
224 maxIdle = Math.min(Math.max(maxConnections / 2, MAX_IDLE_DEFAULT * 2),
225 maxConnections);
226 if (maxIdle < GenericObjectPool.DEFAULT_MAX_IDLE) {
227 ds.setMaxIdle(maxIdle);
228 }
229 ds.setInitialSize(MAX_IDLE_DEFAULT);
230 }
231
232
233
234
235 public void close() {
236 logger.info("Closing ConnectionFactory");
237 ds.close();
238 }
239
240
241
242
243 public int getMaxConnections() {
244 return maxConnections;
245 }
246
247
248
249
250 public String getServer() {
251 return server;
252 }
253
254
255
256
257 public String getUser() {
258 return user;
259 }
260
261
262
263
264 public String getPassword() {
265 return password;
266 }
267
268
269
270
271 public DbProperties getProperties() {
272 return properties;
273 }
274
275 @Override
276 public String toString() {
277 final StringBuilder sb = new StringBuilder();
278 sb.append("Datapool:");
279 sb.append(server);
280 sb.append(", with user:");
281 sb.append(user);
282 sb.append(", AutoCommit:");
283 sb.append(AUTOCOMMIT);
284 sb.append(", DefaultReadOnly:");
285 sb.append(READONLY);
286 sb.append(", max connecions:");
287 sb.append(maxConnections);
288 return sb.toString();
289 }
290 }