Salome HOME
add method NameChanged to update title name
[modules/kernel.git] / src / ResourcesManager / ResourcesManager.cxx
index 5bcf6d8437d7fb61d098b20a525053cc85241400..03a0bf6847d35356505e60685af12c5eafc149d3 100644 (file)
@@ -1,25 +1,27 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
 #include "ResourcesManager.hxx" 
+#include "SALOME_ResourcesCatalog_Handler.hxx"
 #include <Basics_Utils.hxx>
 #include <fstream>
 #include <iostream>
 #include <string.h>
 #include <map>
 #include <list>
-
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef WIN32
+#else
+#include <unistd.h>
+#endif
 #include <libxml/parser.h>
 
 #include <algorithm>
 
 using namespace std;
 
+const string ResourcesManager_cpp::DEFAULT_RESOURCE_NAME = "localhost";
+
+static LoadRateManagerFirst first;
+static LoadRateManagerCycl cycl;
+static LoadRateManagerAltCycl altcycl;
+
+resourceParams::resourceParams()
+: can_launch_batch_jobs(false),
+  can_run_containers(false),
+  nb_proc(-1),
+  nb_node(-1),
+  nb_proc_per_node(-1),
+  cpu_clock(-1),
+  mem_mb(-1)
+{
+}
+
 //=============================================================================
 /*!
  * just for test
@@ -45,12 +67,19 @@ using namespace std;
 //=============================================================================
 
 ResourcesManager_cpp::
-ResourcesManager_cpp(const char *xmlFilePath) :
-    _path_resources(xmlFilePath)
+ResourcesManager_cpp(const char *xmlFilePath)
 {
+  _path_resources.push_back(xmlFilePath);
 #if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "ResourcesManager_cpp constructor" << endl;
+  std::cerr << "ResourcesManager_cpp constructor" << std::endl;
 #endif
+  _resourceManagerMap["first"]=&first;
+  _resourceManagerMap["cycl"]=&cycl;
+  _resourceManagerMap["altcycl"]=&altcycl;
+  _resourceManagerMap["best"]=&altcycl;
+  _resourceManagerMap[""]=&altcycl;
+
+  AddDefaultResourceInCatalog();
 }
 
 //=============================================================================
@@ -66,31 +95,75 @@ ResourcesManager_cpp(const char *xmlFilePath) :
 
 ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException)
 {
-#if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "ResourcesManager_cpp constructor" << endl;
-#endif
-  _isAppliSalomeDefined = (getenv("APPLI") != 0);
-  if(!getenv("KERNEL_ROOT_DIR"))
-    throw ResourcesException("you must define KERNEL_ROOT_DIR environment variable!!");
+  RES_MESSAGE("ResourcesManager_cpp constructor");
+
+  _resourceManagerMap["first"]=&first;
+  _resourceManagerMap["cycl"]=&cycl;
+  _resourceManagerMap["altcycl"]=&altcycl;
+  _resourceManagerMap["best"]=&altcycl;
+  _resourceManagerMap[""]=&altcycl;
+
+  AddDefaultResourceInCatalog();
 
-  if (_isAppliSalomeDefined)
+  bool default_catalog_resource = true;
+  if (getenv("USER_CATALOG_RESOURCES_FILE") != 0)
+  {
+    default_catalog_resource = false;
+    std::string user_file("");
+    user_file = getenv("USER_CATALOG_RESOURCES_FILE");
+    std::ifstream ifile(user_file.c_str(), std::ifstream::in );
+    if (ifile) {
+      // The file exists, and is open for input
+      _path_resources.push_back(user_file);
+    }
+    else {
+      default_catalog_resource = false;
+      RES_INFOS("Warning: USER_CATALOG_RESOURCES_FILE is set and file cannot be found.")
+      RES_INFOS("Warning: That's why we try to create a new one.")
+      std::ofstream user_catalog_file;
+      user_catalog_file.open(user_file.c_str());
+      if (user_catalog_file.fail())
+      {
+        RES_INFOS("Error: cannot write in the user catalog resouces files");
+        RES_INFOS("Error: using default CatalogResources.xml file");
+        default_catalog_resource = true;
+      }
+      else
+      {
+        user_catalog_file << "<!-- File created by SALOME -->" << std::endl;
+        user_catalog_file << "<!DOCTYPE ResourcesCatalog>" << std::endl;
+        user_catalog_file << "<resources>" << std::endl;
+        user_catalog_file << "   <machine name=\"localhost\" hostname=\"localhost\" />" << std::endl;
+        user_catalog_file << "</resources>" << std::endl;
+        user_catalog_file.close();
+      }
+    }
+  }
+  if (default_catalog_resource)
+  {
+    std::string default_file("");
+    if (getenv("APPLI") != 0)
     {
-      _path_resources = getenv("HOME");
-      _path_resources += "/";
-      _path_resources += getenv("APPLI");
-      _path_resources += "/CatalogResources.xml";
+      default_file += getenv("HOME");
+      default_file += "/";
+      default_file += getenv("APPLI");
+      default_file += "/CatalogResources.xml";
+      _path_resources.push_back(default_file);
     }
-
-  else
+    else
     {
-      _path_resources = getenv("KERNEL_ROOT_DIR");
-      _path_resources += "/share/salome/resources/kernel/CatalogResources.xml";
+      if(!getenv("KERNEL_ROOT_DIR"))
+        throw ResourcesException("you must define KERNEL_ROOT_DIR environment variable!! -> cannot load a CatalogResources.xml");
+      default_file = getenv("KERNEL_ROOT_DIR");
+      default_file += "/share/salome/resources/kernel/CatalogResources.xml";
+      _path_resources.push_back(default_file);
     }
+  }
 
-  ParseXmlFile();
-#if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "ResourcesManager_cpp constructor end";
-#endif
+  _lasttime=0;
+
+  ParseXmlFiles();
+  RES_MESSAGE("ResourcesManager_cpp constructor end");
 }
 
 //=============================================================================
@@ -101,169 +174,164 @@ ResourcesManager_cpp::ResourcesManager_cpp() throw(ResourcesException)
 
 ResourcesManager_cpp::~ResourcesManager_cpp()
 {
-#if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "ResourcesManager_cpp destructor" << endl;
-#endif
+  RES_MESSAGE("ResourcesManager_cpp destructor");
 }
 
 //=============================================================================
+//! get the list of resource names fitting constraints given by params
 /*!
- *  get the list of name of ressources fitting for the specified module.
- *  If hostname specified, check it is local or known in resources catalog.
- *
- *  Else
- *  - select first machines with corresponding OS (all machines if
- *    parameter OS empty),
- *  - then select the sublist of machines on witch the module is known
- *    (if the result is empty, that probably means that the inventory of
- *    modules is probably not done, so give complete list from previous step)
+ * Steps:
+ * 1: Restrict list with resourceList if defined
+ * 2: If name is defined -> check resource list
+ * 3: If not 2:, if hostname is defined -> check resource list
+ * 4: If not 3:, sort resource with nb_proc, etc...
+ * 5: In all cases remove resource that does not correspond with OS
+ * 6: And remove resource with componentList - if list is empty ignored it...
  */ 
 //=============================================================================
 
 std::vector<std::string> 
-ResourcesManager_cpp::GetFittingResources(const machineParams& params,
-                                     const std::vector<std::string>& componentList) throw(ResourcesException)
+ResourcesManager_cpp::GetFittingResources(const resourceParams& params) throw(ResourcesException)
 {
-  vector <std::string> vec;
+  RES_MESSAGE("[GetFittingResources] on computer " << Kernel_Utils::GetHostname().c_str());
+  RES_MESSAGE("[GetFittingResources] with resource name: " << params.name);
+  RES_MESSAGE("[GetFittingResources] with hostname: "<< params.hostname);
+
+  // Result
+  std::vector<std::string> vec;
+
+  // Parse Again CalatogResource File
+  ParseXmlFiles();
+
+  // Steps:
+  // 1: If name is defined -> check resource list
+  // 2: Restrict list with resourceList if defined
+  // 3: If not 2:, if hostname is defined -> check resource list
+  // 4: If not 3:, sort resource with nb_proc, etc...
+  // 5: In all cases remove resource that does not correspond with OS
+  // 6: And remove resource with componentList - if list is empty ignored it...
+
+  // Step 1
+  if (params.name != "")
+  {
+    RES_MESSAGE("[GetFittingResources] name parameter found !");
+    if (_resourcesList.find(params.name) != _resourcesList.end())
+    {
+      vec.push_back(params.name);
+      return vec;
+    }
+    else
+      RES_MESSAGE("[GetFittingResources] resource name was not found on resource list ! name requested was " << params.name);
+      std::string error("[GetFittingResources] resource name was not found on resource list ! name requested was " + params.name);
+      throw ResourcesException(error);
+  }
 
-  ParseXmlFile();
+  MapOfParserResourcesType local_resourcesList = _resourcesList;
+  // Step 2
+  if (params.resourceList.size() > 0)
+  {
+    RES_MESSAGE("[GetFittingResources] Restricted resource list found !");
+    local_resourcesList.clear();
+    std::vector<std::string>::size_type sz = params.resourceList.size();
 
-  const char *hostname = params.hostname.c_str();
-#if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "GetFittingResources " << hostname << " " << Kernel_Utils::GetHostname().c_str() << endl;
-#endif
+    for (unsigned int i=0; i < sz; i++)
+    {
+      if (_resourcesList.find(params.resourceList[i]) != _resourcesList.end())
+        local_resourcesList[params.resourceList[i]] = _resourcesList[params.resourceList[i]];
+    }
+  }
 
-  if (hostname[0] != '\0'){
+  // Step 3
+  if (params.hostname != "")
+  {
+    RES_MESSAGE("[GetFittingResources] Entering in hostname case !");
 
-    if ( strcmp(hostname, "localhost") == 0 ||
-        strcmp(hostname, Kernel_Utils::GetHostname().c_str()) == 0 )
-      {
-//#if defined(_DEBUG_) || defined(_DEBUG)
-//     cerr << "ResourcesManager_cpp::GetFittingResources : localhost" << endl;
-//#endif
-       vec.push_back(Kernel_Utils::GetHostname().c_str());
-//#if defined(_DEBUG_) || defined(_DEBUG)
-//     cerr << "ResourcesManager_cpp::GetFittingResources : " << vec.size() << endl;
-//#endif
-      }
-       
-    else if (_resourcesList.find(hostname) != _resourcesList.end())
-      {
-       // --- params.hostname is in the list of resources so return it.
-       vec.push_back(hostname);
-      }
-        
-    else if (_resourcesBatchList.find(hostname) != _resourcesBatchList.end())
+    std::string hostname = params.hostname;
+    if (hostname ==  "localhost")
+      hostname = Kernel_Utils::GetHostname().c_str();
+
+    std::map<std::string, ParserResourcesType>::const_iterator iter = _resourcesList.begin();
+    for (; iter != _resourcesList.end(); iter++)
     {
-      // --- params.hostname is in the list of resources so return it.
-      vec.push_back(hostname);
+      if ((*iter).second.HostName == hostname)
+        vec.push_back((*iter).first);
     }
-
-    else
-      {
-       // Cas d'un cluster: nombre de noeuds > 1
-       int cpt=0;
-       for (map<string, ParserResourcesType>::const_iterator iter = _resourcesList.begin(); iter != _resourcesList.end(); iter++){
-         if( (*iter).second.DataForSort._nbOfNodes > 1 ){
-           if( strncmp(hostname,(*iter).first.c_str(),strlen(hostname)) == 0 ){
-             vec.push_back((*iter).first.c_str());
-             cpt++;
-           }
-         }
-       }
-       if(cpt==0){
-         // --- user specified an unknown hostame so notify him.
-#if defined(_DEBUG_) || defined(_DEBUG)
-         cerr << "ResourcesManager_cpp::GetFittingResources : SALOME_Exception" << endl;
-#endif
-         throw ResourcesException("unknown host");
-       }
-      }
   }
-    
-  else{
+  // Step 4
+  else
+  {
     // --- Search for available resources sorted by priority
-    SelectOnlyResourcesWithOS(vec, params.OS.c_str());
-      
-    KeepOnlyResourcesWithModule(vec, componentList);
-       
-    if (vec.size() == 0)
-      SelectOnlyResourcesWithOS(vec, params.OS.c_str());
-    
+    MapOfParserResourcesType_it i = local_resourcesList.begin();
+    for (; i != local_resourcesList.end(); ++i)
+      vec.push_back(i->first);
+
     // --- set wanted parameters
+    ResourceDataToSort::_nbOfProcWanted = params.nb_proc;
     ResourceDataToSort::_nbOfNodesWanted = params.nb_node;
-      
     ResourceDataToSort::_nbOfProcPerNodeWanted = params.nb_proc_per_node;
-       
     ResourceDataToSort::_CPUFreqMHzWanted = params.cpu_clock;
-       
     ResourceDataToSort::_memInMBWanted = params.mem_mb;
-       
     // --- end of set
-       
-    list<ResourceDataToSort> li;
-       
-    for (vector<string>::iterator iter = vec.begin();
-        iter != vec.end();
-        iter++)
-      li.push_back(_resourcesList[(*iter)].DataForSort);
-       
+        
+    // Sort
+    std::list<ResourceDataToSort> li;
+    std::vector<std::string>::iterator iter = vec.begin();
+    for (; iter != vec.end(); iter++)
+      li.push_back(local_resourcesList[(*iter)].DataForSort);
     li.sort();
-       
-    unsigned int i = 0;
-       
-    for (list<ResourceDataToSort>::iterator iter2 = li.begin();
-        iter2 != li.end();
-        iter2++)
-      vec[i++] = (*iter2)._hostName;
+
+    vec.clear();
+    for (std::list<ResourceDataToSort>::iterator iter2 = li.begin(); iter2 != li.end(); iter2++)
+      vec.push_back((*iter2)._Name);
   }
-    
-  return vec;
 
+  // Step 5
+  SelectOnlyResourcesWithOS(vec, params.OS.c_str());
+
+  // Step 6
+  std::vector<std::string> vec_save(vec);
+  KeepOnlyResourcesWithComponent(vec, params.componentList);
+  if (vec.size() == 0)
+    vec = vec_save;
+
+  // Step 7 : Filter on possible usage
+  vector<string> prev_list(vec);
+  vec.clear();
+  for (vector<string>::iterator iter = prev_list.begin() ; iter != prev_list.end() ; iter++)
+  {
+    MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
+    if (it != _resourcesList.end() &&
+        (!params.can_launch_batch_jobs || it->second.can_launch_batch_jobs) &&
+        (!params.can_run_containers || it->second.can_run_containers))
+      vec.push_back(*iter);
+  }
+
+  // End
+  // Send an exception if return list is empty...
+  if (vec.size() == 0)
+  {
+    std::string error("[GetFittingResources] ResourcesManager doesn't find any resource that fits to your parameters");
+    throw ResourcesException(error);
+  }
+
+  return vec;
 }
 
 //=============================================================================
 /*!
- *  add an entry in the ressources catalog  xml file.
- *  Return 0 if OK (KERNEL found in new resources modules) else throw exception
+ *  add an entry in the ressources catalog xml file.
  */ 
 //=============================================================================
 
-int
-ResourcesManager_cpp::
-AddResourceInCatalog(const machineParams& paramsOfNewResources,
-                     const vector<string>& modulesOnNewResources,
-                     const char *alias,
-                     const char *userName,
-                     AccessModeType mode,
-                     AccessProtocolType prot)
-throw(ResourcesException)
+void
+ResourcesManager_cpp::AddResourceInCatalog(const ParserResourcesType & new_resource)
 {
-  vector<string>::const_iterator iter = find(modulesOnNewResources.begin(),
-                                            modulesOnNewResources.end(),
-                                            "KERNEL");
-
-  if (iter != modulesOnNewResources.end())
-    {
-      ParserResourcesType newElt;
-      newElt.DataForSort._hostName = paramsOfNewResources.hostname;
-      newElt.Alias = alias;
-      newElt.Protocol = prot;
-      newElt.Mode = mode;
-      newElt.UserName = userName;
-      newElt.ModulesList = modulesOnNewResources;
-      newElt.OS = paramsOfNewResources.OS;
-      newElt.DataForSort._memInMB = paramsOfNewResources.mem_mb;
-      newElt.DataForSort._CPUFreqMHz = paramsOfNewResources.cpu_clock;
-      newElt.DataForSort._nbOfNodes = paramsOfNewResources.nb_node;
-      newElt.DataForSort._nbOfProcPerNode =
-        paramsOfNewResources.nb_proc_per_node;
-      _resourcesList[newElt.DataForSort._hostName] = newElt;
-      return 0;
-    }
-
-  else
-    throw ResourcesException("KERNEL is not present in this resource");
+  if (new_resource.Name == DEFAULT_RESOURCE_NAME){
+    std::string error("Cannot modify default local resource \"" + DEFAULT_RESOURCE_NAME + "\"");
+    throw ResourcesException(error);
+  }
+  // TODO - Add minimal check
+  _resourcesList[new_resource.Name] = new_resource;
 }
 
 //=============================================================================
@@ -272,9 +340,17 @@ throw(ResourcesException)
  */ 
 //=============================================================================
 
-void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
+void ResourcesManager_cpp::DeleteResourceInCatalog(const char * name)
 {
-  _resourcesList.erase(hostname);
+  if (DEFAULT_RESOURCE_NAME == name){
+    std::string error("Cannot delete default local resource \"" + DEFAULT_RESOURCE_NAME + "\"");
+    throw ResourcesException(error);
+  }
+  MapOfParserResourcesType_it it = _resourcesList.find(name);
+  if (it != _resourcesList.end())
+    _resourcesList.erase(name);
+  else
+    RES_INFOS("You try to delete a resource that does not exist... : " << name);
 }
 
 //=============================================================================
@@ -283,43 +359,51 @@ void ResourcesManager_cpp::DeleteResourceInCatalog(const char *hostname)
  */ 
 //=============================================================================
 
-void ResourcesManager_cpp::WriteInXmlFile()
+void ResourcesManager_cpp::WriteInXmlFile(std::string xml_file)
 {
-  const char* aFilePath = _path_resources.c_str();
-  
+  RES_MESSAGE("WriteInXmlFile : start");
+
+  MapOfParserResourcesType resourceListToSave(_resourcesList);
+  // We do not save default local resource because it is automatically created at startup
+  resourceListToSave.erase(DEFAULT_RESOURCE_NAME);
+  if (resourceListToSave.empty())
+  {
+    RES_MESSAGE("WriteInXmlFile: nothing to do, no resource except default \"" <<
+                DEFAULT_RESOURCE_NAME << "\"");
+    return;
+  }
+
+  if (xml_file == "")
+  {
+    _path_resources_it = _path_resources.begin();
+    xml_file = *_path_resources_it;
+  }
+
+  const char* aFilePath = xml_file.c_str();
   FILE* aFile = fopen(aFilePath, "w");
 
   if (aFile == NULL)
-    {
-#if defined(_DEBUG_) || defined(_DEBUG)
-      cerr << "Error opening file !"  << endl;
-#endif
-      return;
-    }
+  {
+    std::cerr << "Error opening file in WriteInXmlFile : " << xml_file << std::endl;
+    return;
+  }
   
   xmlDocPtr aDoc = xmlNewDoc(BAD_CAST "1.0");
   xmlNewDocComment(aDoc, BAD_CAST "ResourcesCatalog");
 
   SALOME_ResourcesCatalog_Handler* handler =
-    new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
+    new SALOME_ResourcesCatalog_Handler(resourceListToSave);
   handler->PrepareDocToXmlFile(aDoc);
   delete handler;
 
-#if defined(_DEBUG_) || defined(_DEBUG)
-  int isOk = xmlSaveFile(aFilePath, aDoc);
-  if (!isOk) cerr << "Error while XML file saving." << endl;
-#else
-  xmlSaveFile(aFilePath, aDoc);
-#endif
+  int isOk = xmlSaveFormatFile(aFilePath, aDoc, 1);
+  if (!isOk) 
+     std::cerr << "Error while XML file saving : " << xml_file << std::endl;
   
   // Free the document
   xmlFreeDoc(aDoc);
-
   fclose(aFile);
-  
-#if defined(_DEBUG_) || defined(_DEBUG)
-  cerr << "WRITING DONE!" << endl;
-#endif
+  RES_MESSAGE("WriteInXmlFile : WRITING DONE!");
 }
 
 //=============================================================================
@@ -328,37 +412,88 @@ void ResourcesManager_cpp::WriteInXmlFile()
  */ 
 //=============================================================================
 
-const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
+const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFiles()
 {
-  SALOME_ResourcesCatalog_Handler* handler =
-    new SALOME_ResourcesCatalog_Handler(_resourcesList, _resourcesBatchList);
+  // Parse file only if its modification time is greater than lasttime (last registered modification time)
+  bool to_parse = false;
+  for(_path_resources_it = _path_resources.begin(); _path_resources_it != _path_resources.end(); ++_path_resources_it)
+  {
+    struct stat statinfo;
+    int result = stat((*_path_resources_it).c_str(), &statinfo);
+    if (result < 0)
+    {
+      RES_MESSAGE("Resource file " << *_path_resources_it << " does not exist");
+      return _resourcesList;
+    }
 
-  const char* aFilePath = _path_resources.c_str();
-  FILE* aFile = fopen(aFilePath, "r");
-  
-  if (aFile != NULL)
+    if(statinfo.st_mtime > _lasttime)
     {
-      xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
-      
-      if (aDoc != NULL)
-       handler->ProcessXmlDocument(aDoc);
-#if defined(_DEBUG_) || defined(_DEBUG)
+      to_parse = true;
+      _lasttime = statinfo.st_mtime;
+    }
+  }
+
+  if (to_parse)
+  {
+    _resourcesList.clear();
+    AddDefaultResourceInCatalog();
+    // On parse tous les fichiers
+    for(_path_resources_it = _path_resources.begin(); _path_resources_it != _path_resources.end(); ++_path_resources_it)
+    {
+      MapOfParserResourcesType _resourcesList_tmp;
+      MapOfParserResourcesType _resourcesBatchList_tmp;
+      SALOME_ResourcesCatalog_Handler *handler( new SALOME_ResourcesCatalog_Handler(_resourcesList_tmp) );
+      const char *aFilePath( (*_path_resources_it).c_str() );
+      FILE* aFile = fopen(aFilePath, "r");
+
+      if (aFile != NULL)
+      {
+        xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
+        if (aDoc != NULL)
+        {
+          handler->ProcessXmlDocument(aDoc);
+
+          // adding new resources to the file
+          for (MapOfParserResourcesType_it i = _resourcesList_tmp.begin(); i != _resourcesList_tmp.end(); ++i)
+          {
+            MapOfParserResourcesType_it j = _resourcesList.find(i->first);
+            if (i->second.HostName == DEFAULT_RESOURCE_NAME || i->second.HostName == Kernel_Utils::GetHostname())
+            {
+              MapOfParserResourcesType_it it0(_resourcesList.find(DEFAULT_RESOURCE_NAME));
+              if(it0!=_resourcesList.end())
+                {
+                  ParserResourcesType& localhostElt((*it0).second);
+                  localhostElt.DataForSort._nbOfNodes=(*i).second.DataForSort._nbOfNodes;
+                  localhostElt.DataForSort._nbOfProcPerNode=(*i).second.DataForSort._nbOfProcPerNode;
+                  localhostElt.DataForSort._CPUFreqMHz=(*i).second.DataForSort._CPUFreqMHz;
+                  localhostElt.DataForSort._memInMB=(*i).second.DataForSort._memInMB;
+                }
+              RES_MESSAGE("Resource " << i->first << " is not added because it is the same "
+                          "machine as default local resource \"" << DEFAULT_RESOURCE_NAME << "\"");
+            }
+            else if (j != _resourcesList.end())
+            {
+              cerr << "ParseXmlFiles Warning, two resources with the same name were found, "
+                      "taking the first declaration : " << i->first << endl;
+            }
+            else
+            {
+              _resourcesList[i->first] = i->second;
+            }
+          }
+        }
+        else
+          std::cerr << "ResourcesManager_cpp: could not parse file " << aFilePath << std::endl;
+        // Free the document
+        xmlFreeDoc(aDoc);
+        fclose(aFile);
+      }
       else
-       cerr << "ResourcesManager_cpp: could not parse file "<< aFilePath << endl;
-#endif
-      
-      // Free the document
-      xmlFreeDoc(aDoc);
+        std::cerr << "ResourcesManager_cpp: file " << aFilePath << " is not readable." << std::endl;
 
-      fclose(aFile);
+      delete handler;
     }
-#if defined(_DEBUG_) || defined(_DEBUG)
-  else
-    cerr << "ResourcesManager_cpp: file "<<aFilePath<<" is not readable." << endl;
-#endif
-  
-  delete handler;
-
+  }
   return _resourcesList;
 }
 
@@ -369,108 +504,120 @@ const MapOfParserResourcesType& ResourcesManager_cpp::ParseXmlFile()
 //=============================================================================
 
 const MapOfParserResourcesType& ResourcesManager_cpp::GetList() const
-  {
-    return _resourcesList;
-  }
-
-
-//=============================================================================
-/*!
- *  dynamically obtains the first machines
- */ 
-//=============================================================================
-
-string ResourcesManager_cpp::FindFirst(const std::vector<std::string>& listOfMachines)
 {
-  return _dynamicResourcesSelecter.FindFirst(listOfMachines);
-}
-
-//=============================================================================
-/*!
- *  dynamically obtains the best machines
- */ 
-//=============================================================================
-
-string ResourcesManager_cpp::FindNext(const std::vector<std::string>& listOfMachines)
-{
-  return _dynamicResourcesSelecter.FindNext(listOfMachines,_resourcesList);
+  return _resourcesList;
 }
-//=============================================================================
-/*!
- *  dynamically obtains the best machines
- */ 
-//=============================================================================
 
-string ResourcesManager_cpp::FindBest(const std::vector<std::string>& listOfMachines)
+//! threadsafe
+std::string ResourcesManager_cpp::Find(const std::string& policy, const std::vector<std::string>& listOfResources) const
 {
-  return _dynamicResourcesSelecter.FindBest(listOfMachines);
+  std::map<std::string , LoadRateManager*>::const_iterator it(_resourceManagerMap.find(policy));
+  if(it==_resourceManagerMap.end())
+       {
+         it=_resourceManagerMap.find("");
+         return ((*it).second)->Find(listOfResources, _resourcesList);
+       }
+  return ((*it).second)->Find(listOfResources, _resourcesList);
 }
 
 //=============================================================================
 /*!
- *  Gives a sublist of machines with matching OS.
- *  If parameter OS is empty, gives the complete list of machines
+ *  Gives a sublist of resources with matching OS.
+ *  If parameter OS is empty, gives the complete list of resources
  */ 
 //=============================================================================
-
-// Warning need an updated parsed list : _resourcesList
-void ResourcesManager_cpp::SelectOnlyResourcesWithOS( vector<string>& hosts,  const char *OS) const
-throw(ResourcesException)
+void 
+ResourcesManager_cpp::SelectOnlyResourcesWithOS(std::vector<std::string>& resources, std::string OS)
 {
-  string base(OS);
-
-  for (map<string, ParserResourcesType>::const_iterator iter =
-         _resourcesList.begin();
-       iter != _resourcesList.end();
-       iter++)
+  if (OS != "")
+  {
+    // a computer list is given : take only resources with OS on those computers
+    std::vector<std::string> vec_tmp = resources;
+    resources.clear();
+    std::vector<std::string>::iterator iter = vec_tmp.begin();
+    for (; iter != vec_tmp.end(); iter++)
     {
-      if ( (*iter).second.OS == base || base.size() == 0)
-        hosts.push_back((*iter).first);
+      MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
+      if(it != _resourcesList.end())
+        if ( (*it).second.OS == OS)
+          resources.push_back(*iter);
     }
+  }
 }
 
 
 //=============================================================================
 /*!
- *  Gives a sublist of machines on which the module is known.
+ *  Gives a sublist of machines on which the component is known.
  */ 
 //=============================================================================
-
-//Warning need an updated parsed list : _resourcesList
-void ResourcesManager_cpp::KeepOnlyResourcesWithModule( vector<string>& hosts, const vector<string>& componentList) const
-throw(ResourcesException)
+void 
+ResourcesManager_cpp::KeepOnlyResourcesWithComponent(std::vector<std::string>& resources, 
+                                                     const std::vector<std::string>& componentList)
 {
-  for (vector<string>::iterator iter = hosts.begin(); iter != hosts.end();)
+  std::vector<std::string> kept_resources;
+
+  std::vector<std::string>::iterator iter = resources.begin();
+  for (; iter != resources.end(); iter++)
+  {
+    const std::vector<std::string>& mapOfComponentsOfCurrentHost = _resourcesList[*iter].ComponentsList;
+
+    bool erasedHost = false;
+    if( mapOfComponentsOfCurrentHost.size() > 0 )
     {
-      MapOfParserResourcesType::const_iterator it = _resourcesList.find(*iter);
-      const vector<string>& mapOfModulesOfCurrentHost = (((*it).second).ModulesList);
-
-      bool erasedHost = false;
-      if( mapOfModulesOfCurrentHost.size() > 0 ){
-       for(unsigned int i=0;i<componentList.size();i++){
-          const char* compoi = componentList[i].c_str();
-         vector<string>::const_iterator itt = find(mapOfModulesOfCurrentHost.begin(),
-                                             mapOfModulesOfCurrentHost.end(),
-                                             compoi);
-//                                           componentList[i]);
-         if (itt == mapOfModulesOfCurrentHost.end()){
-           erasedHost = true;
-           break;
-         }
-       }
+      for(unsigned int i=0; i<componentList.size(); i++)
+      {
+        std::vector<std::string>::const_iterator itt = find(mapOfComponentsOfCurrentHost.begin(),
+                                                            mapOfComponentsOfCurrentHost.end(),
+                                                            componentList[i]);
+        if (itt == mapOfComponentsOfCurrentHost.end())
+        {
+          erasedHost = true;
+          break;
+        }
       }
-      if(erasedHost)
-        hosts.erase(iter);
-      else
-        iter++;
     }
+    if(!erasedHost)
+      kept_resources.push_back(*iter);
+  }
+  resources=kept_resources;
 }
 
-
-ParserResourcesType ResourcesManager_cpp::GetResourcesList(const std::string& machine)
+//! thread safe
+ParserResourcesType ResourcesManager_cpp::GetResourcesDescr(const std::string & name) const
 {
-  if (_resourcesList.find(machine) != _resourcesList.end())
-    return _resourcesList[machine];
+  MapOfParserResourcesType::const_iterator it(_resourcesList.find(name));
+  if (it != _resourcesList.end())
+    return (*it).second;
   else
-    return _resourcesBatchList[machine];
+  {
+    std::string error("[GetResourcesDescr] Resource does not exist: ");
+    error += name;
+    throw ResourcesException(error);
+  }
+}
+
+void ResourcesManager_cpp::AddDefaultResourceInCatalog()
+{
+  ParserResourcesType resource;
+  resource.Name = DEFAULT_RESOURCE_NAME;
+  // We can't use "localhost" for parameter hostname because the containers are registered in the
+  // naming service with the real hostname, not "localhost"
+  resource.HostName = Kernel_Utils::GetHostname();
+  resource.DataForSort._Name = DEFAULT_RESOURCE_NAME;
+  resource.Protocol = sh;
+  resource.Batch = none;
+  if (getenv("HOME") != NULL && getenv("APPLI") != NULL)
+  {
+    resource.AppliPath = string(getenv("HOME")) + "/" + getenv("APPLI");
+  }
+  string tmpdir = "/tmp";
+  if (getenv("TMPDIR") != NULL)
+    tmpdir = getenv("TMPDIR");
+  resource.working_directory = tmpdir + "/salome_localres_workdir";
+  if (getenv("USER") != NULL)
+    resource.working_directory += string("_") + getenv("USER");
+  resource.can_launch_batch_jobs = true;
+  resource.can_run_containers = true;
+  _resourcesList[resource.Name] = resource;
 }