]> SALOME platform Git repositories - modules/kernel.git/blob - src/ResourcesManager/SALOME_ResourcesCatalog_Handler.cxx
Salome HOME
bos #42937: [CEA 41954] Integration of UB24.04 patches
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Handler.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl)
24 //  File   : SALOME_ResourcesCatalog_Handler.cxx
25 //  Author : Estelle Deville
26 //  Module : SALOME
27 //$Header$
28 //
29 #include "SALOME_ResourcesCatalog_Handler.hxx"
30 #include "Basics_Utils.hxx"
31 #include "utilities.h"
32 #include <iostream>
33 #include <sstream>
34 #include <map>
35
36 using namespace std;
37
38 //=============================================================================
39 /*!
40  *  Constructor
41  *  \param listOfResources: map of ParserResourcesType to fill when parsing
42  */ 
43 //=============================================================================
44
45 SALOME_ResourcesCatalog_Handler::
46 SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& resources_list): _resources_list(resources_list)
47 {
48   //XML tags initialisation
49   test_machine = "machine";
50   test_cluster = "cluster";
51   test_name = "name";
52   test_hostname = "hostname";
53   test_type = "type";
54   test_protocol = "protocol";
55   test_cluster_internal_protocol = "iprotocol";
56   test_mode = "mode";
57   test_batch = "batch";
58   test_mpi = "mpi";
59   test_user_name = "userName";
60   test_appli_path = "appliPath";
61   test_modules = "modules";
62   test_module_name = "moduleName";
63   test_components = "component";
64   test_component_name = "name";
65   test_os = "OS";
66   test_mem_in_mb = "memInMB";
67   test_cpu_freq_mhz = "CPUFreqMHz";
68   test_nb_of_nodes = "nbOfNodes";
69   test_nb_of_proc = "nbOfProc";
70   test_nb_of_proc_per_node = "nbOfProcPerNode";
71   test_batch_queue = "batchQueue";
72   test_user_commands = "userCommands";
73   test_use = "use";
74   test_members = "members";
75   test_is_cluster_head = "isClusterHead";
76   test_working_directory = "workingDirectory";
77   test_can_launch_batch_jobs = "canLaunchBatchJobs";
78   test_can_run_containers = "canRunContainers";
79 }
80
81 //=============================================================================
82 /*!
83  *  Destructor
84  */ 
85 //=============================================================================
86
87 SALOME_ResourcesCatalog_Handler::~SALOME_ResourcesCatalog_Handler()
88 {
89   //  cout << "SALOME_ResourcesCatalog_Handler destruction") << endl;
90 }
91
92 //=============================================================================
93 /*!
94  *  Retrieves DS after the file parse.
95  */ 
96 //=============================================================================
97
98 const MapOfParserResourcesType&
99 SALOME_ResourcesCatalog_Handler::GetResourcesAfterParsing() const
100 {
101   return _resources_list;
102 }
103
104 //=============================================================================
105 /*!
106  *  Processes XML document and fills the list of resources
107  */ 
108 //=============================================================================
109
110 void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc)
111 {
112   // Empty private elements
113   _resources_list.clear();
114
115   // Get the document root node
116   xmlNodePtr aCurNode = xmlDocGetRootElement(theDoc);
117
118   aCurNode = aCurNode->xmlChildrenNode;
119  
120   // Processing the document nodes
121   while(aCurNode != NULL)
122   {
123     // Declaration of a single machine or a frontal node for a cluster managed by a batch manager
124     if (!xmlStrcmp(aCurNode->name,(const xmlChar*)test_machine))
125     {
126       ParserResourcesType resource;
127       bool Ok = ProcessMachine(aCurNode, resource);
128       if (Ok)
129       {
130         // Adding a resource
131         if(resource.HostName == "localhost")
132         {
133           resource.HostName = Kernel_Utils::GetHostname();
134         }
135         std::map<std::string, ParserResourcesType>::const_iterator iter = _resources_list.find(resource.Name);
136         if (iter != _resources_list.end())
137           RES_INFOS("Warning resource " << resource.Name << " already added, keep last resource found !");
138         _resources_list[resource.Name] = resource;
139       }
140     }
141     // Declaration of a cluster
142     // Here, a cluster is NOT the frontal node of a cluster managed by a batch manager (classical
143     // usage of a cluster). It is a group of machines intended to be used for a parallel container.
144     // The methods ProcessCluster and ProcessMember are only used in the context of parallel
145     // containers. They are not used in classical Salome usage scenarios.
146     if (!xmlStrcmp(aCurNode->name,(const xmlChar*)test_cluster))
147     {
148       ParserResourcesType resource;
149       if(ProcessCluster(aCurNode, resource))
150       {
151         std::map<std::string, ParserResourcesType>::const_iterator iter = _resources_list.find(resource.Name);
152         if (iter != _resources_list.end())
153           RES_INFOS("Warning resource " << resource.Name << " already added, keep last resource found !");
154         _resources_list[resource.Name] = resource;
155       }
156     }
157     aCurNode = aCurNode->next;
158   }
159   DEBUG_MESSAGE( "************ Resources in memory ************");
160   for (std::map<std::string, ParserResourcesType>::const_iterator iter = _resources_list.begin(); iter != _resources_list.end(); iter++)
161   {
162     DEBUG_MESSAGE( "Resource \"" << (*iter).first << "\" -> " << (*iter).second.dump(' '));
163   }
164   DEBUG_MESSAGE( "************ Resources in memory ************");
165 }
166
167 bool
168 SALOME_ResourcesCatalog_Handler::ProcessCluster(xmlNodePtr cluster_descr, ParserResourcesType & resource)
169 {
170   // Ajout d'un cluster
171   // hostname, use et nbOfProc sont obligatoires
172   if (xmlHasProp(cluster_descr, (const xmlChar*)test_hostname))
173   {
174     xmlChar* hostname = xmlGetProp(cluster_descr, (const xmlChar*)test_hostname);
175     resource.HostName = (const char*)hostname;
176     xmlFree(hostname);
177   }
178   else
179   {
180     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a hostname" );
181     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" );
182     return false;
183   }
184
185   if (xmlHasProp(cluster_descr, (const xmlChar*)test_name))
186   {
187     xmlChar* name = xmlGetProp(cluster_descr, (const xmlChar*)test_name);
188     resource.Name = (const char*)name;
189     resource.DataForSort._Name = (const char*)name;
190     xmlFree(name);
191   }
192   else
193   {
194     resource.Name = resource.HostName;
195     resource.DataForSort._Name = resource.HostName;
196     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! No Name found use Hostname for resource: " << resource.Name );
197   }
198
199   if (xmlHasProp(cluster_descr, (const xmlChar*)test_use))
200   {
201     xmlChar* use = xmlGetProp(cluster_descr, (const xmlChar*)test_use);
202     resource.use = (const char*)use;
203     xmlFree(use);
204   }
205   else
206   {
207     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a use" );
208     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" );
209     return false;
210   }
211
212   if (xmlHasProp(cluster_descr, (const xmlChar*)test_nb_of_proc))
213   {
214     xmlChar* nb_of_proc = xmlGetProp(cluster_descr, (const xmlChar*)test_nb_of_proc);
215     resource.nbOfProc = atoi((const char*)nb_of_proc);
216     xmlFree(nb_of_proc);
217   }
218   else
219   {
220     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a nbOfProc" );
221     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" );
222     return false;
223   }
224
225   if (xmlHasProp(cluster_descr, (const xmlChar*)test_mpi))
226   {
227     xmlChar* mpi = xmlGetProp(cluster_descr, (const xmlChar*)test_mpi);
228     std::string anMpi = (const char*)mpi;
229     xmlFree(mpi);
230     resource.setMpiImplTypeStr(anMpi);
231   }
232
233   // Parsing des membres du cluster 
234   xmlNodePtr aCurSubNode = cluster_descr->xmlChildrenNode;
235   while(aCurSubNode != NULL)
236   {
237     if (!xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_members))
238     {
239        xmlNodePtr members = aCurSubNode->xmlChildrenNode;
240        while (members != NULL)
241        {
242          // Process members
243          if (!xmlStrcmp(members->name, (const xmlChar*)test_machine))
244          {
245            ParserResourcesType new_member;
246            if (ProcessMember(members, new_member))
247              resource.ClusterMembersList.push_back(new_member);
248          }
249          members = members->next;
250        }
251     }
252     aCurSubNode = aCurSubNode->next;
253   }
254
255   // Test: Il faut au moins un membre pour que le cluster soit correct !
256   if (resource.ClusterMembersList.empty())
257   {
258     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a member" );
259     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" );
260     return false;
261   }
262   return true;
263 }
264
265 bool
266 SALOME_ResourcesCatalog_Handler::ProcessMember(xmlNodePtr member_descr, ParserResourcesType & resource)
267 {
268   if (xmlHasProp(member_descr, (const xmlChar*)test_hostname))
269   {
270     xmlChar* hostname = xmlGetProp(member_descr, (const xmlChar*)test_hostname);
271     resource.HostName = (const char*)hostname;
272     xmlFree(hostname);
273   }
274   else
275   {
276     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a hostname" );
277     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
278     return false;
279   }
280
281   if (xmlHasProp(member_descr, (const xmlChar*)test_protocol))
282   {
283     xmlChar* protocol= xmlGetProp(member_descr, (const xmlChar*)test_protocol);
284     try
285     {
286       resource.setAccessProtocolTypeStr((const char *)protocol);
287     }
288     catch (const ResourcesException & )
289     {
290       MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine with a bad protocol" );
291       MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
292       return false;
293     }
294     xmlFree(protocol);
295   }
296   else
297   {
298     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a protocol" );
299     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
300     return false;
301   }
302
303   if (xmlHasProp(member_descr, (const xmlChar*)test_cluster_internal_protocol))
304   {
305     xmlChar* iprotocol= xmlGetProp(member_descr, (const xmlChar*)test_cluster_internal_protocol);
306     try
307     {
308       resource.setClusterInternalProtocolStr((const char *)iprotocol);
309     }
310     catch (const ResourcesException &)
311     {
312       MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine with a bad protocol" );
313       MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
314       return false;
315     }
316     xmlFree(iprotocol);
317   }
318   else
319   {
320     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a protocol" );
321     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
322     return false;
323   }
324
325   if (xmlHasProp(member_descr, (const xmlChar*)test_user_name))
326   {
327     xmlChar* user_name= xmlGetProp(member_descr, (const xmlChar*)test_user_name);
328     resource.UserName = (const char*)user_name;
329     xmlFree(user_name);
330   }
331   else
332   {
333     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a user name" );
334     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
335     return false;
336   }
337
338   if (xmlHasProp(member_descr, (const xmlChar*)test_nb_of_nodes))
339   {
340     xmlChar* nb_of_nodes = xmlGetProp(member_descr, (const xmlChar*)test_nb_of_nodes);
341     resource.DataForSort._nbOfNodes = atoi((const char*)nb_of_nodes);
342     xmlFree(nb_of_nodes);
343   }
344   else
345   {
346     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a nbOfNodes" );
347     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
348     return false;
349   }
350
351   if (xmlHasProp(member_descr, (const xmlChar*)test_nb_of_proc_per_node))
352   {
353     xmlChar* nb_of_proc_per_node = xmlGetProp(member_descr, (const xmlChar*)test_nb_of_proc_per_node);
354     resource.DataForSort._nbOfProcPerNode = atoi((const char*)nb_of_proc_per_node);
355     xmlFree(nb_of_proc_per_node);
356   }
357   else
358   {
359     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a nbOfProcPerNode" );
360     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
361     return false;
362   }
363
364   if (xmlHasProp(member_descr, (const xmlChar*)test_appli_path))
365   {
366     xmlChar* appli_path = xmlGetProp(member_descr, (const xmlChar*)test_appli_path);
367     resource.AppliPath = (const char*)appli_path;
368     xmlFree(appli_path);
369   }
370   else
371   {
372     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a AppliPath" );
373     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" );
374     return false;
375   }
376   return true;
377 }
378
379 bool
380 SALOME_ResourcesCatalog_Handler::ProcessMachine(xmlNodePtr machine_descr, ParserResourcesType & resource)
381 {
382   if (xmlHasProp(machine_descr, (const xmlChar*)test_hostname))
383   {
384     xmlChar* hostname = xmlGetProp(machine_descr, (const xmlChar*)test_hostname);
385     resource.HostName = (const char*)hostname;
386     xmlFree(hostname);
387   }
388   else
389   {
390     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMachine : Warning found a machine without a hostname" );
391     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMachine : Warning this machine will not be added" );
392     return false;
393   }
394
395   if (xmlHasProp(machine_descr, (const xmlChar*)test_name))
396   {
397     xmlChar* name = xmlGetProp(machine_descr, (const xmlChar*)test_name);
398     resource.Name = (const char*)name;
399     resource.DataForSort._Name = (const char*)name;
400     xmlFree(name);
401   }
402   else
403   {
404     resource.Name = resource.HostName;
405     resource.DataForSort._Name = resource.HostName;
406     MESSAGE( "SALOME_ResourcesCatalog_Handler::ProcessMachine : !!! Warning !!! No Name found use Hostname for resource: " << resource.Name );
407   }
408
409   // This block is for compatibility with files created in Salome 6.
410   // It can safely be removed in Salome 8.
411   if (xmlHasProp(machine_descr, (const xmlChar*)test_mode))
412   {
413     MESSAGE( "Warning: parameter \"" << test_mode << "\" defined for resource \"" <<
414             resource.Name << "\" is deprecated. It will be replaced when your resource " <<
415             "file is saved." );
416     xmlChar* mode=xmlGetProp(machine_descr, (const xmlChar*)test_mode);
417     switch ( mode[0] )
418     {
419       case 'i':
420         resource.can_run_containers = true;
421         break;
422       case 'b':
423         resource.can_launch_batch_jobs = true;
424         break;
425       default:
426         break;
427     }
428     xmlFree(mode);
429   }
430
431   if (xmlHasProp(machine_descr, (const xmlChar*)test_is_cluster_head))
432   {
433     MESSAGE( "Warning: parameter \"" << test_is_cluster_head << "\" defined for resource \"" <<
434             resource.Name << "\" is deprecated. It will be replaced when your resource " <<
435             "file is saved." );
436     xmlChar* is_cluster_head = xmlGetProp(machine_descr, (const xmlChar*)test_is_cluster_head);
437     std::string str_ich = (const char*)is_cluster_head;
438     if (str_ich == "true")
439     {
440       resource.type = cluster;
441       resource.can_launch_batch_jobs = true;
442       resource.can_run_containers = false;
443     }
444     else
445     {
446       resource.type = single_machine;
447       resource.can_run_containers = true;
448     }
449     xmlFree(is_cluster_head);
450   }
451   // End of compatibility block
452
453   if (xmlHasProp(machine_descr, (const xmlChar*)test_type))
454   {
455     xmlChar* type = xmlGetProp(machine_descr, (const xmlChar*)test_type);
456     try
457     {
458       resource.setResourceTypeStr((const char*)type);
459     }
460     catch (const ResourcesException &)
461     {
462       INFO_MESSAGE( "Warning, invalid type \"" << (const char*)type << "\" for resource \"" <<
463               resource.Name << "\", using default value \"" << resource.getResourceTypeStr() <<
464               "\"" ) ;
465     }
466     xmlFree(type);
467   }
468   else
469   {
470       INFO_MESSAGE( "Warning, no type found for resource \"" << resource.Name <<
471             "\", using default value \"" << resource.getResourceTypeStr() << "\"");
472   }
473
474   if (xmlHasProp(machine_descr, (const xmlChar*)test_batch_queue))
475   {
476     xmlChar* batch_queue = xmlGetProp(machine_descr, (const xmlChar*)test_batch_queue);
477     resource.batchQueue = (const char*)batch_queue;
478     xmlFree(batch_queue);
479   }
480
481   if (xmlHasProp(machine_descr, (const xmlChar*)test_user_commands))
482   {
483     xmlChar* user_commands= xmlGetProp(machine_descr, (const xmlChar*)test_user_commands);
484     resource.userCommands = (const char*)user_commands;
485     xmlFree(user_commands);
486   }
487
488   if (xmlHasProp(machine_descr, (const xmlChar*)test_protocol))
489   {
490     xmlChar* protocol= xmlGetProp(machine_descr, (const xmlChar*)test_protocol);
491     try
492     {
493       resource.setAccessProtocolTypeStr((const char *)protocol);
494     }
495     catch (const ResourcesException &)
496     {
497       MESSAGE( "Warning, invalid protocol \"" << (const char*)protocol << "\" for resource \"" <<
498               resource.Name << "\", using default value \"" <<
499               resource.getAccessProtocolTypeStr() << "\"" );
500     }
501     xmlFree(protocol);
502   }
503
504   if (xmlHasProp(machine_descr, (const xmlChar*)test_cluster_internal_protocol))
505   {
506     xmlChar* iprotocol= xmlGetProp(machine_descr, (const xmlChar*)test_cluster_internal_protocol);
507     try
508     {
509       resource.setClusterInternalProtocolStr((const char *)iprotocol);
510     }
511     catch (const ResourcesException &)
512     {
513       MESSAGE( "Warning, invalid internal protocol \"" << (const char*)iprotocol <<
514               "\" for resource \"" << resource.Name << "\", using default value \"" <<
515               resource.getClusterInternalProtocolStr() << "\"" );
516     }
517     xmlFree(iprotocol);
518   }
519   else
520     resource.ClusterInternalProtocol = resource.Protocol;
521
522   if (xmlHasProp(machine_descr, (const xmlChar*)test_batch))
523   {
524     xmlChar* batch = xmlGetProp(machine_descr, (const xmlChar*)test_batch);
525     try
526     {
527       resource.setBatchTypeStr((const char *)batch);
528     }
529     catch (const ResourcesException &)
530     {
531       MESSAGE( "Warning, invalid batch manager \"" << (const char*)batch <<
532               "\" for resource \"" << resource.Name << "\", using default value \"" <<
533               resource.getBatchTypeStr() << "\"" );
534     }
535     xmlFree(batch);
536   }
537
538   if (xmlHasProp(machine_descr, (const xmlChar*)test_mpi))
539   {
540     xmlChar* mpi = xmlGetProp(machine_descr, (const xmlChar*)test_mpi);
541     try
542     {
543       resource.setMpiImplTypeStr((const char *)mpi);
544     }
545     catch (const ResourcesException &)
546     {
547       MESSAGE( "Warning, invalid MPI implementation \"" << (const char*)mpi <<
548               "\" for resource \"" << resource.Name << "\", using default value \"" <<
549               resource.getMpiImplTypeStr() << "\"" );
550     }
551     xmlFree(mpi);
552   }
553
554   if (xmlHasProp(machine_descr, (const xmlChar*)test_user_name))
555   {
556     xmlChar* user_name= xmlGetProp(machine_descr, (const xmlChar*)test_user_name);
557     resource.UserName = (const char*)user_name;
558     xmlFree(user_name);
559   }
560
561   if (xmlHasProp(machine_descr, (const xmlChar*)test_appli_path))
562   {
563     xmlChar* appli_path = xmlGetProp(machine_descr, (const xmlChar*)test_appli_path);
564     resource.AppliPath = (const char*)appli_path;
565     xmlFree(appli_path);
566   }
567
568   if (xmlHasProp(machine_descr, (const xmlChar*)test_os))
569   {
570     xmlChar* os = xmlGetProp(machine_descr, (const xmlChar*)test_os);
571     resource.OS = (const char*)os;
572     xmlFree(os);
573   }
574
575   if (xmlHasProp(machine_descr, (const xmlChar*)test_mem_in_mb))
576   {
577     xmlChar* mem_in_mb = xmlGetProp(machine_descr, (const xmlChar*)test_mem_in_mb);
578     resource.DataForSort._memInMB = atoi((const char*)mem_in_mb);
579     xmlFree(mem_in_mb);
580   }
581
582   if (xmlHasProp(machine_descr, (const xmlChar*)test_cpu_freq_mhz))
583   {
584     xmlChar* cpu_freq_mhz = xmlGetProp(machine_descr, (const xmlChar*)test_cpu_freq_mhz);
585     resource.DataForSort._CPUFreqMHz = atoi((const char*)cpu_freq_mhz);
586     xmlFree(cpu_freq_mhz);
587   }
588
589   if (xmlHasProp(machine_descr, (const xmlChar*)test_nb_of_nodes))
590   {
591     xmlChar* nb_of_nodes = xmlGetProp(machine_descr, (const xmlChar*)test_nb_of_nodes);
592     resource.DataForSort._nbOfNodes = atoi((const char*)nb_of_nodes);
593     xmlFree(nb_of_nodes);
594   }
595
596   if (xmlHasProp(machine_descr, (const xmlChar*)test_nb_of_proc_per_node))
597   {
598     xmlChar* nb_of_proc_per_node = xmlGetProp(machine_descr, (const xmlChar*)test_nb_of_proc_per_node);
599     resource.DataForSort._nbOfProcPerNode = atoi((const char*)nb_of_proc_per_node);
600     xmlFree(nb_of_proc_per_node);
601   }
602
603   if (xmlHasProp(machine_descr, (const xmlChar*)test_can_launch_batch_jobs))
604   {
605     xmlChar* can_launch_batch_jobs = xmlGetProp(machine_descr, (const xmlChar*)test_can_launch_batch_jobs);
606     try
607     {
608       resource.setCanLaunchBatchJobsStr((const char *)can_launch_batch_jobs);
609     }
610     catch (const ResourcesException &)
611     {
612       MESSAGE( "Warning, invalid can_launch_batch_jobs parameter value \"" <<
613               (const char*)can_launch_batch_jobs << "\" for resource \"" << resource.Name <<
614               "\", using default value \"" << resource.getCanLaunchBatchJobsStr() << "\"" );
615     }
616     xmlFree(can_launch_batch_jobs);
617   }
618
619   if (xmlHasProp(machine_descr, (const xmlChar*)test_can_run_containers))
620   {
621     xmlChar* can_run_containers = xmlGetProp(machine_descr, (const xmlChar*)test_can_run_containers);
622     try
623     {
624       resource.setCanRunContainersStr((const char *)can_run_containers);
625     }
626     catch (const ResourcesException &)
627     {
628       MESSAGE( "Warning, invalid can_run_containers parameter value \"" <<
629               (const char*)can_run_containers << "\" for resource \"" << resource.Name <<
630               "\", using default value \"" << resource.getCanRunContainersStr() << "\"" );
631     }
632     xmlFree(can_run_containers);
633   }
634
635   if (xmlHasProp(machine_descr, (const xmlChar*)test_working_directory))
636   {
637     xmlChar* working_directory = xmlGetProp(machine_descr, (const xmlChar*)test_working_directory);
638     resource.working_directory = (const char*)working_directory;
639     xmlFree(working_directory);
640   }
641
642   // Process children nodes
643   xmlNodePtr aCurSubNode = machine_descr->xmlChildrenNode;
644   while(aCurSubNode != NULL)
645   {
646     // Process components
647     if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_components) )
648     {
649       //If a component is given, it is in a module with the same name
650       //except if the module name is given
651       if (xmlHasProp(aCurSubNode, (const xmlChar*)test_component_name)) 
652       {
653         xmlChar* component_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_component_name);
654         std::string aComponentName = (const char*)component_name;
655         resource.ComponentsList.push_back(aComponentName);
656         if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
657         {
658           xmlChar* module_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
659           std::string aModuleName = (const char*)module_name;
660           resource.ModulesList.push_back(aModuleName);
661           xmlFree(module_name);
662         }
663         else
664           resource.ModulesList.push_back(aComponentName);
665         xmlFree(component_name);
666       }
667     }
668     // Process modules
669     else if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_modules) )
670     {
671       // If a module is given, we create an entry in componentsList and modulesList
672       // with the same name (module == component)
673       if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
674       {
675         xmlChar* component_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
676         std::string aComponentName = (const char*)component_name;
677         resource.ComponentsList.push_back(aComponentName);
678         resource.ModulesList.push_back(aComponentName);
679         xmlFree(component_name);
680       }
681     }
682     aCurSubNode = aCurSubNode->next;
683   }
684   return true;
685 }
686
687 //=============================================================================
688 /*!
689  *  Fill the document tree in xml file, used to write in an xml file.
690  *  \param theDoc document to fill.
691  */ 
692 //=============================================================================
693
694 void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc)
695 {
696   // Node pointers
697   xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;
698
699   root_node = xmlNewNode(NULL, BAD_CAST "resources");
700   xmlDocSetRootElement(theDoc, root_node);
701     
702   std::map<std::string, ParserResourcesType>::iterator iter = _resources_list.begin();
703   for (; iter != _resources_list.end(); iter++)
704   {
705     node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL);
706     RES_MESSAGE("Add resource name = " << (*iter).second.Name.c_str());
707     xmlNewProp(node, BAD_CAST test_name, BAD_CAST (*iter).second.Name.c_str());
708     xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str());
709     xmlNewProp(node, BAD_CAST test_type, BAD_CAST (*iter).second.getResourceTypeStr().c_str());
710     xmlNewProp(node, BAD_CAST test_appli_path, BAD_CAST (*iter).second.AppliPath.c_str());
711     xmlNewProp(node, BAD_CAST test_batch_queue, BAD_CAST (*iter).second.batchQueue.c_str());
712     xmlNewProp(node, BAD_CAST test_user_commands, BAD_CAST (*iter).second.userCommands.c_str());
713     xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST (*iter).second.getAccessProtocolTypeStr().c_str());
714     xmlNewProp(node, BAD_CAST test_cluster_internal_protocol,
715                BAD_CAST (*iter).second.getClusterInternalProtocolStr().c_str());
716     xmlNewProp(node, BAD_CAST test_working_directory, BAD_CAST (*iter).second.working_directory.c_str());
717     xmlNewProp(node, BAD_CAST test_can_launch_batch_jobs,
718                BAD_CAST (*iter).second.getCanLaunchBatchJobsStr().c_str());
719     xmlNewProp(node, BAD_CAST test_can_run_containers,
720                BAD_CAST (*iter).second.getCanRunContainersStr().c_str());
721     xmlNewProp(node, BAD_CAST test_batch, BAD_CAST (*iter).second.getBatchTypeStr().c_str());
722     xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST (*iter).second.getMpiImplTypeStr().c_str());
723     xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str());
724
725     std::vector<std::string>::const_iterator iter2 = (*iter).second.ComponentsList.begin();
726     for(;iter2 != (*iter).second.ComponentsList.end(); iter2++)
727     {
728       node1 = xmlNewChild(node, NULL, BAD_CAST test_components, NULL);
729       xmlNewProp(node1, BAD_CAST test_component_name, BAD_CAST (*iter2).c_str());
730     }
731
732     xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str());
733     std::ostringstream mem_stream;
734     mem_stream << (*iter).second.DataForSort._memInMB;
735     xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST mem_stream.str().c_str());
736     std::ostringstream cpu_stream;
737     cpu_stream << (*iter).second.DataForSort._CPUFreqMHz;
738     xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST cpu_stream.str().c_str());
739     std::ostringstream nb_nodes_stream;
740     nb_nodes_stream << (*iter).second.DataForSort._nbOfNodes;
741     xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST nb_nodes_stream.str().c_str());
742     std::ostringstream nb_proc_per_nodes_stream;
743     nb_proc_per_nodes_stream << (*iter).second.DataForSort._nbOfProcPerNode;
744     xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST nb_proc_per_nodes_stream.str().c_str());
745   }
746 }