1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.database;
21
22 import io.netty.util.HashedWheelTimer;
23 import io.netty.util.Timer;
24 import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
25 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
26 import org.waarp.common.database.model.DbModel;
27 import org.waarp.common.database.model.DbModelFactory;
28 import org.waarp.common.database.model.DbType;
29 import org.waarp.common.database.model.EmptyDbModel;
30 import org.waarp.common.guid.GUID;
31 import org.waarp.common.logging.WaarpLogger;
32 import org.waarp.common.logging.WaarpLoggerFactory;
33 import org.waarp.common.utility.WaarpThreadFactory;
34
35 import java.sql.Connection;
36 import java.sql.SQLException;
37 import java.util.ConcurrentModificationException;
38 import java.util.concurrent.ConcurrentHashMap;
39 import java.util.concurrent.TimeUnit;
40
41
42
43
44
45
46
47 public class DbAdmin {
48
49
50
51 private static final WaarpLogger logger =
52 WaarpLoggerFactory.getLogger(DbAdmin.class);
53
54 public static final int RETRYNB = 3;
55
56 public static final long WAITFORNETOP = 100;
57
58
59
60
61 protected final DbType typeDriver;
62
63
64
65
66 private final DbModel dbModel;
67
68
69
70
71 private final String server;
72
73
74
75
76 private final String user;
77
78
79
80
81 private final String passwd;
82
83
84
85
86 private boolean isReadOnly;
87
88
89
90
91 private DbSession session;
92
93
94
95 private static int nbHttpSession;
96
97 protected static final Timer dbSessionTimer =
98 new HashedWheelTimer(new WaarpThreadFactory("TimerClose"), 50,
99 TimeUnit.MILLISECONDS, 1024);
100
101
102
103
104 public DbSession getSession() {
105 return session;
106 }
107
108
109
110
111 public final void setSession(final DbSession session) {
112 this.session = session;
113 }
114
115
116
117
118 public final boolean isReadOnly() {
119 return isReadOnly;
120 }
121
122
123
124
125
126
127 public final void validConnection()
128 throws WaarpDatabaseNoConnectionException {
129 try {
130 dbModel.validConnection(getSession());
131 } catch (final WaarpDatabaseNoConnectionException e) {
132 getSession().setDisActive(true);
133 throw e;
134 }
135 getSession().setDisActive(false);
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 public DbAdmin(final DbModel model, final String server, final String user,
165 final String passwd)
166 throws WaarpDatabaseNoConnectionException {
167 this.server = server;
168 this.user = user;
169 this.passwd = passwd;
170 dbModel = model;
171 typeDriver = model.getDbType();
172 if (typeDriver == null) {
173 logger.error("Cannot find TypeDriver");
174 throw new WaarpDatabaseNoConnectionException(
175 "Cannot find database drive");
176 }
177 setSession(new DbSession(this, false));
178 getSession().setAdmin(this);
179 isReadOnly = false;
180 validConnection();
181 getSession().useConnection();
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212 public DbAdmin(final DbModel model, final String server, final String user,
213 final String passwd, final boolean write)
214 throws WaarpDatabaseNoConnectionException {
215 this.server = server;
216 this.user = user;
217 this.passwd = passwd;
218 dbModel = model;
219 typeDriver = model.getDbType();
220 if (typeDriver == null) {
221 logger.error("Cannot find TypeDriver");
222 throw new WaarpDatabaseNoConnectionException(
223 "Cannot find database driver");
224 }
225 if (write) {
226 for (int i = 0; i < RETRYNB; i++) {
227 try {
228 setSession(new DbSession(this, false));
229 } catch (final WaarpDatabaseNoConnectionException e) {
230 logger.warn("Attempt of connection in error: " + i + " : {}",
231 e.getMessage());
232 continue;
233 }
234 isReadOnly = false;
235 getSession().setAdmin(this);
236 validConnection();
237 getSession().useConnection();
238
239 return;
240 }
241 } else {
242 for (int i = 0; i < RETRYNB; i++) {
243 try {
244 setSession(new DbSession(this, true));
245 } catch (final WaarpDatabaseNoConnectionException e) {
246 logger.warn("Attempt of connection in error: " + i + " : {}",
247 e.getMessage());
248 continue;
249 }
250 isReadOnly = true;
251 getSession().setAdmin(this);
252 validConnection();
253 getSession().useConnection();
254
255 return;
256 }
257 }
258 setSession(null);
259 logger.error("Cannot connect to Database!");
260 throw new WaarpDatabaseNoConnectionException("Cannot connect to database");
261 }
262
263
264
265
266 public DbAdmin() {
267
268 typeDriver = DbType.none;
269 DbModelFactory.classLoaded.add(DbType.none.name());
270 dbModel = new EmptyDbModel();
271 server = null;
272 user = null;
273 passwd = null;
274 }
275
276
277
278
279
280
281 public final void close() {
282 if (getSession() != null) {
283 getSession().endUseConnection();
284
285 getSession().forceDisconnect();
286 setSession(null);
287 }
288 }
289
290
291
292
293
294
295
296 public final void commit()
297 throws WaarpDatabaseSqlException, WaarpDatabaseNoConnectionException {
298 if (getSession() != null) {
299 getSession().commit();
300 }
301 }
302
303
304
305
306 public final String getServer() {
307 return server;
308 }
309
310
311
312
313 public final String getUser() {
314 return user;
315 }
316
317
318
319
320 public final String getPasswd() {
321 return passwd;
322 }
323
324
325
326
327 public final DbModel getDbModel() {
328 return dbModel;
329 }
330
331
332
333
334 public final DbType getTypeDriver() {
335 return typeDriver;
336 }
337
338 @Override
339 public String toString() {
340 return "Admin: " + typeDriver.name() + ':' + server + ':' + user + ':' +
341 (passwd == null? 0 : passwd.length());
342 }
343
344
345
346
347 private static final ConcurrentHashMap<GUID, DbSession> listConnection =
348 new ConcurrentHashMap<org.waarp.common.guid.GUID, DbSession>();
349
350
351
352
353 public static void incHttpSession() {
354 nbHttpSession++;
355 }
356
357
358
359
360 public static void decHttpSession() {
361 nbHttpSession--;
362 }
363
364
365
366
367 public static int getHttpSession() {
368 return nbHttpSession;
369 }
370
371
372
373
374
375
376
377 public static void addConnection(final GUID id, final DbSession session) {
378 listConnection.put(id, session);
379 }
380
381
382
383
384
385
386 public static void removeConnection(final GUID id) {
387 listConnection.remove(id);
388 }
389
390
391
392
393 public static int getNbConnection() {
394 return listConnection.size() - 1;
395 }
396
397
398
399
400 public static void closeAllConnection() {
401 logger.debug("DEBUG Close All Connections");
402 for (final DbSession session : listConnection.values()) {
403 logger.debug("Close (all) Db Conn: {}", session.getInternalId());
404 try {
405 final Connection connection = session.getConn();
406 if (connection != null) {
407 connection.close();
408 }
409 } catch (final SQLException ignored) {
410
411 } catch (final ConcurrentModificationException ignored) {
412
413 }
414 }
415 listConnection.clear();
416 for (final DbModel dbModel : DbModelFactory.dbModels) {
417 if (dbModel != null) {
418 dbModel.releaseResources();
419 }
420 }
421 dbSessionTimer.stop();
422 }
423
424
425
426
427 public static void checkAllConnections() {
428 for (final DbSession session : listConnection.values()) {
429 try {
430 session.checkConnection();
431 } catch (final WaarpDatabaseNoConnectionException e) {
432 logger.error("Database Connection cannot be reinitialized");
433 }
434 }
435 }
436
437
438
439
440
441 public final boolean isCompatibleWithThreadSharedConnexion() {
442 return typeDriver != DbType.MariaDB && typeDriver != DbType.MySQL &&
443 typeDriver != DbType.Oracle && typeDriver != DbType.none;
444 }
445 }