View Javadoc

1   /*
2    * ResourceManager.java
3    *
4    * Created on May 24, 2004, 3:17 PM
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 }