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