1
2
3
4
5
6
7 package gov.bnl.gums;
8
9 import java.io.*;
10 import java.util.*;
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13
14 /*** The main interface of the Business Logic for GUMS, allows to update the
15 * groups, generate the gridMapfiles and to map a single user.
16 *
17 * @author Gabriele Carcassi
18 */
19 public class ResourceManager {
20 private Log log = LogFactory.getLog(ResourceManager.class);
21 private Log resourceAdminLog = LogFactory.getLog(GUMS.resourceAdminLog);
22
23 GUMS gums;
24
25 /*** Creates a Resource Manager for a particula instance of the GUMS server.
26 */
27 public ResourceManager(GUMS gums) {
28 this.gums = gums;
29 }
30
31 /*** Scans the configuration and calls updateMembers() on all the groups,
32 * updating the local database.
33 */
34 public void updateGroups() {
35 updateGroupsImpl();
36 }
37
38 private void updateGroupsImpl() {
39 boolean success = true;
40 UserGroup admins = gums.getConfiguration().getAdminGroup();
41 if (admins != null) {
42 log.debug("Updating group " + admins);
43 try {
44 admins.updateMembers();
45 resourceAdminLog.info("Admin group " + admins.toString() + " updated");
46 } catch (Exception e) {
47 resourceAdminLog.warn("Admin group " + admins.toString() + " wasn't updated successfully: " + " [" + e.getMessage() + "]");
48 log.warn("updateMember for " + admins + " threw an exception", e);
49 success = false;
50 }
51 }
52 Collection groups = gums.getConfiguration().getAllGroups();
53 log.info("Updating group information for all " + groups.size() + " groups");
54 Iterator iter = groups.iterator();
55 while (iter.hasNext()) {
56 UserGroup group = (UserGroup) iter.next();
57 log.debug("Updating group " + group);
58 try {
59 group.updateMembers();
60 resourceAdminLog.info(group.toString() + " updated");
61 } catch (Exception e) {
62 resourceAdminLog.warn(group.toString() + " wasn't updated successfully: " + " [" + e.getMessage() + "]");
63 log.warn("updateMember for " + group + " threw an exception", e);
64 success = false;
65 }
66 }
67 if (!success) {
68 throw new RuntimeException("Some groups weren't updated correctly: consult the logs for more details. Check GUMS configuration or the status of the VO servers.");
69 }
70 }
71
72 /*** Generates a grid mapfile for a given host and prints it to out.
73 */
74 public String generateGridMapfile(String hostname) {
75 String mapfile;
76 mapfile = generateGridMapfileImpl(hostname);
77 return mapfile;
78 }
79
80 private String generateGridMapfileImpl(String hostname) {
81 Configuration conf = gums.getConfiguration();
82 HostGroup hostGroup = hostGroup(conf, hostname);
83 if (hostGroup == null) return null;
84 String mapfile = generateGridMapfile(hostGroup);
85 return mapfile;
86 }
87
88 private HostGroup hostGroup(Configuration conf, String hostname) {
89 List hostGroups = conf.getHostGroup();
90 for (int i = 0; i < hostGroups.size(); i++) {
91 HostGroup group = (HostGroup) hostGroups.get(i);
92 if (group.isInGroup(hostname)) {
93 return group;
94 }
95 }
96 return null;
97 }
98
99 /***
100 * @todo usersInMap should be a sorted list to make things faster, but
101 * no ready made implementation was found.
102 */
103 private String generateGridMapfile(HostGroup group) {
104 Iterator iter = group.getGroupMappers().iterator();
105 List usersInMap = new ArrayList();
106
107 StringBuffer gridMapfileBuffer = new StringBuffer("");
108 while (iter.hasNext()) {
109 GroupMapper gMap = (GroupMapper) iter.next();
110 List members = gMap.getGroup().getMemberList();
111 members = new ArrayList(members);
112 Collections.sort(members, retrieveUserComparatorByDN());
113 gridMapfileBuffer.append("#---- members of vo: " + gMap.getGroup().getName() + " ----#\n");
114
115 Iterator memberIter = members.iterator();
116 while (memberIter.hasNext()) {
117 GridUser user = (GridUser) memberIter.next();
118 if ((!usersInMap.contains(user.getCertificateDN())) && (gMap.getGroup().isInGroup(new GridUser(user.getCertificateDN(), null)))) {
119 String username = gMap.getMapper().mapUser(user.getCertificateDN());
120 if (username != null) {
121 gridMapfileBuffer.append('"');
122 gridMapfileBuffer.append(user.getCertificateDN() );
123 gridMapfileBuffer.append('"' );
124 gridMapfileBuffer.append(' ' );
125 gridMapfileBuffer.append(username );
126 gridMapfileBuffer.append("\n");
127 usersInMap.add(user.getCertificateDN());
128 } else {
129 resourceAdminLog.warn("User " + user + " from group " + gMap.getGroup() + " can't be mapped.");
130 }
131 }
132 }
133 }
134 String finalGridmapfile = gridMapfileBuffer.toString();
135 return finalGridmapfile;
136 }
137
138 private Comparator retrieveUserComparatorByDN() {
139 return new Comparator() {
140 public int compare(Object o1, Object o2) {
141 GridUser user1 = (GridUser) o1;
142 GridUser user2 = (GridUser) o2;
143 return user1.getCertificateDN().compareTo(user2.getCertificateDN());
144 }
145 };
146 }
147
148 public String generateGrid3UserVoMap(String hostname) {
149 Configuration conf = gums.getConfiguration();
150 HostGroup hostGroup = hostGroup(conf, hostname);
151 if (hostGroup == null)
152 throw new RuntimeException("The host '" + hostname + "' is not defined in any group.");
153 StringBuffer grid3MapBuffer = new StringBuffer("");
154 Iterator iter = hostGroup.getGroupMappers().iterator();
155
156 grid3MapBuffer.append("#User-VO map\n");
157 grid3MapBuffer.append("# #comment line, format of each regular line line: account VO\n");
158 grid3MapBuffer.append("# Next 2 lines with VO names, same order, all lowercase, with case (lines starting with #voi, #VOc)\n");
159
160 String voi = "#voi";
161 String voc = "#VOc";
162 while (iter.hasNext()) {
163 GroupMapper gMap = (GroupMapper) iter.next();
164
165 if (gMap.getAccountingVo() != null && gMap.getAccountingDesc() != null && gMap.getGroup().getMemberList().size() != 0) {
166 voi = voi + " " + gMap.getAccountingVo();
167 voc = voc + " " + gMap.getAccountingDesc();
168 }
169 }
170
171 grid3MapBuffer.append(voi);
172 grid3MapBuffer.append("\n");
173 grid3MapBuffer.append(voc);
174 grid3MapBuffer.append("\n");
175
176 iter = hostGroup.getGroupMappers().iterator();
177
178 List accountsInMap = new ArrayList();
179
180 while (iter.hasNext()) {
181 GroupMapper gMap = (GroupMapper) iter.next();
182 List members = gMap.getGroup().getMemberList();
183 members = new ArrayList(members);
184 Collections.sort(members, retrieveUserComparatorByDN());
185 grid3MapBuffer.append("#---- accounts for vo: " + gMap.getGroup().getName() + " ----#\n");
186
187 Iterator memberIter = members.iterator();
188 while (memberIter.hasNext()) {
189 GridUser user = (GridUser) memberIter.next();
190 String username = gMap.getMapper().mapUser(user.getCertificateDN());
191 if ((username != null) && !accountsInMap.contains(username) && (gMap.getAccountingVo() != null)) {
192 grid3MapBuffer.append(username);
193 grid3MapBuffer.append(' ');
194 grid3MapBuffer.append(gMap.getAccountingVo());
195 grid3MapBuffer.append("\n");
196 accountsInMap.add(username);
197 }
198 }
199 }
200 String finalGrid3Map = grid3MapBuffer.toString();
201 return finalGrid3Map;
202 }
203
204 /*** Maps a user to a local account for a given host.
205 */
206 public String map(String hostname, GridUser user) {
207 String value;
208 value = mapImpl(hostname, user);
209 return value;
210 }
211
212 private String mapImpl(String hostname, GridUser user) {
213 Configuration conf = gums.getConfiguration();
214 HostGroup group = hostGroup(conf, hostname);
215 if (group == null) return null;
216 List groupMappers = group.getGroupMappers();
217 Iterator iter = groupMappers.iterator();
218 while (iter.hasNext()) {
219 GroupMapper gMap = (GroupMapper) iter.next();
220 if (gMap.getGroup().isInGroup(user)) {
221 String localUser = gMap.getMapper().mapUser(user.getCertificateDN());
222 if (user != null) {
223 return localUser;
224 } else {
225 if (conf.isErrorOnMissedMapping()) {
226 resourceAdminLog.error("User " + user + " wasn't mapped even though is present in group " + gMap.getGroup());
227 }
228 }
229 }
230 }
231 return null;
232 }
233 }