Salome HOME
PR: default policy
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Handler.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, 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.
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 //  SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl)
23 //  File   : SALOME_ResourcesCatalog_Handler.cxx
24 //  Author : Estelle Deville
25 //  Module : SALOME
26 //$Header$
27 //
28 #include "SALOME_ResourcesCatalog_Handler.hxx"
29 #include "Basics_Utils.hxx"
30 #include <iostream>
31 #include <map>
32
33 using namespace std;
34
35 //=============================================================================
36 /*!
37  *  Constructor
38  *  \param listOfResources: map of ParserResourcesType to fill when parsing
39  */ 
40 //=============================================================================
41
42 SALOME_ResourcesCatalog_Handler::
43 SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& resources_list,
44                                 MapOfParserResourcesType& resources_batch_list):
45     _resources_list(resources_list),
46     _resources_batch_list(resources_batch_list)
47 {
48   //XML tags initialisation
49   test_machine = "machine";
50   test_resources = "resources";
51
52   test_hostname = "hostname";
53   test_alias = "alias";
54   test_protocol = "protocol";
55   test_mode = "mode";
56   test_batch = "batch";
57   test_mpi = "mpi";
58   test_user_name = "userName";
59   test_appli_path = "appliPath";
60   test_modules = "modules";
61   test_module_name = "moduleName";
62   test_components = "component";
63   test_component_name = "name";
64   test_os = "OS";
65   test_mem_in_mb = "memInMB";
66   test_cpu_freq_mhz = "CPUFreqMHz";
67   test_nb_of_nodes = "nbOfNodes";
68   test_nb_of_proc_per_node = "nbOfProcPerNode";
69   test_batch_queue = "batchQueue";
70   test_user_commands = "userCommands";
71 }
72
73 //=============================================================================
74 /*!
75  *  Destructor
76  */ 
77 //=============================================================================
78
79 SALOME_ResourcesCatalog_Handler::~SALOME_ResourcesCatalog_Handler()
80 {
81   //  cout << "SALOME_ResourcesCatalog_Handler destruction") << endl;
82 }
83
84 //=============================================================================
85 /*!
86  *  Retrieves DS after the file parse.
87  */ 
88 //=============================================================================
89
90 const MapOfParserResourcesType&
91 SALOME_ResourcesCatalog_Handler::GetResourcesAfterParsing() const
92 {
93   return _resources_list;
94 }
95
96 //=============================================================================
97 /*!
98  *  Processes XML document and fills the list of resources
99  */ 
100 //=============================================================================
101
102 void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc)
103 {
104   // Empty private elements
105   _resources_list.clear();
106
107   // Get the document root node
108   xmlNodePtr aCurNode = xmlDocGetRootElement(theDoc);
109
110   aCurNode = aCurNode->xmlChildrenNode;
111   
112   // Processing the document nodes
113   while(aCurNode != NULL)
114     {
115       if ( !xmlStrcmp(aCurNode->name,(const xmlChar*)test_machine) )
116         {
117           _resource.Clear();
118           if (xmlHasProp(aCurNode, (const xmlChar*)test_hostname))
119             {
120               xmlChar* hostname = xmlGetProp(aCurNode, (const xmlChar*)test_hostname);
121               _resource.DataForSort._hostName = (const char*)hostname;
122               _resource.HostName = (const char*)hostname;
123               xmlFree(hostname);
124             }
125           else
126             break;
127
128           if (xmlHasProp(aCurNode, (const xmlChar*)test_alias))
129             {
130               xmlChar* alias = xmlGetProp(aCurNode, (const xmlChar*)test_alias);
131               _resource.Alias = (const char*)alias;
132               xmlFree(alias);
133             }
134           else
135             _resource.Alias = "";
136
137           if (xmlHasProp(aCurNode, (const xmlChar*)test_batch_queue))
138             {
139               xmlChar* batch_queue = xmlGetProp(aCurNode, (const xmlChar*)test_batch_queue);
140               _resource.batchQueue = (const char*)batch_queue;
141               xmlFree(batch_queue);
142             }
143           else
144             _resource.batchQueue = "";
145
146           if (xmlHasProp(aCurNode, (const xmlChar*)test_user_commands))
147             {
148               xmlChar* user_commands= xmlGetProp(aCurNode, (const xmlChar*)test_user_commands);
149               _resource.userCommands = (const char*)user_commands;
150               xmlFree(user_commands);
151             }
152           else
153             _resource.userCommands = "";
154           
155           if (xmlHasProp(aCurNode, (const xmlChar*)test_protocol))
156             {
157               xmlChar* protocol= xmlGetProp(aCurNode, (const xmlChar*)test_protocol);
158               switch ( protocol[0])
159                 {
160                 case 'r':
161                   _resource.Protocol = rsh;
162                   break;
163                 case 's':
164                   _resource.Protocol = ssh;
165                   break;
166                 default:
167                   // If it'not in all theses cases, the protocol is affected to rsh
168                   _resource.Protocol = rsh;
169                   break;
170                 }
171               xmlFree(protocol);
172             }
173           else
174             _resource.Protocol = rsh;
175           
176           if (xmlHasProp(aCurNode, (const xmlChar*)test_mode))
177             {
178               xmlChar* mode=xmlGetProp(aCurNode, (const xmlChar*)test_mode);
179               switch ( mode[0] )
180                 {
181                 case 'i':
182                   _resource.Mode = interactive;
183                   break;
184                 case 'b':
185                   _resource.Mode = batch;
186                   break;
187                 default:
188                   // If it'not in all theses cases, the mode is affected to interactive
189                   _resource.Mode = interactive;
190                   break;
191                 }
192               xmlFree(mode);
193             }
194           else
195             _resource.Mode = interactive;
196
197           if (xmlHasProp(aCurNode, (const xmlChar*)test_batch))
198             {
199               xmlChar* batch = xmlGetProp(aCurNode, (const xmlChar*)test_batch);
200               std::string aBatch = (const char*)batch;
201               xmlFree(batch);
202               if (aBatch == "pbs")
203                 _resource.Batch = pbs;
204               else if  (aBatch == "lsf")
205                 _resource.Batch = lsf;
206               else if  (aBatch == "sge")
207                 _resource.Batch = sge;
208               else
209                 _resource.Batch = none;
210             }
211
212           if (xmlHasProp(aCurNode, (const xmlChar*)test_mpi))
213             {
214               xmlChar* mpi = xmlGetProp(aCurNode, (const xmlChar*)test_mpi);
215               std::string anMpi = (const char*)mpi;
216               xmlFree(mpi);
217               if (anMpi == "lam")
218                 _resource.mpi = lam;
219               else if (anMpi == "mpich1")
220                 _resource.mpi = mpich1;
221               else if (anMpi == "mpich2")
222                 _resource.mpi = mpich2;
223               else if (anMpi == "openmpi")
224                 _resource.mpi = openmpi;
225               else if  (anMpi == "slurm")
226                 _resource.mpi = slurm;
227               else if  (anMpi == "prun")
228                 _resource.mpi = prun;
229               else
230                 _resource.mpi = nompi;
231             }
232
233           if (xmlHasProp(aCurNode, (const xmlChar*)test_user_name))
234             {
235               xmlChar* user_name= xmlGetProp(aCurNode, (const xmlChar*)test_user_name);
236               _resource.UserName = (const char*)user_name;
237               xmlFree(user_name);
238             }
239           
240           if (xmlHasProp(aCurNode, (const xmlChar*)test_appli_path))
241             {
242               xmlChar* appli_path = xmlGetProp(aCurNode, (const xmlChar*)test_appli_path);
243               _resource.AppliPath = (const char*)appli_path;
244               xmlFree(appli_path);
245             }
246           
247           if (xmlHasProp(aCurNode, (const xmlChar*)test_os))
248             {
249               xmlChar* os = xmlGetProp(aCurNode, (const xmlChar*)test_os);
250               _resource.OS = (const char*)os;
251               xmlFree(os);
252             }
253           
254           if (xmlHasProp(aCurNode, (const xmlChar*)test_mem_in_mb))
255             {
256               xmlChar* mem_in_mb = xmlGetProp(aCurNode, (const xmlChar*)test_mem_in_mb);
257               _resource.DataForSort._memInMB = atoi((const char*)mem_in_mb);
258               xmlFree(mem_in_mb);
259             }
260           
261           if (xmlHasProp(aCurNode, (const xmlChar*)test_cpu_freq_mhz))
262             {
263               xmlChar* cpu_freq_mhz = xmlGetProp(aCurNode, (const xmlChar*)test_cpu_freq_mhz);
264               _resource.DataForSort._CPUFreqMHz = atoi((const char*)cpu_freq_mhz);
265               xmlFree(cpu_freq_mhz);
266             }
267           
268           if (xmlHasProp(aCurNode, (const xmlChar*)test_nb_of_nodes))
269             {
270               xmlChar* nb_of_nodes = xmlGetProp(aCurNode, (const xmlChar*)test_nb_of_nodes);
271               _resource.DataForSort._nbOfNodes = atoi((const char*)nb_of_nodes);
272               xmlFree(nb_of_nodes);
273             }
274           
275           if (xmlHasProp(aCurNode, (const xmlChar*)test_nb_of_proc_per_node))
276             {
277               xmlChar* nb_of_proc_per_node = xmlGetProp(aCurNode, (const xmlChar*)test_nb_of_proc_per_node);
278               _resource.DataForSort._nbOfProcPerNode = atoi((const char*)nb_of_proc_per_node);
279               xmlFree(nb_of_proc_per_node);
280             }
281           
282           // Process components
283           xmlNodePtr aCurSubNode = aCurNode->xmlChildrenNode;
284           while(aCurSubNode != NULL)
285             {
286               if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_components) )
287                 {
288                   //If a component is given, it is in a module with the same name
289                   //except if the module name is given
290                   if (xmlHasProp(aCurSubNode, (const xmlChar*)test_component_name)) 
291                     {
292                       xmlChar* component_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_component_name);
293                       std::string aComponentName = (const char*)component_name;
294                       _resource.ComponentsList.push_back(aComponentName);
295                       if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
296                         {
297                           xmlChar* module_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
298                           std::string aModuleName = (const char*)module_name;
299                           _resource.ModulesList.push_back(aModuleName);
300                           xmlFree(module_name);
301                         }
302                       else
303                         _resource.ModulesList.push_back(aComponentName);
304                       xmlFree(component_name);
305                     }
306                 }
307               else if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_modules) )
308                 {
309                   // If a module is given, we create an entry in componentsList and modulesList
310                   // with the same name (module == component)
311                   if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
312                     {
313                       xmlChar* component_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
314                       std::string aComponentName = (const char*)component_name;
315                       _resource.ComponentsList.push_back(aComponentName);
316                       _resource.ModulesList.push_back(aComponentName);
317                       xmlFree(component_name);
318                     }
319                 }
320               aCurSubNode = aCurSubNode->next;
321             }
322          
323           // There is two lists
324           // _resources_list for interactive resources
325           // _resources_batch_list for batch resources
326           // This choice is done with Mode parameter
327           if (_resource.Mode == interactive)
328           {
329             int aNbNodes = _resource.DataForSort._nbOfNodes;
330             if( aNbNodes > 1 ){
331               string clusterNode = _resource.DataForSort._hostName ;
332               for( int i=0; i < aNbNodes; i++ ){
333                 char inode[64];
334                 inode[0] = '\0' ;
335                 sprintf(inode,"%s%d",clusterNode.c_str(),i+1);
336                 std::string nodeName(inode);
337                 _resource.DataForSort._hostName = nodeName ;
338                 _resource.HostName = nodeName ;
339                 _resources_list[nodeName] = _resource;
340               }
341             }
342             else
343               {
344                 if(_resource.HostName == "localhost")
345                   {
346                     _resource.HostName = Kernel_Utils::GetHostname();
347                     _resource.DataForSort._hostName = Kernel_Utils::GetHostname();
348                     _resources_list[Kernel_Utils::GetHostname()] = _resource;
349                   }
350                 else
351                   _resources_list[_resource.HostName] = _resource;
352               }
353           }
354           else
355             _resources_batch_list[_resource.HostName] = _resource;
356         }
357       aCurNode = aCurNode->next;
358     }
359
360 #ifdef _DEBUG_
361     for (map<string, ParserResourcesType>::const_iterator iter =
362            _resources_list.begin();
363          iter != _resources_list.end();
364          iter++)
365       {
366         std::cerr << (*iter).first << std::endl;
367         std::cerr << (*iter).second.HostName << std::endl;
368         std::cerr << (*iter).second.Alias << std::endl;
369         std::cerr << (*iter).second.UserName << std::endl;
370         std::cerr << (*iter).second.AppliPath << std::endl;
371         std::cerr << (*iter).second.OS << std::endl;
372         std::cerr << (*iter).second.Protocol << std::endl;
373         std::cerr << (*iter).second.Mode << std::endl;
374       }
375 #endif
376
377 }
378
379
380 //=============================================================================
381 /*!
382  *  Fill the document tree in xml file, used to write in an xml file.
383  *  \param theDoc document to fill.
384  */ 
385 //=============================================================================
386
387 void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc)
388 {
389   // Node pointers
390   xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;
391   char string_buf[80];
392
393   root_node = xmlNewNode(NULL, BAD_CAST "resources");
394   xmlDocSetRootElement(theDoc, root_node);
395     
396   for (map<string, ParserResourcesType>::iterator iter =
397          _resources_list.begin();
398        iter != _resources_list.end();
399        iter++)
400     {
401       node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL);
402       xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str());
403       xmlNewProp(node, BAD_CAST test_alias, BAD_CAST (*iter).second.Alias.c_str());
404       xmlNewProp(node, BAD_CAST test_batch_queue, BAD_CAST (*iter).second.batchQueue.c_str());
405       xmlNewProp(node, BAD_CAST test_user_commands, BAD_CAST (*iter).second.userCommands.c_str());
406   
407       switch ((*iter).second.Protocol)
408         {
409         case rsh:
410           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
411           break;
412         case ssh:
413           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "ssh");
414           break;
415         default:
416           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
417         }
418
419       switch ((*iter).second.Mode)
420         {
421         case interactive:
422           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
423           break;
424         case batch:
425           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "batch");
426           break;
427         default:
428           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
429         }
430
431       switch ((*iter).second.Batch)
432         {
433         case pbs:
434           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "pbs");
435           break;
436         case lsf:
437           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "lsf");
438           break;
439         case sge:
440           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
441           break;
442         default:
443           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
444         }
445
446       switch ((*iter).second.mpi)
447         {
448         case lam:
449           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "lam");
450           break;
451         case mpich1:
452           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich1");
453           break;
454         case mpich2:
455           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich2");
456           break;
457         case openmpi:
458           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "openmpi");
459           break;
460         case slurm:
461           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "slurm");
462           break;
463         case prun:
464           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "prun");
465           break;
466         default:
467           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "");
468         }
469
470       xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str());
471
472      for (vector<string>::const_iterator iter2 =
473              (*iter).second.ComponentsList.begin();
474            iter2 != (*iter).second.ComponentsList.end();
475            iter2++)
476         {
477           node1 = xmlNewChild(node, NULL, BAD_CAST test_components, NULL);
478           xmlNewProp(node1, BAD_CAST test_component_name, BAD_CAST (*iter2).c_str());
479         }
480
481       xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str());
482       xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._memInMB));
483       xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._CPUFreqMHz));
484       xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfNodes));
485       xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfProcPerNode));
486     }
487   for (map<string, ParserResourcesType>::iterator iter =
488          _resources_batch_list.begin();
489        iter != _resources_batch_list.end();
490        iter++)
491     {
492       node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL);
493       xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str());
494       xmlNewProp(node, BAD_CAST test_alias, BAD_CAST (*iter).second.Alias.c_str());
495       
496       switch ((*iter).second.Protocol)
497         {
498         case rsh:
499           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
500           break;
501         case ssh:
502           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "ssh");
503           break;
504         default:
505           xmlNewProp(node, BAD_CAST test_protocol, BAD_CAST "rsh");
506         }
507
508       switch ((*iter).second.Mode)
509         {
510         case interactive:
511           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
512           break;
513         case batch:
514           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "batch");
515           break;
516         default:
517           xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
518         }
519
520       switch ((*iter).second.Batch)
521         {
522         case pbs:
523           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "pbs");
524           break;
525         case lsf:
526           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "lsf");
527           break;
528         case sge:
529           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
530           break;
531         default:
532           xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
533         }
534
535       switch ((*iter).second.mpi)
536         {
537         case lam:
538           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "lam");
539           break;
540         case mpich1:
541           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich1");
542           break;
543         case mpich2:
544           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich2");
545           break;
546         case openmpi:
547           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "openmpi");
548           break;
549         case slurm:
550           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "slurm");
551           break;
552         case prun:
553           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "prun");
554           break;
555         default:
556           xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "");
557         }
558
559       xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str());
560
561      for (vector<string>::const_iterator iter2 =
562              (*iter).second.ComponentsList.begin();
563            iter2 != (*iter).second.ComponentsList.end();
564            iter2++)
565         {
566           node1 = xmlNewChild(node, NULL, BAD_CAST test_components, NULL);
567           xmlNewProp(node1, BAD_CAST test_component_name, BAD_CAST (*iter2).c_str());
568         }
569
570       xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str());
571       xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._memInMB));
572       xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._CPUFreqMHz));
573       xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfNodes));
574       xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST sprintf(string_buf, "%u", (*iter).second.DataForSort._nbOfProcPerNode));
575     }
576 }