View Javadoc

1   /*
2    * HibernateMapping.java
3    *
4    * Created on June 16, 2005, 4:22 PM
5    *
6    * To change this template, choose Tools | Options and locate the template under
7    * the Source Creation and Management node. Right-click the template and choose
8    * Open. You can then make changes to the template in the Source Editor.
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   * @author Gabriele Carcassi, Jay Packard
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      /** Creates a new instance of HibernateMapping */
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          // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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         // Handles when transaction goes wrong...
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 }