Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Private Attributes
CacheConfig Class Reference

Reads conf file and provides methods to obtain cache info from it. More...

#include <conf_cache.h>

Collaboration diagram for CacheConfig:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 CacheConfig (std::string username="")
 Create a new CacheConfig instance.
void parseINIConf (std::string username, ConfigSections *cf)
 Parsers for the two different conf styles.
void parseXMLConf (std::string username, Arc::XMLNode cfg)
std::vector< std::string > getCacheDirs ()
std::vector< std::string > getRemoteCacheDirs ()
std::vector< std::string > getDrainingCacheDirs ()
void setCacheDirs (std::vector< std::string > cache_dirs)
 To allow for substitutions done during configuration.
void setRemoteCacheDirs (std::vector< std::string > remote_cache_dirs)
void setDrainingCacheDirs (std::vector< std::string > draining_cache_dirs)
int getCacheMax ()
int getCacheMin ()
bool cleanCache ()
std::string getLogLevel ()

Private Attributes

std::vector< std::string > _cache_dirs
 List of (cache dir [link dir])
std::vector< std::string > _remote_cache_dirs
 List of (cache dir [link dir]) for remote caches.
int _cache_max
int _cache_min
std::vector< std::string > _draining_cache_dirs
 Cache directories that are needed to be drained.
std::string _log_level
 cache-clean log level

Detailed Description

Reads conf file and provides methods to obtain cache info from it.

Definition at line 31 of file conf_cache.h.


Constructor & Destructor Documentation

CacheConfig::CacheConfig ( std::string  username = "")

Create a new CacheConfig instance.

Read the config file and fill in private member variables with cache parameters. If different users are defined in the conf file, use the cache parameters for the given username.

Definition at line 5 of file conf_cache.cpp.

                                          : _cache_max(100),
                                                _cache_min(100),
                                                _log_level("INFO") {
  // open conf file
  std::ifstream cfile;
  if(nordugrid_config_loc().empty()) read_env_vars(true);
  if(!config_open(cfile)) throw CacheConfigException("Can't open configuration file");
  
  /* detect type of file */
  switch(config_detect(cfile)) {
    case config_file_XML: {
      Arc::XMLNode cfg;
      if(!cfg.ReadFromStream(cfile)) {
        config_close(cfile);
        throw CacheConfigException("Can't interpret configuration file as XML");
      };
      config_close(cfile);
      try {
        parseXMLConf(username, cfg);
      } catch (CacheConfigException& e) {
        config_close(cfile);
        throw e;
      }
    }; break;
    case config_file_INI: {
      ConfigSections* cf = new ConfigSections(cfile);
      try {
        parseINIConf(username, cf);
      } catch (CacheConfigException& e) {
        delete cf;
        config_close(cfile);
        throw e;
      }
      delete cf;
    }; break;
    default: {
      config_close(cfile);
      throw CacheConfigException("Can't recognize type of configuration file");
    }; break;
  };
  config_close(cfile);
}

Here is the call graph for this function:


Member Function Documentation

bool CacheConfig::cleanCache ( ) [inline]

Definition at line 74 of file conf_cache.h.

{ return _cache_max < 100; };

Here is the caller graph for this function:

std::vector<std::string> CacheConfig::getCacheDirs ( ) [inline]

Definition at line 63 of file conf_cache.h.

{ return _cache_dirs; };

Here is the caller graph for this function:

int CacheConfig::getCacheMax ( ) [inline]

Definition at line 72 of file conf_cache.h.

{ return _cache_max; };

Here is the caller graph for this function:

int CacheConfig::getCacheMin ( ) [inline]

Definition at line 73 of file conf_cache.h.

{ return _cache_min; };

Here is the caller graph for this function:

std::vector<std::string> CacheConfig::getDrainingCacheDirs ( ) [inline]

Definition at line 65 of file conf_cache.h.

{ return _draining_cache_dirs; };

Here is the caller graph for this function:

std::string CacheConfig::getLogLevel ( ) [inline]

Definition at line 75 of file conf_cache.h.

{ return _log_level; };

Here is the caller graph for this function:

std::vector<std::string> CacheConfig::getRemoteCacheDirs ( ) [inline]

Definition at line 64 of file conf_cache.h.

{ return _remote_cache_dirs; };

Here is the caller graph for this function:

void CacheConfig::parseINIConf ( std::string  username,
ConfigSections cf 
)

Parsers for the two different conf styles.

