1
2
3
4
5
6
7
8
9
10
11 package gov.bnl.gums.db;
12
13
14 import gov.bnl.gums.GridUser;
15 import gov.bnl.gums.persistence.HibernatePersistenceFactory;
16
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.Hashtable;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.hibernate.Query;
26 import org.hibernate.Session;
27 import org.hibernate.Transaction;
28 import org.hibernate.type.StringType;
29 import org.hibernate.type.Type;
30
31 import org.apache.log4j.Logger;
32
33
34
35
36
37 public class HibernateAccountMapperDB implements ManualAccountMapperDB, AccountPoolMapperDB {
38 private Logger log = Logger.getLogger(HibernateAccountMapperDB.class);
39 private HibernatePersistenceFactory persistenceFactory;
40 private String map;
41 private static Map needsCacheRefresh = Collections.synchronizedMap(new HashMap());
42
43
44 public HibernateAccountMapperDB(HibernatePersistenceFactory persistenceFactory, String map) {
45 this.persistenceFactory = persistenceFactory;
46 this.map = map;
47 }
48
49 public void addAccount(String account) {
50 Session session = null;
51 Transaction tx = null;
52 try {
53 log.trace("Adding account '" + account + "' to pool '" + map + "'");
54 session = persistenceFactory.retrieveSessionFactory().openSession();
55 tx = session.beginTransaction();
56 HibernateMapping map = retrieveMapping(session, tx, null, account);
57 if (map != null) {
58 return;
59 }
60 createMapping(session, tx, null, account);
61 tx.commit();
62 setNeedsCacheRefresh(true);
63
64 } catch (Exception e) {
65 log.error("Couldn't add account to pool '" + map + "'", e);
66 if (tx != null) {
67 try {
68 tx.rollback();
69 } catch (Exception e1) {
70 log.error("Hibernate error: rollback failed", e1);
71 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
72 }
73 }
74 throw new RuntimeException("Database error: " + e.getMessage(), e);
75 } finally {
76 if (session != null) {
77 try {
78 session.close();
79 } catch (Exception e1) {
80 log.error("Hibernate error: couldn't close session", e1);
81 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
82 }
83 }
84 }
85 }
86
87 public String assignAccount(GridUser user) {
88 Session session = null;
89 Transaction tx = null;
90 try {
91 log.trace("Assing an account to '" + user.getCertificateDN() + "' from pool '" + map + "'");
92 session = persistenceFactory.retrieveSessionFactory().openSession();
93 tx = session.beginTransaction();
94 Query q;
95 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn is null ORDER BY m.account");
96 q.setMaxResults(1);
97 q.setString(0, map);
98 HibernateMapping mapping = (HibernateMapping) q.uniqueResult();
99 if (mapping == null) {
100 tx.commit();
101 return null;
102 }
103 mapping.setDn(user.getCertificateDN());
104 tx.commit();
105 setNeedsCacheRefresh(true);
106 return mapping.getAccount();
107
108 } catch (Exception e) {
109 log.error("Couldn't assign account to '" + user.getCertificateDN() + "' from pool '" + map + "'", e);
110 if (tx != null) {
111 try {
112 tx.rollback();
113 } catch (Exception e1) {
114 log.error("Hibernate error: rollback failed", e1);
115 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
116 }
117 }
118 throw new RuntimeException("Database error: " + e.getMessage(), e);
119 } finally {
120 if (session != null) {
121 try {
122 session.close();
123 } catch (Exception e1) {
124 log.error("Hibernate error: couldn't close session", e1);
125 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
126 }
127 }
128 }
129 }
130
131 public void createMapping(String userDN, String account) {
132 Session session = null;
133 Transaction tx = null;
134 try {
135 log.trace("Creating mapping for map '" + map + "' DN '" + userDN + "' -> '" + account + "'");
136 session = persistenceFactory.retrieveSessionFactory().openSession();
137 tx = session.beginTransaction();
138 HibernateMapping map = retrieveMapping(session, tx, userDN, account);
139 if (map != null) {
140 return;
141 }
142 createMapping(session, tx, userDN, account);
143 tx.commit();
144 setNeedsCacheRefresh(true);
145
146 } catch (Exception e) {
147 log.error("Couldn't create mapping to '" + map + "'", e);
148 if (tx != null) {
149 try {
150 tx.rollback();
151 } catch (Exception e1) {
152 log.error("Hibernate error: rollback failed", e1);
153 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
154 }
155 }
156 throw new RuntimeException("Database error: " + e.getMessage(), e);
157 } finally {
158 if (session != null) {
159 try {
160 session.close();
161 } catch (Exception e1) {
162 log.error("Hibernate error: couldn't close session", e1);
163 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
164 }
165 }
166 }
167 }
168
169 public String getMap() {
170 return map;
171 }
172
173 public boolean needsCacheRefresh() {
174 if (needsCacheRefresh.get(map) != null)
175 return ((Boolean)needsCacheRefresh.get(map)).booleanValue();
176 else
177 return true;
178 }
179
180 public boolean removeAccount(String account) {
181 Session session = null;
182 Transaction tx = null;
183 try {
184 log.trace("Removing mapping from map '" + map + "' for account '" + account + "'");
185 session = persistenceFactory.retrieveSessionFactory().openSession();
186 tx = session.beginTransaction();
187 boolean result = removeAccount(session, tx, account);
188 tx.commit();
189 setNeedsCacheRefresh(true);
190 return result;
191
192 } catch (Exception e) {
193 log.error("Couldn't remove mapping from '" + map + "' for account '" + account + "'", e);
194 if (tx != null) {
195 try {
196 tx.rollback();
197 } catch (Exception e1) {
198 log.error("Hibernate error: rollback failed", e1);
199 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
200 }
201 }
202 throw new RuntimeException("Database error: " + e.getMessage(), e);
203 } finally {
204 if (session != null) {
205 try {
206 session.close();
207 } catch (Exception e1) {
208 log.error("Hibernate error: couldn't close session", e1);
209 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
210 }
211 }
212 }
213 }
214
215 public boolean removeMapping(String userDN) {
216 Session session = null;
217 Transaction tx = null;
218 try {
219 log.trace("Removing mapping from map '" + map + "' for DN '" + userDN + "'");
220 session = persistenceFactory.retrieveSessionFactory().openSession();
221 tx = session.beginTransaction();
222 boolean result = removeMapping(session, tx, userDN);
223 tx.commit();
224 setNeedsCacheRefresh(true);
225 return result;
226
227 } catch (Exception e) {
228 log.error("Couldn't remove mapping from '" + map + "' for DN '" + userDN + "'", e);
229 if (tx != null) {
230 try {
231 tx.rollback();
232 } catch (Exception e1) {
233 log.error("Hibernate error: rollback failed", e1);
234 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
235 }
236 }
237 throw new RuntimeException("Database error: " + e.getMessage(), e);
238 } finally {
239 if (session != null) {
240 try {
241 session.close();
242 } catch (Exception e1) {
243 log.error("Hibernate error: couldn't close session", e1);
244 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
245 }
246 }
247 }
248 }
249
250 public String retrieveAccount(GridUser user) {
251 Session session = null;
252 Transaction tx = null;
253 String userDN = user.getCertificateDN();
254 try {
255 log.trace("Retrieving account for user '" + userDN + "' from pool '" + map + "'");
256 session = persistenceFactory.retrieveSessionFactory().openSession();
257 tx = session.beginTransaction();
258 Query q;
259 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn = ? ORDER BY m.account");
260 q.setMaxResults(1);
261 q.setString(0, map);
262 q.setString(1, userDN);
263 HibernateMapping mapping = (HibernateMapping) q.uniqueResult();
264 tx.commit();
265 if (mapping == null)
266 return null;
267 return mapping.getAccount();
268
269 } catch (Exception e) {
270 log.error("Couldn't retrieve account for user '" + userDN + "' from pool '" + map + "'", e);
271 if (tx != null) {
272 try {
273 tx.rollback();
274 } catch (Exception e1) {
275 log.error("Hibernate error: rollback failed", e1);
276 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
277 }
278 }
279 throw new RuntimeException("Database error: " + e.getMessage(), e);
280 } finally {
281 if (session != null) {
282 try {
283 session.close();
284 } catch (Exception e1) {
285 log.error("Hibernate error: couldn't close session", e1);
286 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
287 }
288 }
289 }
290 }
291
292 public java.util.Map retrieveAccountMap() {
293 Session session = null;
294 Transaction tx = null;
295 try {
296 log.trace("Retrieving map for pool '" + map + "'");
297 session = persistenceFactory.retrieveSessionFactory().openSession();
298 tx = session.beginTransaction();
299 Query q;
300 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn is not null");
301 q.setString(0, map);
302 List mappings = (List) q.list();
303 Iterator iter = mappings.iterator();
304 Map map = new Hashtable();
305 while (iter.hasNext()) {
306 HibernateMapping mapping = (HibernateMapping) iter.next();
307 map.put(mapping.getDn(), mapping.getAccount());
308 }
309 tx.commit();
310 return map;
311
312 } catch (Exception e) {
313 log.error("Couldn't retrieve map for pool '" + map + "'", e);
314 if (tx != null) {
315 try {
316 tx.rollback();
317 } catch (Exception e1) {
318 log.error("Hibernate error: rollback failed", e1);
319 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
320 }
321 }
322 throw new RuntimeException("Database error: " + e.getMessage(), e);
323 } finally {
324 if (session != null) {
325 try {
326 session.close();
327 } catch (Exception e1) {
328 log.error("Hibernate error: couldn't close session", e1);
329 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
330 }
331 }
332 }
333 }
334
335 public String retrieveMapping(String userDN) {
336 Session session = null;
337 Transaction tx = null;
338 try {
339 log.trace("Retrieving mapping from map '" + map + "' for DN '" + userDN + "'");
340 session = persistenceFactory.retrieveSessionFactory().openSession();
341 tx = session.beginTransaction();
342 HibernateMapping map = retrieveMapping(session, tx, userDN);
343 tx.commit();
344 if (map == null)
345 return null;
346 return map.getAccount();
347
348 } catch (Exception e) {
349 log.error("Couldn't retrieve mapping from '" + map + "' for DN '" + userDN + "'", e);
350 if (tx != null) {
351 try {
352 tx.rollback();
353 } catch (Exception e1) {
354 log.error("Hibernate error: rollback failed", e1);
355 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
356 }
357 }
358 throw new RuntimeException("Database error: " + e.getMessage(), e);
359 } finally {
360 if (session != null) {
361 try {
362 session.close();
363 } catch (Exception e1) {
364 log.error("Hibernate error: couldn't close session", e1);
365 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
366 }
367 }
368 }
369 }
370
371 public java.util.Map retrieveReverseAccountMap() {
372 Session session = null;
373 Transaction tx = null;
374 try {
375 log.trace("Retrieving reverse map for pool '" + map + "'");
376 session = persistenceFactory.retrieveSessionFactory().openSession();
377 tx = session.beginTransaction();
378 Query q;
379 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.account is not null");
380 q.setString(0, map);
381 List mappings = (List) q.list();
382 Iterator iter = mappings.iterator();
383 Map reverseMap = new Hashtable();
384 while (iter.hasNext()) {
385 HibernateMapping mapping = (HibernateMapping) iter.next();
386 reverseMap.put(mapping.getAccount(), mapping.getDn()!=null?mapping.getDn():"");
387 }
388 tx.commit();
389 return reverseMap;
390
391 } catch (Exception e) {
392 log.error("Couldn't retrieve reverse map for pool '" + map + "'", e);
393 if (tx != null) {
394 try {
395 tx.rollback();
396 } catch (Exception e1) {
397 log.error("Hibernate error: rollback failed", e1);
398 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
399 }
400 }
401 throw new RuntimeException("Database error: " + e.getMessage(), e);
402 } finally {
403 if (session != null) {
404 try {
405 session.close();
406 } catch (Exception e1) {
407 log.error("Hibernate error: couldn't close session", e1);
408 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
409 }
410 }
411 }
412 }
413
414 public java.util.List retrieveUsersNotUsedSince(java.util.Date date) {
415 throw new UnsupportedOperationException("retrieveUsersNotUsedSince is not supported anymore");
416 }
417
418 public void setCacheRefreshed() {
419 setNeedsCacheRefresh(false);
420 }
421
422 public void unassignAccount(String account) {
423 Session session = null;
424 Transaction tx = null;
425 try {
426 log.trace("Unassign account '" + account + "' from pool '" + map + "'");
427 session = persistenceFactory.retrieveSessionFactory().openSession();
428 tx = session.beginTransaction();
429 Query q;
430 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.account = ?");
431 q.setString(0, map);
432 q.setString(1, account);
433 List mappings = (List) q.list();
434 Iterator iter = mappings.iterator();
435 while (iter.hasNext()) {
436 HibernateMapping mapping = (HibernateMapping) iter.next();
437 mapping.setDn(null);
438 }
439 tx.commit();
440 setNeedsCacheRefresh(true);
441
442 } catch (Exception e) {
443 log.error("Couldn't unassign account '" + account + "' from pool '" + map + "'", e);
444 if (tx != null) {
445 try {
446 tx.rollback();
447 } catch (Exception e1) {
448 log.error("Hibernate error: rollback failed", e1);
449 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
450 }
451 }
452 throw new RuntimeException("Database error: " + e.getMessage(), e);
453 } finally {
454 if (session != null) {
455 try {
456 session.close();
457 } catch (Exception e1) {
458 log.error("Hibernate error: couldn't close session", e1);
459 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
460 }
461 }
462 }
463 }
464
465 public void unassignUser(String userDN) {
466 Session session = null;
467 Transaction tx = null;
468 try {
469 log.trace("Unassign account for user '" + userDN + "' from pool '" + map + "'");
470 session = persistenceFactory.retrieveSessionFactory().openSession();
471 tx = session.beginTransaction();
472 Query q;
473 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn = ? ORDER BY m.account");
474 q.setMaxResults(1);
475 q.setString(0, map);
476 q.setString(1, userDN);
477 HibernateMapping mapping = (HibernateMapping) q.uniqueResult();
478 mapping.setDn(null);
479 tx.commit();
480 setNeedsCacheRefresh(true);
481
482 } catch (Exception e) {
483 log.error("Couldn't unassign account for user '" + userDN + "' from pool '" + map + "'", e);
484 if (tx != null) {
485 try {
486 tx.rollback();
487 } catch (Exception e1) {
488 log.error("Hibernate error: rollback failed", e1);
489 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
490 }
491 }
492 throw new RuntimeException("Database error: " + map + " " + userDN + " " + e.getMessage(), e);
493 } finally {
494 if (session != null) {
495 try {
496 session.close();
497 } catch (Exception e1) {
498 log.error("Hibernate error: couldn't close session", e1);
499 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
500 }
501 }
502 }
503 }
504
505 private void createMapping(Session session, Transaction tx, String userDN, String account) throws Exception {
506 HibernateMapping hMapping = new HibernateMapping();
507 hMapping.setMap(map);
508 hMapping.setDn(userDN);
509 hMapping.setAccount(account);
510 session.save(hMapping);
511 }
512
513 private boolean removeAccount(Session session, Transaction tx, String account) throws Exception {
514 Query q;
515 q = session.createQuery("DELETE FROM HibernateMapping WHERE map = ? AND account = ?");
516 q.setString(0, map);
517 q.setString(1, account);
518 return q.executeUpdate() > 0;
519 }
520
521 private boolean removeMapping(Session session, Transaction tx, String userDN) throws Exception {
522 Query q;
523 q = session.createQuery("DELETE FROM HibernateMapping WHERE map = ? AND dn = ?");
524 q.setString(0, map);
525 q.setString(1, userDN);
526 return q.executeUpdate() > 0;
527 }
528
529 private HibernateMapping retrieveMapping(Session session, Transaction tx, String userDN) throws Exception{
530 Query q;
531 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn = ?");
532 q.setString(0, map);
533 q.setString(1, userDN);
534 return (HibernateMapping) q.uniqueResult();
535 }
536
537 private HibernateMapping retrieveMapping(Session session, Transaction tx, String userDN, String account) throws Exception{
538 Query q;
539 if (userDN!=null) {
540 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn = ? AND m.account = ? ");
541 q.setString(0, map);
542 q.setString(1, userDN);
543 q.setString(2, account);
544 }
545 else {
546 q = session.createQuery("FROM HibernateMapping m WHERE m.map = ? AND m.dn is null AND m.account = ? ");
547 q.setString(0, map);
548 q.setString(1, account);
549 }
550 return (HibernateMapping) q.uniqueResult();
551 }
552
553 private void setNeedsCacheRefresh(boolean value) {
554 needsCacheRefresh.put(map, new Boolean(value));
555 }
556
557 }