ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/core/ConfigurationManagerServant.java
(Generate patch)

Comparing projects/cms/source/server/uk/org/iscream/cms/server/core/ConfigurationManagerServant.java (file contents):
Revision 1.3 by ajm, Tue Nov 21 21:58:52 2000 UTC vs.
Revision 1.15 by ajm, Sat Mar 3 14:52:56 2001 UTC

# Line 1 | Line 1
1   //---PACKAGE DECLARATION---
2 + package uk.ac.ukc.iscream.core;
3  
4   //---IMPORTS---
5 < import uk.ac.ukc.iscream.core.*;
5 > import uk.ac.ukc.iscream.util.*;
6 > import uk.ac.ukc.iscream.componentmanager.*;
7 > import java.net.InetAddress;
8 > import java.net.UnknownHostException;
9   import java.util.*;
10   import java.io.*;
7 import org.omg.CORBA.*;
8 import org.omg.PortableServer.*;
11  
12   /**
13   * This class is essentially a Configuration factory.
# Line 18 | Line 20 | import org.omg.PortableServer.*;
20   *
21   * It also relies on the System.properties to set internal values.
22   *
23 + * ###
24 + * A point to note is that this class does NOT yet manage
25 + * created configurations which may cause memory problems!
26 + * ###
27 + *
28   * @author  $Author$
29   * @version $Id$
30   */
# Line 37 | Line 44 | class ConfigurationManagerServant extends Configuratio
44      /**
45       * Creates a new ConfiguratorServant
46       * This class uses the System.properties to set internal values
40     *
41     * @param rootPOARef a reference to the RootPOA
42     * @param logRef a reference to the Logger
47       */
48 <    ConfigurationManagerServant(POA rootPOARef, Logger logRef) {
48 >    ConfigurationManagerServant() {
49          // assign some local variables
46        _rootPOARef = rootPOARef;
47        _logRef = logRef;
50          _configPath = System.getProperty("uk.ac.ukc.iscream.ConfigurationLocation");
51          _systemConfigFile = System.getProperty("uk.ac.ukc.iscream.SystemConfigurationFile");
52  
# Line 52 | Line 54 | class ConfigurationManagerServant extends Configuratio
54          loadSystemConfig();
55  
56          // log our status
57 <        _logRef.write(this.toString(), Logger.SYSINIT, "started");
58 <        _logRef.write(this.toString(), Logger.SYSMSG, "configuration location - " + _configPath);
59 <        _logRef.write(this.toString(), Logger.SYSMSG, "system configuration file - " + _systemConfigFile);
57 >        _logger.write(toString(), Logger.SYSINIT, "started");
58 >        _logger.write(toString(), Logger.SYSMSG, "configuration location - " + _configPath);
59 >        _logger.write(toString(), Logger.SYSMSG, "system configuration file - " + _systemConfigFile);
60      }
61  
62   //---PUBLIC METHODS---
# Line 79 | Line 81 | class ConfigurationManagerServant extends Configuratio
81       * @return the Configuration
82       */
83      public Configuration getConfiguration(String source) {
84 <        _logRef.write(this.toString(), Logger.SYSMSG, "got request for " + source);
85 <        Configuration config = null;
84 >        _logger.write(toString(), Logger.SYSMSG, "got request for " + source);
85 >
86          
87          // check to see if we need to reload the system config
88          // because it has changed
89          if (isModified(_systemConfig.getFileList(), _systemConfig.getLastModified())) {
90 <            _logRef.write(this.toString(), Logger.SYSMSG, "system config changed");
90 >            _logger.write(toString(), Logger.SYSMSG, "system config changed");
91              loadSystemConfig();
92          }
93  
94 <        // we look for this entry in the systemConfig
95 <        String configFile = _systemConfig.getProperty("config." + source);
96 <        _logRef.write(this.toString(), Logger.DEBUG, "looking for config tree in - " + configFile);
97 <
98 <        // if there is an entry
99 <        if (configFile != null) {
94 >        // search config for group membership
95 >        LinkedList groups = getGroupMembership(source);
96 >        
97 >        // if we are dealing with a Host.<hostname> request, then we also
98 >        // want to look for ip address details, as configuration entries may relate to it
99 >        // if we can't resolve it, we don't look.
100 >        if (source.startsWith("Host.")) {
101 >            // hostname is after Host.
102 >            String hostname = source.substring(5);
103              try {
104 <                // get the file list of includes etc
105 <                String fileList = getIncludedFiles(configFile);            
106 <                _logRef.write(this.toString(), Logger.DEBUG, "config tree - " + fileList);
107 <                
108 <                // build the properites here from the filelist....
109 <                StringTokenizer st = new StringTokenizer(fileList, ";");
110 <                
111 <                // some holders for variables
107 <                File currentFile;
108 <                long lastModified, newLastModified;
109 <                Properties properties, prevProperties;
110 <                
111 <                // the root of all configurations will be the system config
112 <                // so we need to open the properties of that
113 <                Properties defaultProperties = new Properties();
114 <                currentFile = new File(_configPath, _systemConfigFile);
115 <                lastModified = currentFile.lastModified();
116 <                defaultProperties.load(new FileInputStream(currentFile));
117 <                
118 <                // This loop then iterates over the file list
119 <                // creates the properties to be passed to the
120 <                // Configuration constructor
121 <                do {
122 <                    properties = new Properties(defaultProperties);
123 <                    currentFile = new File(_configPath, st.nextToken());
124 <                    newLastModified = currentFile.lastModified();
125 <                    if (newLastModified > lastModified) {
126 <                        lastModified = newLastModified;
127 <                    }
128 <                    properties.load(new FileInputStream(currentFile));
129 <                    defaultProperties = properties;
130 <                } while (st.hasMoreTokens());
104 >                String ip = "Host." + InetAddress.getByName(hostname).getHostAddress();
105 >                LinkedList ipGroups = getGroupMembership(ip);
106 >                groups.addFirst(ip);
107 >                groups.addAll(ipGroups);
108 >            } catch (UnknownHostException e) {
109 >                _logger.write(toString(), Logger.ERROR, "could not resolve hostname - " + hostname);
110 >            }
111 >        }
112  
113 <                // this creates the configuration, all nice, ready to be returned
114 <                ConfigurationServant ref = new ConfigurationServant(properties, fileList, lastModified, _logRef);
134 <                org.omg.CORBA.Object objRef = _rootPOARef.servant_to_reference(ref);
135 <                config = ConfigurationHelper.narrow(objRef);
113 >        // add the hosts individual config to the start of the list
114 >        groups.addFirst(source);
115  
116 <            } catch (Exception e) {
117 <                // not sure what to do here
118 <                System.err.println("CONFIGURATION MANAGER ERROR: " + e);
119 <                e.printStackTrace(System.out);
116 >        Iterator i = groups.iterator();
117 >        String fileList = "";
118 >        while (i.hasNext()) {
119 >            String groupName = (String) i.next();
120 >            _logger.write(toString(), Logger.DEBUG, "looking for config entry for - " + groupName);
121 >            // we look for this entry in the systemConfig
122 >            String configFile = _systemConfig.getProperty("config." + groupName);
123 >            // if there is a config entry then
124 >            if (configFile != null) {
125 >                _logger.write(toString(), Logger.DEBUG, "looking for config tree in - " + configFile);
126 >    
127 >                // get the file list of includes etc + the system config
128 >                String groupFileList = null;
129 >                try {
130 >                    groupFileList = getIncludedFiles(configFile, "") + ";";
131 >                } catch (Exception e) {
132 >                    // not sure what to do here
133 >                    // so we just log the error
134 >                    _logger.write(toString(), Logger.ERROR, "ERROR - " + e);
135 >                }
136 >                if (groupFileList != null) {
137 >                    fileList += groupFileList;
138 >                }
139 >            } else {
140 >                _logger.write(toString(), Logger.DEBUG, "no config entry for - " + groupName);
141              }
142            
143        // if there isn't an entry for he requested config
144        } else {
145            _logRef.write(this.toString(), Logger.DEBUG, "no configured config, returning " + _systemConfigFile);
146            config = _systemConfig;
142          }
143 +        // add the system config as the final check
144 +        fileList = _systemConfigFile + ";" + fileList;
145 +        _logger.write(toString(), Logger.DEBUG, "config tree - " + fileList);
146          
147 +        // build the configuration
148 +        Configuration config = buildConfiguration(fileList);
149 +        
150          // if this is null at this point, then there will have been an error
151          return config;
152      }
# Line 175 | Line 176 | class ConfigurationManagerServant extends Configuratio
176          }
177          return false;
178      }
179 <    
179 >
180      /**
181       * Overrides the {@link java.lang.Object#toString() Object.toString()}
182       * method to provide clean logging (every class should have this).
183       *
184 +     * This uses the uk.ac.ukc.iscream.util.FormatName class
185 +     * to format the toString()
186 +     *
187       * @return the name of this class and its CVS revision
188       */
189      public String toString() {
190 <        return this.getClass().getName() + "(" + REVISION.substring(11, REVISION.length() - 2) + ")";
190 >        return FormatName.getName(
191 >            _name,
192 >            getClass().getName(),
193 >            REVISION);
194      }
195  
196   //---PRIVATE METHODS---
# Line 195 | Line 202 | class ConfigurationManagerServant extends Configuratio
202       * This function calls itself.
203       *
204       * @param currentFile the current file to be processed
205 <     *
205 >     * @param readFiles used for recursion purposes only, these are the files it has read so far
206 >     *
207       * @return the current list that has been constructed
208       *
209       * @throws IOException if there is trouble reading the file
210       * @throws FileNotFoundException is there is trouble finding the file
211 +     * @throws CircularIncludeException this is if a circular include is detected
212       */
213 <    private String getIncludedFiles(String currentFile) throws IOException, FileNotFoundException {
213 >    private String getIncludedFiles(String currentFile, String readFiles) throws IOException, FileNotFoundException, Exception {
214 >        
215 >        // check for circular include here
216 >        if (hasDuplicate(currentFile, readFiles) || currentFile.equals(_systemConfigFile)) {
217 >            throw new CircularIncludeException(currentFile + " is included more than once");
218 >        }
219 >        
220 >        // if there wasn't, we're gonna use this file, so make a note of it as read
221 >        // (note the use of the ";", this is for the hasDuplicate, function)
222 >        readFiles = readFiles + currentFile + ";";
223 >
224          Properties properties = new Properties();
225          properties.load(new FileInputStream(new File(_configPath, currentFile)));
226 +        
227 +        // get the include property
228          String includes = properties.getProperty("include");
229 +
230 +        // if we're the last file with no includes, return our name
231          if (includes == null) {
232              return currentFile;
233 +        
234 +        // otherwise, recurse over our includes
235          } else {
236              StringTokenizer st = new StringTokenizer(includes, ";");
237              String returnList= "";
238              while (st.hasMoreTokens()) {
239 <                String nextFile = st.nextToken();
215 <                returnList = getIncludedFiles(nextFile) + ";" + returnList;
239 >                returnList = getIncludedFiles(st.nextToken(), readFiles) + ";" + returnList;
240              }
241 +            
242              return returnList + currentFile;
243          }
244      }
245  
246      /**
247 +     * This simple method checks to see if a given
248 +     * file exists in the given list.
249 +     *
250 +     * @param file the file to check the list for
251 +     * @param fileList the list to check
252 +     *
253 +     * @return if the given file appeard in the list
254 +     */
255 +    private boolean hasDuplicate(String file, String fileList) {
256 +        StringTokenizer st = new StringTokenizer(fileList, ";");
257 +        while (st.hasMoreTokens()) {
258 +            if (file.equals(st.nextToken())) {
259 +                return true;
260 +            }
261 +        }
262 +        return false;
263 +    }
264 +
265 +    /**
266       * Opens and loads the system configuration into the
267       * local reference _systemConfig
268       */
269      private void loadSystemConfig() {
270 <        _logRef.write(this.toString(), Logger.SYSMSG, "reloading" + _systemConfigFile);
270 >        _logger.write(this.toString(), Logger.SYSMSG, "reloading " + _systemConfigFile);
271          // get a reference to the system config and store it
272          try {
273              // create the properties for the configuration
274              File systemConfigFile = new File(_configPath, _systemConfigFile);
275 <            Properties systemConfigHolder = new Properties();
276 <            systemConfigHolder.load(new FileInputStream(systemConfigFile));
277 <                        
275 >            _systemConfigHolder = new Properties();
276 >            _systemConfigHolder.load(new FileInputStream(systemConfigFile));
277 >            
278              // create the servant
279 <            ConfigurationServant ref = new ConfigurationServant(systemConfigHolder, _systemConfigFile, systemConfigFile.lastModified(), _logRef);
280 <            org.omg.CORBA.Object objRef = _rootPOARef.servant_to_reference(ref);
279 >            ConfigurationServant ref = new ConfigurationServant(_systemConfigHolder, _systemConfigFile, systemConfigFile.lastModified());
280 >            org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
281              
282              // narrow it to a Configuration
283              _systemConfig = ConfigurationHelper.narrow(objRef);
284              
285          } catch (Exception e) {
286 <            _logRef.write(this.toString(), Logger.FATAL, "ERROR: " + e.getMessage());
286 >            _logger.write(toString(), Logger.FATAL, "ERROR: " + e.getMessage());
287          }
288      }
289  
290 +    /**
291 +     * Parses the system configuration file
292 +     * for group membership entries.
293 +     *
294 +     * It looks for all entries of group.<name>
295 +     * which contain the given source name
296 +     *
297 +     * @param source the source to find membership for
298 +     *
299 +     * @return the list of groups that this source is a member of
300 +     */
301 +    private LinkedList getGroupMembership(String source) {
302 +        _logger.write(toString(), Logger.DEBUG, "searching group members for - " + source);
303 +        LinkedList groupMembership = new LinkedList();        
304 +        Iterator i = new TreeSet(_systemConfigHolder.keySet()).iterator();
305 +        while(i.hasNext()) {
306 +            String key = (String) i.next();
307 +            if (key.startsWith("group.")) {
308 +                String group = _systemConfig.getProperty(key);
309 +                // if it is in the group
310 +                if (group.indexOf(source) != -1) {
311 +                    groupMembership.add(key.substring(6));
312 +                
313 +                // if there are wildcards in the group
314 +                } else if (group.indexOf("*") != -1) {
315 +                    // check the wildcards apply to this srce
316 +                    if( wildcardCheck(source, group)) {
317 +                        groupMembership.add(key.substring(6));
318 +                    }
319 +                }
320 +                
321 +            }  
322 +        }
323 +        return groupMembership;
324 +    }    
325 +
326 +    /**
327 +     * Checks that a given string is not matched within the
328 +     * given list of strings. eg:<br>
329 +     * <br>
330 +     * Given "stue5de.ukc.ac.uk"<br>
331 +     * And   "raptor.ukc.ac.uk;stue*.ukc.ac.uk<br>
332 +     * <br>
333 +     * This method would return true as there is a match
334 +     *
335 +     * @param source the string to look for
336 +     * @param group the group to search for a wilcard entry
337 +     *
338 +     * @return if there is a match
339 +     */
340 +    private boolean wildcardCheck(String source, String group) {
341 +        boolean foundMatch = false;
342 +        StringTokenizer st = new StringTokenizer(group, ";");
343 +        // go through all the hosts in the group
344 +        while (st.hasMoreTokens()) {
345 +            String host = st.nextToken();
346 +            // this host has wildcards
347 +            if(host.indexOf("*") != -1) {
348 +                StringTokenizer hostst = new StringTokenizer(host, "*");
349 +                String part = "";
350 +                int index = 0;
351 +                // the first token will be everything at the start
352 +                // unless it starts with a wildcard
353 +                if(!host.startsWith("*")) {
354 +                    part = hostst.nextToken();
355 +                    if (source.startsWith(part)) {
356 +                        foundMatch = true;
357 +                        index = part.length();
358 +                    }
359 +                // all of the start of the string is matched
360 +                } else {
361 +                    foundMatch = true;
362 +                }
363 +                // if the start matched, we want to check the rest...
364 +                if (foundMatch) {
365 +                    while (hostst.hasMoreTokens()) {
366 +                        part = hostst.nextToken();
367 +                        // if the next section can't be matched
368 +                        // then this isn't in the source
369 +                        if(source.substring(index).indexOf(part) == -1) {
370 +                            foundMatch = false;
371 +                            // we don't want to look through any more of it
372 +                            break;
373 +                        } else {
374 +                            foundMatch = true;
375 +                            index += source.substring(index).indexOf(part) + part.length();
376 +                        }
377 +                    }
378 +                    // if we reach here and we've found a match
379 +                    // we want to check that the last part
380 +                    // of the wildcard string is the last part
381 +                    // of the source, if it is, we break out
382 +                    // and finish as we've found a match.
383 +                    // if the end of the wildcard is a *, then
384 +                    // we don't care
385 +                    if (!host.endsWith("*") && foundMatch) {
386 +                        if ((source.endsWith(part))) {
387 +                            _logger.write(toString(), Logger.DEBUG, "wildcard match found for - " + source + " in - " + host);
388 +                            break;
389 +                        // if there is no match, say so so we go round again
390 +                        } else {
391 +                            foundMatch = false;
392 +                        }
393 +                    } else if (foundMatch) {
394 +                        _logger.write(toString(), Logger.DEBUG, "wildcard match found for - " + source + " in - " + host);
395 +                        break;
396 +                    }
397 +                }
398 +            }
399 +        }
400 +        return foundMatch;
401 +    }
402 +
403 +
404 +    /**
405 +     * Build the properties as a Configuration to be
406 +     * returned to the caller
407 +     *
408 +     * @param fileList the list of files to build the configuration from
409 +     *
410 +     * @return the built Configuration
411 +     */
412 +    private Configuration buildConfiguration(String fileList) {
413 +        Configuration config = null;
414 +
415 +        // if there is an entry
416 +        if (!fileList.equals("")) {
417 +            try {
418 +                
419 +                // build the properites here from the filelist....
420 +                StringTokenizer st = new StringTokenizer(fileList, ";");
421 +                
422 +                // some holders for variables
423 +                File currentFile;
424 +                long lastModified = 0, newLastModified = 0;
425 +                Properties properties = null, prevProperties = null;
426 +                
427 +                // the root of all configurations will be the system config
428 +                // so we need to open the properties of that
429 +                Properties defaultProperties = new Properties();
430 +                
431 +                // This loop then iterates over the file list
432 +                // creates the properties to be passed to the
433 +                // Configuration constructor
434 +                while (st.hasMoreTokens()) {
435 +                    properties = new Properties(defaultProperties);
436 +                    currentFile = new File(_configPath, st.nextToken());
437 +                    newLastModified = currentFile.lastModified();
438 +                    if (newLastModified > lastModified) {
439 +                        lastModified = newLastModified;
440 +                    }
441 +                    properties.load(new FileInputStream(currentFile));
442 +                    defaultProperties = properties;
443 +                }
444 +
445 +                // this creates the configuration, all nice, ready to be returned
446 +                ConfigurationServant ref = new ConfigurationServant(properties, fileList, lastModified);
447 +                org.omg.CORBA.Object objRef = _refman.getRootPOA().servant_to_reference(ref);
448 +                config = ConfigurationHelper.narrow(objRef);
449 +                _logger.write(toString(), Logger.DEBUG, "returning built configuration");
450 +            } catch (Exception e) {
451 +                // not sure what to do here
452 +                // so we just log the error
453 +                _logger.write(toString(), Logger.ERROR, "ERROR - " + e);
454 +            }
455 +            
456 +        // if there isn't an entry for the requested config
457 +        } else {
458 +            _logger.write(toString(), Logger.DEBUG, "no configured config, returning " + _systemConfigFile);
459 +            config = _systemConfig;
460 +        }
461 +        return config;
462 +    }
463 +
464   //---ACCESSOR/MUTATOR METHODS---
465  
466   //---ATTRIBUTES---
467  
468      /**
469 <     * Local storage of the RootPOA
469 >     * This is the friendly identifier of the
470 >     * component this class is running in.
471 >     * eg, a Filter may be called "filter1",
472 >     * If this class does not have an owning
473 >     * component,  a name from the configuration
474 >     * can be placed here.  This name could also
475 >     * be changed to null for utility classes.
476       */
477 <    private POA _rootPOARef;
477 >    private String _name = Core.NAME;
478 >
479 >    /**
480 >     * This holds a reference to the
481 >     * system logger that is being used.
482 >     */
483 >    private Logger _logger = ReferenceManager.getInstance().getLogger();
484      
485      /**
486 <     * Local storage of the Logger
486 >     * A reference to the reference manager in use
487       */
488 <    private Logger _logRef;
488 >    private ReferenceManager _refman = ReferenceManager.getInstance();
489      
490      /**
491       * The root path to all configurations
# Line 271 | Line 501 | class ConfigurationManagerServant extends Configuratio
501       * An instance of the system config
502       */
503      private Configuration _systemConfig;
504 +    
505 +    /**
506 +     * The system config file represented by a
507 +     * properties object.
508 +     */
509 +    private Properties _systemConfigHolder;
510      
511   //---STATIC ATTRIBUTES---
512      

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines