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