1
2
3
4
5
6
7
8
9
10
11 package gov.bnl.gums.db;
12
13 import gov.bnl.gums.*;
14
15 import gov.bnl.gums.persistence.HibernatePersistenceFactory;
16
17 import java.sql.Connection;
18 import java.sql.SQLException;
19 import java.util.ArrayList;
20 import java.util.Iterator;
21 import java.util.List;
22
23 import org.hibernate.*;
24 import org.hibernate.type.StringType;
25 import org.hibernate.type.Type;
26
27 import org.apache.log4j.Logger;
28
29
30
31
32
33 public class HibernateUserGroupDB implements UserGroupDB, ManualUserGroupDB {
34 private Logger log = Logger.getLogger(HibernateUserGroupDB.class);
35 private HibernatePersistenceFactory persistenceFactory;
36 private String group;
37 private List addedMembers;
38 private List removedMembers;
39
40
41 public HibernateUserGroupDB(HibernatePersistenceFactory persistenceFactory, String group) {
42 log.trace("HibernateUserGroupDB created for group " + group);
43 this.persistenceFactory = persistenceFactory;
44 this.group = group;
45 }
46
47 public String getGroup(){return group;};
48
49 public void addMember(GridUser user) {
50 Session session = null;
51 Transaction tx = null;
52 try {
53
54 session = persistenceFactory.retrieveSessionFactory().openSession();
55 tx = session.beginTransaction();
56 if (isMemberInGroup(user)) {
57 throw new Exception("User " + user + " is already present in group '" + group + "'");
58 }
59 addMember(session, tx, user);
60 tx.commit();
61
62 } catch (Exception e) {
63 log.error("Couldn't add member to '" + group + "'", e);
64 if (tx != null) {
65 try {
66 tx.rollback();
67 } catch (Exception e1) {
68 log.error("Hibernate error: rollback failed", e1);
69 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
70 }
71 }
72 throw new RuntimeException("Database error: " + e.getMessage(), e);
73 } finally {
74 if (session != null) {
75 try {
76 session.close();
77 } catch (Exception e1) {
78 log.error("Hibernate error: couldn't close session", e1);
79 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
80 }
81 }
82 }
83 }
84
85 public boolean isMemberInGroup(GridUser user) {
86 Session session = null;
87 Transaction tx = null;
88 try {
89 log.trace("Checking whether user " + user + " is in group " + group);
90
91 session = persistenceFactory.retrieveSessionFactory().openSession();
92 tx = session.beginTransaction();
93 boolean result = isMemberInGroup(session, tx, user);
94 tx.commit();
95 return result;
96
97 } catch (Exception e) {
98 log.error("Couldn't determine whether member is in group '" + group + "'", e);
99 if (tx != null) {
100 try {
101 tx.rollback();
102 } catch (Exception e1) {
103 log.error("Hibernate error: rollback failed", e1);
104 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
105 }
106 }
107 throw new RuntimeException("Database error: " + e.getMessage(), e);
108 } finally {
109 if (session != null) {
110 try {
111 session.close();
112 } catch (Exception e1) {
113 log.error("Hibernate error: couldn't close session", e1);
114 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
115 }
116 }
117 }
118 }
119
120 public void loadUpdatedList(java.util.List members) {
121 Session session = null;
122 Transaction tx = null;
123 int isolation = -1;
124 try {
125 if (log.isTraceEnabled()) {
126 log.trace("Changing the list of users in group " + group + " to " + members);
127 }
128
129 session = persistenceFactory.retrieveSessionFactory().openSession();
130 Connection conn = session.connection();
131 isolation = conn.getTransactionIsolation();
132 conn.setTransactionIsolation(conn.TRANSACTION_SERIALIZABLE);
133 tx = session.beginTransaction();
134
135
136 List currentMembers = retrieveMembers(session, tx);
137
138
139 List newMembers = new ArrayList(members);
140 newMembers.removeAll(currentMembers);
141 List oldMembers = new ArrayList(currentMembers);
142 oldMembers.removeAll(members);
143
144
145 if (log.isTraceEnabled()) {
146 log.trace("Removing old members from group " + group + ": " + oldMembers);
147 }
148 Iterator iter = oldMembers.iterator();
149 while (iter.hasNext()) {
150 GridUser user = (GridUser) iter.next();
151 removeMember(session, tx, user);
152 }
153
154
155 if (log.isTraceEnabled()) {
156 log.trace("Adding new members from group " + group + ": " + newMembers);
157 }
158 iter = newMembers.iterator();
159 while (iter.hasNext()) {
160 GridUser user = (GridUser) iter.next();
161 addMember(session, tx, user);
162 }
163
164 tx.commit();
165
166 addedMembers = newMembers;
167 removedMembers = oldMembers;
168
169 } catch (Exception e) {
170 log.error("Couldn't update members of group '" + group + "'", e);
171 if (tx != null) {
172 try {
173 tx.rollback();
174 } catch (Exception e1) {
175 log.error("Hibernate error: rollback failed", e1);
176 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
177 }
178 }
179 if ((e instanceof JDBCException) &&
180 (e.getCause() != null) &&
181 (e.getCause() instanceof SQLException) &&
182 (e.getCause().getMessage().indexOf("transaction") != -1)) {
183 throw new RuntimeException("Update failed: probably there is another update running simultaneously.");
184 }
185 throw new RuntimeException("Database error: " + e.getMessage(), e);
186 } finally {
187 if (session != null) {
188 try {
189 if (isolation != -1) {
190 session.connection().setTransactionIsolation(isolation);
191 }
192 session.close();
193 } catch (Exception e1) {
194 log.error("Hibernate error: couldn't close session", e1);
195 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
196 }
197 }
198 }
199 }
200
201 public boolean removeMember(GridUser user) {
202 Session session = null;
203 Transaction tx = null;
204 try {
205
206 session = persistenceFactory.retrieveSessionFactory().openSession();
207 tx = session.beginTransaction();
208 boolean result = removeMember(session, tx, user);
209 tx.commit();
210 return result;
211
212 } catch (Exception e) {
213 log.error("Couldn't remove member from group '" + group + "'", e);
214 if (tx != null) {
215 try {
216 tx.rollback();
217 } catch (Exception e1) {
218 log.error("Hibernate error: rollback failed", e1);
219 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
220 }
221 }
222 throw new RuntimeException("Database error: " + e.getMessage(), e);
223 } finally {
224 if (session != null) {
225 try {
226 session.close();
227 } catch (Exception e1) {
228 log.error("Hibernate error: couldn't close session", e1);
229 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
230 }
231 }
232 }
233 }
234
235 public java.util.List retrieveMembers() {
236 Session session = null;
237 Transaction tx = null;
238 try {
239
240 log.trace("Retrieving members from group " + group);
241 session = persistenceFactory.retrieveSessionFactory().openSession();
242 tx = session.beginTransaction();
243 List members = retrieveMembers(session, tx);
244 tx.commit();
245 return members;
246
247 } catch (Exception e) {
248 log.error("Couldn't retrieve members from group '" + group + "'", e);
249 if (tx != null) {
250 try {
251 tx.rollback();
252 } catch (Exception e1) {
253 log.error("Hibernate error: rollback failed", e1);
254 throw new RuntimeException("Database errors: " + e.getMessage() + " - " + e1.getMessage(), e);
255 }
256 }
257 throw new RuntimeException("Database error: " + e.getMessage(), e);
258 } finally {
259 if (session != null) {
260 try {
261 session.close();
262 } catch (Exception e1) {
263 log.error("Hibernate error: couldn't close session", e1);
264 throw new RuntimeException("Database error: " + e1.getMessage(), e1);
265 }
266 }
267 }
268 }
269
270 public java.util.List retrieveNewMembers() {
271 return addedMembers;
272 }
273
274 public java.util.List retrieveRemovedMembers() {
275 return removedMembers;
276 }
277
278 private void addMember(Session session, Transaction tx, GridUser user) throws Exception {
279 HibernateUser hUser = new HibernateUser();
280 hUser.setGroup(group);
281 hUser.setDn(user.getCertificateDN());
282 hUser.setEmail(user.getEmail());
283 if (user.getVoFQAN() != null) {
284 hUser.setFqan(user.getVoFQAN().toString());
285 }
286 session.save(hUser);
287 }
288
289 private boolean isMemberInGroup(Session session, Transaction tx, GridUser user) throws Exception {
290 Query q;
291 if (user.getVoFQAN() == null) {
292 q = session.createQuery("FROM HibernateUser u WHERE u.group = ? AND u.dn = ? AND u.fqan is null");
293 } else {
294 q = session.createQuery("FROM HibernateUser u WHERE u.group = ? AND u.dn = ? AND u.fqan = ?");
295 q.setString(2, user.getVoFQAN().toString());
296 }
297 q.setString(0, group);
298 q.setString(1, user.getCertificateDN());
299 List result = q.list();
300 return result.size() > 0;
301 }
302
303 private boolean removeMember(Session session, Transaction tx, GridUser user) throws Exception {
304 Query q;
305 if (user.getVoFQAN() == null) {
306 q = session.createQuery("DELETE FROM HibernateUser WHERE group = ? AND dn = ? AND fqan is null");
307 } else {
308 q = session.createQuery("DELETE FROM HibernateUser WHERE group = ? AND dn = ? AND fqan = ?");
309 q.setString(2, user.getVoFQAN().toString());
310 }
311 q.setString(0, group);
312 q.setString(1, user.getCertificateDN());
313 return q.executeUpdate() > 0;
314 }
315
316 private java.util.List retrieveMembers(Session session, Transaction tx) throws Exception {
317 Query q;
318 q = session.createQuery("FROM HibernateUser u WHERE u.group = ?");
319 q.setString(0, group);
320 List hibernateUsers = q.list();
321 List members = new ArrayList(hibernateUsers.size());
322 Iterator iter = hibernateUsers.iterator();
323 while (iter.hasNext()) {
324 HibernateUser user = (HibernateUser) iter.next();
325 members.add(new GridUser(user.getDn(), user.getFqan(), user.getEmail(), false));
326 }
327 return members;
328 }
329 }