Definition at line 48 of file conf_cache.cpp.

                                                                     {
  
  cf->AddSection("common");
  cf->AddSection("grid-manager");
  
  for(;;) {
    std::string rest;
    std::string command;
    cf->ReadNext(command,rest);

    if(command.length() == 0) break;
    
    else if(command == "remotecachedir") {
      std::string cache_dir = config_next_arg(rest);
      if(cache_dir.length() == 0) continue; // cache is disabled
      std::string cache_link_dir = config_next_arg(rest);
       
      // take off leading slashes
      if (cache_dir.rfind("/") == cache_dir.length()-1) cache_dir = cache_dir.substr(0, cache_dir.length()-1);

      // if there are substitutions, check username is defined
      if (username.empty() &&
          (cache_dir.find("%U") != std::string::npos ||
              cache_dir.find("%u") != std::string::npos ||
              cache_dir.find("%g") != std::string::npos ||
              cache_dir.find("%H") != std::string::npos ||
              cache_link_dir.find("%U") != std::string::npos ||  
              cache_link_dir.find("%u") != std::string::npos ||
              cache_link_dir.find("%g") != std::string::npos ||
              cache_link_dir.find("%H") != std::string::npos )) continue; 
      // add this cache to our list
      std::string cache = cache_dir;
      // check if the cache dir needs to be drained 
      bool isDrainingCache = false;
      if (cache_link_dir == "drain") {
        cache = cache_dir.substr(0, cache_dir.find(" "));
        cache_link_dir = "";
        isDrainingCache = true;
      }
      if (!cache_link_dir.empty()) cache += " "+cache_link_dir;
   
      if(isDrainingCache)
        _draining_cache_dirs.push_back(cache);  
      else
        _remote_cache_dirs.push_back(cache);
    }
    else if(command == "cachedir") {
      std::string cache_dir = config_next_arg(rest);
      if(cache_dir.length() == 0) continue; // cache is disabled
      std::string cache_link_dir = config_next_arg(rest);

      // validation of paths
      while (cache_dir.length() > 1 && cache_dir.rfind("/") == cache_dir.length()-1) cache_dir = cache_dir.substr(0, cache_dir.length()-1);
      if (cache_dir[0] != '/') throw CacheConfigException("Cache path must start with '/'");
      if (cache_dir.find("..") != std::string::npos) throw CacheConfigException("Cache path cannot contain '..'");
      if (!cache_link_dir.empty() && cache_link_dir != "." && cache_link_dir != "drain") {
        while (cache_link_dir.rfind("/") == cache_link_dir.length()-1) cache_link_dir = cache_link_dir.substr(0, cache_link_dir.length()-1);
        if (cache_link_dir[0] != '/') throw CacheConfigException("Cache link path must start with '/'");
        if (cache_link_dir.find("..") != std::string::npos) throw CacheConfigException("Cache link path cannot contain '..'");
      }
      
      // if there are substitutions, check username is defined
      if (username.empty() &&
          (cache_dir.find("%U") != std::string::npos ||
              cache_dir.find("%u") != std::string::npos ||
              cache_dir.find("%g") != std::string::npos ||
              cache_dir.find("%H") != std::string::npos ||
              cache_link_dir.find("%U") != std::string::npos ||  
              cache_link_dir.find("%u") != std::string::npos ||
              cache_link_dir.find("%g") != std::string::npos ||
              cache_link_dir.find("%H") != std::string::npos )) continue;

      // add this cache to our list
      std::string cache = cache_dir;
      bool isDrainingCache = false;
      // check if the cache dir needs to be drained 
      if (cache_link_dir == "drain") {
        cache = cache_dir.substr(0, cache_dir.find(' '));
        cache_link_dir = "";
        isDrainingCache = true;
      }
      if (!cache_link_dir.empty())
        cache += " "+cache_link_dir;

      if (isDrainingCache)
        _draining_cache_dirs.push_back(cache); 
      else
        _cache_dirs.push_back(cache);
    }
    else if(command == "cachesize") {
      std::string max_s = config_next_arg(rest);
      if(max_s.length() == 0)
        continue; 

      std::string min_s = config_next_arg(rest);
      if(min_s.length() == 0)
        throw CacheConfigException("Not enough parameters in cachesize parameter");

      off_t max_i;
      if(!Arc::stringto(max_s,max_i))
        throw CacheConfigException("bad number in cachesize parameter");
      if (max_i > 100 || max_i < 0)
        throw CacheConfigException("max cache size must be between 0 and 100");
      _cache_max = max_i;
      
      off_t min_i;
      if(!Arc::stringto(min_s,min_i))
        throw CacheConfigException("bad number in cachesize parameter");
      if (min_i > 100 || min_i < 0)
        throw CacheConfigException("max cache size must be between 0 and 100");
      if (min_i >= max_i)
        throw CacheConfigException("max cache size must be greater than min size");
      _cache_min = min_i;
    }
    else if(command == "cacheloglevel") {
      std::string log_level = config_next_arg(rest);
      if(log_level.length() == 0)
        throw CacheConfigException("No value specified in cacheloglevel");
      off_t level_i;
      if(!Arc::stringto(log_level, level_i))
        throw CacheConfigException("bad number in cacheloglevel parameter");
      // manual conversion from int to log level
      switch (level_i) {
        case 0: { _log_level = "FATAL"; };
          break;
        case 1: { _log_level = "ERROR"; };
          break;
        case 2: { _log_level = "WARNING"; };
          break;
        case 3: { _log_level = "INFO"; };
          break;
        case 4: { _log_level = "VERBOSE"; };
          break;
        case 5: { _log_level = "DEBUG"; };
          break;
        default: { _log_level = "INFO"; };
          break;
      } 
    }
    else if(command == "control") {
      // if the user specified here matches the one given, exit the loop
      config_next_arg(rest);
      bool usermatch = false;
      std::string user = config_next_arg(rest);
      while (user != "") {
        if(user == "*") {  /* add all gridmap users */
           if(!gridmap_user_list(rest)) throw CacheConfigException("Can't read users in gridmap file " + globus_gridmap());
        }
        else if (user == username || user == ".") {
          usermatch = true;
          break;
        }
        user = config_next_arg(rest);
      }
      if (usermatch) break;
      _cache_dirs.clear();
      _cache_max = 100;
      _cache_min = 100;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CacheConfig::parseXMLConf ( std::string  username,
Arc::XMLNode  cfg 
)

Definition at line 210 of file conf_cache.cpp.

                                                                 { 
  /*
  control
    username
    controlDir
    sessionRootDir
    cache
      location
        path
        link
      remotelocation
        path
        link
      highWatermark
      lowWatermark
      cacheLogLevel
    defaultTTL
    defaultTTR
    maxReruns
    noRootPower
  */
  Arc::XMLNode control_node = cfg["control"];
  while (control_node) {
    // does this match our username?
    std::string user = control_node["username"];
    if (user != username && user != ".") {
      ++control_node;
      continue;
    }
    Arc::XMLNode cache_node = control_node["cache"];
    if(cache_node) {
      Arc::XMLNode location_node = cache_node["location"];
      for(;location_node;++location_node) {
        std::string cache_dir = location_node["path"];
        std::string cache_link_dir = location_node["link"];
        if(cache_dir.length() == 0) 
          throw CacheConfigException("Missing path in cache location element");

        // validation of paths
        while (cache_dir.length() > 1 && cache_dir.rfind("/") == cache_dir.length()-1) cache_dir = cache_dir.substr(0, cache_dir.length()-1);
        if (cache_dir[0] != '/') throw CacheConfigException("Cache path must start with '/'");
        if (cache_dir.find("..") != std::string::npos) throw CacheConfigException("Cache path cannot contain '..'");
        if (!cache_link_dir.empty() && cache_link_dir != "." && cache_link_dir != "drain") {
          while (cache_link_dir.rfind("/") == cache_link_dir.length()-1) cache_link_dir = cache_link_dir.substr(0, cache_link_dir.length()-1);
          if (cache_link_dir[0] != '/') throw CacheConfigException("Cache link path must start with '/'");
          if (cache_link_dir.find("..") != std::string::npos) throw CacheConfigException("Cache link path cannot contain '..'");
        }
      
        // if there are user substitutions, check username is defined
        if (username.empty() &&
            (cache_dir.find("%U") != std::string::npos ||
                cache_dir.find("%u") != std::string::npos ||
                cache_dir.find("%g") != std::string::npos ||
                cache_dir.find("%H") != std::string::npos ||
                cache_link_dir.find("%U") != std::string::npos ||  
                cache_link_dir.find("%u") != std::string::npos ||
                cache_link_dir.find("%g") != std::string::npos ||
                cache_link_dir.find("%H") != std::string::npos )) continue;
        
        // add this cache to our list
        std::string cache = cache_dir;
        bool isDrainingCache = false;
        // check if the cache dir needs to be drained 
        if (cache_link_dir == "drain") {
          cache = cache_dir.substr(0, cache_dir.find (" "));
          cache_link_dir = "";
          isDrainingCache = true;
        }
  
        if (!cache_link_dir.empty())
          cache += " "+cache_link_dir;

        // TODO: handle paths with spaces
        if(isDrainingCache)
          _draining_cache_dirs.push_back(cache); 
        else
          _cache_dirs.push_back(cache);
      }
      Arc::XMLNode high_node = cache_node["highWatermark"];
      Arc::XMLNode low_node = cache_node["lowWatermark"];
      if (high_node && !low_node) {
        throw CacheConfigException("missing lowWatermark parameter");
      } else if (low_node && !high_node) {
        throw CacheConfigException("missing highWatermark parameter");
      } else if (low_node && high_node) {
        off_t max_i;
        if(!Arc::stringto((std::string)high_node,max_i))
          throw CacheConfigException("bad number in highWatermark parameter");
        if (max_i > 100)
          throw CacheConfigException("number is too high in highWatermark parameter");
        _cache_max = max_i;

        off_t min_i;
        if(!Arc::stringto((std::string)low_node,min_i))
          throw CacheConfigException("bad number in lowWatermark parameter");
        if (min_i > 100)
          throw CacheConfigException("number is too high in lowWatermark parameter");
        if (min_i >= max_i)
          throw CacheConfigException("highWatermark must be greater than lowWatermark");
        _cache_min = min_i;
      }
      std::string cache_log_level = cache_node["cacheLogLevel"];
      if (!cache_log_level.empty())
        _log_level = cache_log_level;
      Arc::XMLNode remote_location_node = cache_node["remotelocation"];
      for(;remote_location_node;++remote_location_node) {
        std::string cache_dir = remote_location_node["path"];
        std::string cache_link_dir = remote_location_node["link"];
        if(cache_dir.length() == 0) 
          throw CacheConfigException("Missing path in remote cache location element");

        // validation of paths
        while (cache_dir.length() > 1 && cache_dir.rfind("/") == cache_dir.length()-1) cache_dir = cache_dir.substr(0, cache_dir.length()-1);
        if (cache_dir[0] != '/') throw CacheConfigException("Remote cache path must start with '/'");
        if (cache_dir.find("..") != std::string::npos) throw CacheConfigException("Remote cache path cannot contain '..'");
        if (!cache_link_dir.empty() && cache_link_dir != "." && cache_link_dir != "drain" && cache_link_dir != "replicate") {
          while (cache_link_dir.rfind("/") == cache_link_dir.length()-1) cache_link_dir = cache_link_dir.substr(0, cache_link_dir.length()-1);
          if (cache_link_dir[0] != '/') throw CacheConfigException("Remote cache link path must start with '/'");
          if (cache_link_dir.find("..") != std::string::npos) throw CacheConfigException("Remote cache link path cannot contain '..'");
        }
      
        // if there are user substitutions, check username is defined
        if (username.empty() &&
            (cache_dir.find("%U") != std::string::npos ||
                cache_dir.find("%u") != std::string::npos ||
                cache_dir.find("%g") != std::string::npos ||
                cache_dir.find("%H") != std::string::npos ||
                cache_link_dir.find("%U") != std::string::npos ||  
                cache_link_dir.find("%u") != std::string::npos ||
                cache_link_dir.find("%g") != std::string::npos ||
                cache_link_dir.find("%H") != std::string::npos )) continue;
        
        // add this cache to our list
        std::string cache = cache_dir;
        bool isDrainingCache = false;
        // check if the cache dir needs to be drained 
        if (cache_link_dir == "drain") {
          cache = cache_dir.substr(0, cache_dir.find (" "));
          cache_link_dir = "";
          isDrainingCache = true;
        }
  
        if (!cache_link_dir.empty())
          cache += " "+cache_link_dir;

        // TODO: handle paths with spaces
        if(isDrainingCache)
          _draining_cache_dirs.push_back(cache); 
        else
          _remote_cache_dirs.push_back(cache);
      }
    } else {
      // cache is disabled
    }
    ++control_node;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CacheConfig::setCacheDirs ( std::vector< std::string >  cache_dirs) [inline]

To allow for substitutions done during configuration.

Definition at line 69 of file conf_cache.h.

{ _cache_dirs = cache_dirs; };

Here is the caller graph for this function:

void CacheConfig::setDrainingCacheDirs ( std::vector< std::string >  draining_cache_dirs) [inline]

Definition at line 71 of file conf_cache.h.

{ _draining_cache_dirs = draining_cache_dirs; }; 

Here is the caller graph for this function:

void CacheConfig::setRemoteCacheDirs ( std::vector< std::string >  remote_cache_dirs) [inline]

Definition at line 70 of file conf_cache.h.

{ _remote_cache_dirs = remote_cache_dirs; };

Member Data Documentation

std::vector<std::string> CacheConfig::_cache_dirs [private]

List of (cache dir [link dir])

Definition at line 36 of file conf_cache.h.

int CacheConfig::_cache_max [private]

Definition at line 41 of file conf_cache.h.

int CacheConfig::_cache_min [private]

Definition at line 42 of file conf_cache.h.

std::vector<std::string> CacheConfig::_draining_cache_dirs [private]

Cache directories that are needed to be drained.

Definition at line 46 of file conf_cache.h.

std::string CacheConfig::_log_level [private]

cache-clean log level

Definition at line 50 of file conf_cache.h.

std::vector<std::string> CacheConfig::_remote_cache_dirs [private]

List of (cache dir [link dir]) for remote caches.

Definition at line 40 of file conf_cache.h.


The documentation for this class was generated from the following files: