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