Salome HOME
typo-fix by Kunda
[modules/kernel.git] / src / Launcher / Launcher.cxx
1 // Copyright (C) 2007-2016  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, 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 #include <list>
24 #include <iostream>
25 #include <sstream>
26 #include <sys/stat.h>
27 #include <time.h>
28
29 #ifdef WITH_LIBBATCH
30 #include <libbatch/BatchManagerCatalog.hxx>
31 #include <libbatch/FactBatchManager.hxx>
32 #include <libbatch/BatchManager.hxx>
33 #endif
34
35 #include "Basics_Utils.hxx"
36 #include "Basics_DirUtils.hxx"
37 #include "SALOME_Launcher_Handler.hxx"
38 #include "Launcher.hxx"
39 #include "Launcher_Job_Command.hxx"
40 #include "Launcher_XML_Persistence.hxx"
41
42 using namespace std;
43
44 //=============================================================================
45 /*! 
46  *  Constructor
47  *  \param orb
48  *  Define a CORBA single thread policy for the server, which avoid to deal
49  *  with non thread-safe usage like Change_Directory in SALOME naming service
50  */
51 //=============================================================================
52 Launcher_cpp::Launcher_cpp()
53 {
54   LAUNCHER_MESSAGE("Launcher_cpp constructor");
55   _job_cpt = 0;
56   _job_cpt_mutex = new pthread_mutex_t();
57   pthread_mutex_init(_job_cpt_mutex, NULL);
58 }
59
60 //=============================================================================
61 /*! 
62  * destructor
63  */
64 //=============================================================================
65 Launcher_cpp::~Launcher_cpp()
66 {
67   LAUNCHER_MESSAGE("Launcher_cpp destructor");
68 #ifdef WITH_LIBBATCH
69   std::map<int, Launcher::Job *>::const_iterator it_job;
70   for(it_job = _launcher_job_map.begin(); it_job != _launcher_job_map.end(); it_job++)
71     delete it_job->second;
72   std::map <int, Batch::BatchManager * >::const_iterator it1;
73   for(it1=_batchmap.begin();it1!=_batchmap.end();it1++)
74     delete it1->second;
75 #endif
76
77   pthread_mutex_destroy(_job_cpt_mutex);
78   delete _job_cpt_mutex;
79 }
80
81 #ifdef WITH_LIBBATCH
82
83 //=============================================================================
84 /*!
85  * Add a job into the launcher - check resource and choose one 
86  */ 
87 //=============================================================================
88 void 
89 Launcher_cpp::createJob(Launcher::Job * new_job)
90 {
91   LAUNCHER_MESSAGE("Creating a new job");
92   // Add job to the jobs map
93   pthread_mutex_lock(_job_cpt_mutex);
94   new_job->setNumber(_job_cpt);
95   _job_cpt++;
96   pthread_mutex_unlock(_job_cpt_mutex);
97   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(new_job->getNumber());
98   if (it_job == _launcher_job_map.end())
99     _launcher_job_map[new_job->getNumber()] = new_job;
100   else
101   {
102     LAUNCHER_INFOS("A job as already the same id: " << new_job->getNumber());
103     delete new_job;
104     throw LauncherException("A job as already the same id - job is not created !");
105   }
106   LAUNCHER_MESSAGE("New Job created");
107 }
108
109 //=============================================================================
110 /*!
111  * Launch a job 
112  */ 
113 //=============================================================================
114 void 
115 Launcher_cpp::launchJob(int job_id)
116 {
117   LAUNCHER_MESSAGE("Launch a job");
118
119   // Check if job exist
120   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
121   if (it_job == _launcher_job_map.end())
122   {
123     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
124     throw LauncherException("Cannot find the job, is it created ?");
125   }
126
127   Launcher::Job * job = it_job->second;
128
129   // Check job state (cannot launch a job already launched...)
130   if (job->getState() != "CREATED")
131   {
132     LAUNCHER_INFOS("Bad state of the job: " << job->getState());
133     throw LauncherException("Bad state of the job: " + job->getState());
134   }
135
136   // Third step search batch manager for the job into the map -> instantiate one if does not exist
137 #ifdef WITH_LIBBATCH
138   std::map<int, Batch::BatchManager *>::const_iterator it = _batchmap.find(job_id);
139   if(it == _batchmap.end())
140   {
141     createBatchManagerForJob(job);
142   }
143 #endif
144
145   try {
146     Batch::JobId batch_manager_job_id = _batchmap[job_id]->submitJob(*(job->getBatchJob()));
147     job->setBatchManagerJobId(batch_manager_job_id);
148     job->setState("QUEUED");
149     job->setReference(batch_manager_job_id.getReference());
150   }
151   catch(const Batch::GenericException &ex)
152   {
153     LAUNCHER_INFOS("Job is not launched, exception in submitJob: " << ex.message);
154     throw LauncherException(ex.message.c_str());
155   }
156   LAUNCHER_MESSAGE("Job launched");
157 }
158
159 //=============================================================================
160 /*!
161  * Get job state
162  */ 
163 //=============================================================================
164 const char *
165 Launcher_cpp::getJobState(int job_id)
166 {
167   LAUNCHER_MESSAGE("Get job state");
168
169   // Check if job exist
170   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
171   if (it_job == _launcher_job_map.end())
172   {
173     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
174     throw LauncherException("Cannot find the job, is it created ?");
175   }
176
177   Launcher::Job * job = it_job->second;
178
179   std::string state;
180   try
181   {
182     state = job->updateJobState();
183   }
184   catch(const Batch::GenericException &ex)
185   {
186     LAUNCHER_INFOS("getJobState failed, exception: " << ex.message);
187     throw LauncherException(ex.message.c_str());
188   }
189
190   return state.c_str();
191 }
192
193 //=============================================================================
194 /*!
195  * Get job assigned hostnames
196  */
197 //=============================================================================
198 const char *
199 Launcher_cpp::getAssignedHostnames(int job_id)
200 {
201   LAUNCHER_MESSAGE("Get job assigned hostnames");
202
203   // Check if job exist
204   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
205   if (it_job == _launcher_job_map.end())
206   {
207     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
208     throw LauncherException("Cannot find the job, is it created ?");
209   }
210
211   Launcher::Job * job = it_job->second;
212   std::string assigned_hostnames = job->getAssignedHostnames();
213
214   return assigned_hostnames.c_str();
215 }
216
217 //=============================================================================
218 /*!
219  * Get Job result - the result directory could be changed
220  */ 
221 //=============================================================================
222 void
223 Launcher_cpp::getJobResults(int job_id, std::string directory)
224 {
225   LAUNCHER_MESSAGE("Get Job results");
226
227   // Check if job exist
228   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
229   if (it_job == _launcher_job_map.end())
230   {
231     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
232     throw LauncherException("Cannot find the job, is it created ?");
233   }
234
235   Launcher::Job * job = it_job->second;
236   std::string resource_name = job->getResourceDefinition().Name;
237   try 
238   {
239     if (directory != "")
240       _batchmap[job_id]->importOutputFiles(*(job->getBatchJob()), directory);
241     else
242       _batchmap[job_id]->importOutputFiles(*(job->getBatchJob()), job->getResultDirectory());
243   }
244   catch(const Batch::GenericException &ex)
245   {
246     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
247     throw LauncherException(ex.message.c_str());
248   }
249   LAUNCHER_MESSAGE("getJobResult ended");
250 }
251
252 //=============================================================================
253 /*!
254  * Clear the remote working directory
255  */
256 //=============================================================================
257 void
258 Launcher_cpp::clearJobWorkingDir(int job_id)
259 {
260   LAUNCHER_MESSAGE("Clear the remote working directory");
261
262   // Check if job exist
263   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
264   if (it_job == _launcher_job_map.end())
265   {
266     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
267     throw LauncherException("Cannot find the job, is it created ?");
268   }
269
270   Launcher::Job * job = it_job->second;
271   try
272   {
273     _batchmap[job_id]->clearWorkingDir(*(job->getBatchJob()));
274   }
275   catch(const Batch::GenericException &ex)
276   {
277     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
278     throw LauncherException(ex.message.c_str());
279   }
280   LAUNCHER_MESSAGE("getJobResult ended");
281 }
282
283 //=============================================================================
284 /*!
285  * Get Job dump state - the result directory could be changed
286  */ 
287 //=============================================================================
288 bool
289 Launcher_cpp::getJobDumpState(int job_id, std::string directory)
290 {
291   bool rtn;
292   LAUNCHER_MESSAGE("Get Job dump state");
293
294   // Check if job exist
295   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
296   if (it_job == _launcher_job_map.end())
297   {
298     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
299     throw LauncherException("Cannot find the job, is it created ?");
300   }
301
302   Launcher::Job * job = it_job->second;
303   std::string resource_name = job->getResourceDefinition().Name;
304   try 
305   {
306     if (directory != "")
307       rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), directory);
308     else
309       rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), job->getResultDirectory());
310   }
311   catch(const Batch::GenericException &ex)
312   {
313     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
314     throw LauncherException(ex.message.c_str());
315   }
316   LAUNCHER_MESSAGE("getJobResult ended");
317   return rtn;
318 }
319
320 //=============================================================================
321 /*!
322  * Get one file from the working directory - the result directory can be changed
323  */
324 //=============================================================================
325 bool
326 Launcher_cpp::getJobWorkFile(int job_id,
327                              std::string work_file,
328                              std::string directory)
329 {
330   bool rtn;
331   LAUNCHER_MESSAGE("Get working file " << work_file);
332
333   // Check if job exist
334   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
335   if (it_job == _launcher_job_map.end())
336   {
337     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
338     throw LauncherException("Cannot find the job, is it created ?");
339   }
340
341   Launcher::Job * job = it_job->second;
342   std::string resource_name = job->getResourceDefinition().Name;
343   try
344   {
345     if (directory != "")
346       rtn = _batchmap[job_id]->importWorkFile(*(job->getBatchJob()), work_file, directory);
347     else
348       rtn = _batchmap[job_id]->importWorkFile(*(job->getBatchJob()), work_file, job->getResultDirectory());
349   }
350   catch(const Batch::GenericException &ex)
351   {
352     LAUNCHER_INFOS("getJobWorkFile is maybe incomplete, exception: " << ex.message);
353     throw LauncherException(ex.message.c_str());
354   }
355   LAUNCHER_MESSAGE("getJobWorkFile ended");
356   return rtn;
357 }
358
359 //=============================================================================
360 /*!
361  * Remove the job - into the Launcher and its batch manager
362  */ 
363 //=============================================================================
364 void
365 Launcher_cpp::removeJob(int job_id)
366 {
367   LAUNCHER_MESSAGE("Remove Job");
368
369   // Check if job exist
370   std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
371   if (it_job == _launcher_job_map.end())
372   {
373     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
374     throw LauncherException("Cannot find the job, is it created ?");
375   }
376
377   it_job->second->removeJob();
378   delete it_job->second;
379   _launcher_job_map.erase(it_job);
380 }
381
382 //=============================================================================
383 /*!
384  * stop the job
385  */ 
386 //=============================================================================
387 void
388 Launcher_cpp::stopJob(int job_id)
389 {
390   LAUNCHER_MESSAGE("Stop Job");
391
392   // Check if job exist
393   std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
394   if (it_job == _launcher_job_map.end())
395   {
396     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
397     throw LauncherException("Cannot find the job, is it created ?");
398   }
399
400   it_job->second->stopJob();
401 }
402
403 //=============================================================================
404 /*! 
405  *  create a launcher job based on a file
406  *  \param xmlExecuteFile     : to define the execution on the batch cluster
407  */
408 //=============================================================================
409 long 
410 Launcher_cpp::createJobWithFile(const std::string xmlExecuteFile, 
411                                 const std::string clusterName)
412 {
413   LAUNCHER_MESSAGE("Begin of Launcher_cpp::createJobWithFile");
414
415   // Parsing xml file
416   ParserLauncherType job_params = ParseXmlFile(xmlExecuteFile);
417
418   // Creating a new job
419   Launcher::Job_Command * new_job = new Launcher::Job_Command();
420
421   std::string cmdFile = Kernel_Utils::GetTmpFileName();  
422 #ifndef WIN32
423   cmdFile += ".sh";
424 #else
425   cmdFile += ".bat";
426 #endif
427   std::ofstream os;
428   os.open(cmdFile.c_str(), std::ofstream::out );
429   os << "#! /bin/sh" << std::endl;
430   os << job_params.Command;
431   os.close();
432
433   new_job->setJobFile(cmdFile);
434   new_job->setLocalDirectory(job_params.RefDirectory);
435   new_job->setWorkDirectory(job_params.MachinesList[clusterName].WorkDirectory);
436   new_job->setEnvFile(job_params.MachinesList[clusterName].EnvFile);
437
438   for(int i=0; i < job_params.InputFile.size(); i++)
439     new_job->add_in_file(job_params.InputFile[i]);
440   for(int i=0; i < job_params.OutputFile.size();i++)
441     new_job->add_out_file(job_params.OutputFile[i]);
442
443   resourceParams p;
444   p.hostname = clusterName;
445   p.name = "";
446   p.OS = "";
447   p.nb_proc = job_params.NbOfProcesses;
448   p.nb_node = 0;
449   p.nb_proc_per_node = 0;
450   p.cpu_clock = 0;
451   p.mem_mb = 0;
452   new_job->setResourceRequiredParams(p);
453
454   createJob(new_job);
455   return new_job->getNumber();
456 }
457
458 //=============================================================================
459 /*!
460  *  Factory to instantiate the good batch manager for chosen cluster.
461  */ 
462 //=============================================================================
463 Batch::BatchManager *
464 Launcher_cpp::FactoryBatchManager(ParserResourcesType& params)
465 {
466   std::string mpi;
467   Batch::CommunicationProtocolType protocol;
468   Batch::FactBatchManager * fact;
469
470   std::string hostname = params.HostName;
471
472   switch(params.Protocol)
473   {
474     case sh:
475       protocol = Batch::SH;
476       break;
477     case rsh:
478       protocol = Batch::RSH;
479       break;
480     case ssh:
481       protocol = Batch::SSH;
482       break;
483     case rsync:
484       protocol = Batch::RSYNC;
485       break;
486     default:
487       throw LauncherException("Unknown protocol for this resource");
488       break;
489   }
490
491   switch(params.mpi)
492   {
493     case lam:
494       mpi = "lam";
495       break;
496     case mpich1:
497       mpi = "mpich1";
498       break;
499     case mpich2:
500       mpi = "mpich2";
501       break;
502     case openmpi:
503       mpi = "openmpi";
504       break;
505     case ompi:
506       mpi = "ompi";
507       break;
508     case slurmmpi:
509       mpi = "slurmmpi";
510       break;
511     case prun:
512       mpi = "prun";
513       break;
514     default:
515       mpi = "nompi";
516   }
517
518   const char * bmType;
519   switch( params.Batch )
520   {
521     case pbs:
522       bmType = "PBS";
523       break;
524     case lsf:
525       bmType = "LSF";
526       break;
527     case sge:
528       bmType = "SGE";
529       break;
530     case ccc:
531       bmType = "CCC";
532       break;
533     case slurm:
534       bmType = "SLURM";
535       break;
536     case none:
537       bmType = "LOCAL";
538       break;
539     case ll:
540       bmType = "LL";
541       break;
542     case vishnu:
543       bmType = "VISHNU";
544       break;
545     case oar:
546       bmType = "OAR";
547       break;
548     case coorm:
549       bmType = "COORM";
550       break;
551     default:
552       LAUNCHER_MESSAGE("Bad batch description of the resource: Batch = " << params.Batch);
553       throw LauncherException("No batchmanager for that cluster - Bad batch description of the resource");
554   }
555   Batch::BatchManagerCatalog & cata = Batch::BatchManagerCatalog::getInstance();
556   fact = dynamic_cast<Batch::FactBatchManager*>(cata(bmType));
557   if (fact == NULL) {
558     LAUNCHER_MESSAGE("Cannot find batch manager factory for " << bmType << ". Check your version of libBatch.");
559     throw LauncherException("Cannot find batch manager factory");
560   }
561   LAUNCHER_MESSAGE("Instantiation of batch manager of type: " << bmType);
562   Batch::BatchManager * batch_client = (*fact)(hostname.c_str(), params.UserName.c_str(),
563                                                protocol, mpi.c_str());
564   return batch_client;
565 }
566
567 //----------------------------------------------------------
568 // Without LIBBATCH - Launcher_cpp do nothing...
569 //----------------------------------------------------------
570 #else
571
572 void 
573 Launcher_cpp::createJob(Launcher::Job * new_job)
574 {
575   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot create a job !!!");
576   delete new_job;
577   throw LauncherException("Method Launcher_cpp::createJob is not available "
578                           "(libBatch was not present at compilation time)");
579 }
580
581 void 
582 Launcher_cpp::launchJob(int job_id)
583 {
584   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot launch a job !!!");
585   throw LauncherException("Method Launcher_cpp::launchJob is not available "
586                           "(libBatch was not present at compilation time)");
587 }
588
589 const char *
590 Launcher_cpp::getJobState(int job_id)
591 {
592   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job state!!!");
593   throw LauncherException("Method Launcher_cpp::getJobState is not available "
594                           "(libBatch was not present at compilation time)");
595 }
596
597 const char *
598 Launcher_cpp::getAssignedHostnames(int job_id)
599 {
600   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job assigned hostnames!!!");
601   throw LauncherException("Method Launcher_cpp::getAssignedHostnames is not available "
602                           "(libBatch was not present at compilation time)");
603 }
604
605 void
606 Launcher_cpp::getJobResults(int job_id, std::string directory)
607 {
608   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job results!!!");
609   throw LauncherException("Method Launcher_cpp::getJobResults is not available "
610                           "(libBatch was not present at compilation time)");
611 }
612
613 void
614 Launcher_cpp::clearJobWorkingDir(int job_id)
615 {
616   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot clear directory!!!");
617   throw LauncherException("Method Launcher_cpp::clearJobWorkingDir is not available "
618                           "(libBatch was not present at compilation time)");
619 }
620
621 bool
622 Launcher_cpp::getJobDumpState(int job_id, std::string directory)
623 {
624   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job dump state!!!");
625   throw LauncherException("Method Launcher_cpp::getJobDumpState is not available "
626                           "(libBatch was not present at compilation time)");
627 }
628
629 bool
630 Launcher_cpp::getJobWorkFile(int job_id, std::string work_file, std::string directory)
631 {
632   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job dump state!!!");
633   throw LauncherException("Method Launcher_cpp::getJobWorkFile is not available "
634                           "(libBatch was not present at compilation time)");
635 }
636
637 void
638 Launcher_cpp::removeJob(int job_id)
639 {
640   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot remove job!!!");
641   throw LauncherException("Method Launcher_cpp::removeJob is not available "
642                           "(libBatch was not present at compilation time)");
643 }
644
645 void
646 Launcher_cpp::stopJob(int job_id)
647 {
648   throw LauncherException("Method Launcher_cpp::stopJob is not available "
649                           "(libBatch was not present at compilation time)");
650 }
651
652 long 
653 Launcher_cpp::createJobWithFile( const std::string xmlExecuteFile, std::string clusterName)
654 {
655   throw LauncherException("Method Launcher_cpp::createJobWithFile is not available "
656                           "(libBatch was not present at compilation time)");
657   return 0;
658 }
659
660 #endif
661
662 ParserLauncherType 
663 Launcher_cpp::ParseXmlFile(std::string xmlExecuteFile)
664 {
665   ParserLauncherType job_params;
666   SALOME_Launcher_Handler * handler = new SALOME_Launcher_Handler(job_params);
667
668   const char* aFilePath = xmlExecuteFile.c_str();
669   FILE* aFile = fopen(aFilePath, "r");
670   if (aFile != NULL)
671   {
672     xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
673     if (aDoc != NULL)
674       handler->ProcessXmlDocument(aDoc);
675     else
676     {
677       std::string message = "ResourcesManager_cpp: could not parse file: " + xmlExecuteFile;
678       LAUNCHER_MESSAGE(message);
679       delete handler;
680       throw LauncherException(message);
681     }
682     // Free the document
683     xmlFreeDoc(aDoc);
684     fclose(aFile);
685   }
686   else
687   {
688     std::string message = "ResourcesManager_cpp: file is not readable: " + xmlExecuteFile;
689     LAUNCHER_MESSAGE(message);
690     delete handler;
691     throw LauncherException(message);
692   }
693
694   // Return
695   delete handler;
696   return job_params;
697 }
698
699 std::map<int, Launcher::Job *>
700 Launcher_cpp::getJobs()
701 {
702   return _launcher_job_map;
703 }
704
705 void 
706 Launcher_cpp::createBatchManagerForJob(Launcher::Job * job)
707 {
708   int job_id = job->getNumber();
709
710   // Select a resource for the job
711   std::vector<std::string> ResourceList;
712   resourceParams params = job->getResourceRequiredParams();
713   // Consider only resources that can launch batch jobs
714   params.can_launch_batch_jobs = true;
715   try
716   {
717     ResourceList = _ResManager->GetFittingResources(params);
718   }
719   catch(const ResourcesException &ex)
720   {
721     throw LauncherException(ex.msg.c_str());
722   }
723   if (ResourceList.size() == 0)
724   {
725     LAUNCHER_INFOS("No adequate resource found for the job, number " << job->getNumber());
726     job->setState("ERROR");
727     throw LauncherException("No resource found the job");
728   }
729
730   // Configure the job with the resource selected - the first of the list
731   ParserResourcesType resource_definition = _ResManager->GetResourcesDescr(ResourceList[0]);
732
733   // Set resource definition to the job
734   // The job will check if the definitions needed
735   try
736   {
737     job->setResourceDefinition(resource_definition);
738   }
739   catch(const LauncherException &ex)
740   {
741     LAUNCHER_INFOS("Error in the definition of the resource, mess: " << ex.msg);
742     job->setState("ERROR");
743     throw ex;
744   }
745
746   // Step 2: We can now add a Factory if the resource is correctly define
747 #ifdef WITH_LIBBATCH
748   std::map<int, Batch::BatchManager *>::const_iterator it = _batchmap.find(job_id);
749   if(it == _batchmap.end())
750   {
751     try
752     {
753       // Warning cannot write on one line like this, because map object is constructed before
754       // the method is called...
755       //_batchmap[job_id] = FactoryBatchManager(resource_definition);
756       Batch::BatchManager * batch_client = FactoryBatchManager(resource_definition);
757       _batchmap[job_id] = batch_client;
758     }
759     catch(const LauncherException &ex)
760     {
761       LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.msg);
762       throw ex;
763     }
764     catch(const Batch::GenericException &ex)
765     {
766       LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.message);
767       throw LauncherException(ex.message);
768     }
769   }
770 #endif
771 }
772
773 void 
774 Launcher_cpp::addJobDirectlyToMap(Launcher::Job * new_job)
775 {
776   // Step 0: Calculated job_id
777   pthread_mutex_lock(_job_cpt_mutex);
778   int job_id = _job_cpt;
779   _job_cpt++;
780   new_job->setNumber(job_id);
781   pthread_mutex_unlock(_job_cpt_mutex);
782
783   // Step 1: check if resource is already in the map
784   createBatchManagerForJob(new_job);
785
786   // Step 2: add the job to the batch manager
787 #ifdef WITH_LIBBATCH
788   try
789   {
790     Batch::JobId batch_manager_job_id = _batchmap[job_id]->addJob(*(new_job->getBatchJob()),
791                                                                   new_job->getReference());
792     new_job->setBatchManagerJobId(batch_manager_job_id);
793   }
794   catch(const Batch::GenericException &ex)
795   {
796     LAUNCHER_INFOS("Job cannot be added, exception in addJob: " << ex.message);
797     throw LauncherException(ex.message.c_str());
798   }
799
800   // Step 3: add job to launcher map
801   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(new_job->getNumber());
802   if (it_job == _launcher_job_map.end())
803     _launcher_job_map[new_job->getNumber()] = new_job;
804   else
805   {
806     LAUNCHER_INFOS("A job as already the same id: " << new_job->getNumber());
807     delete new_job;
808     throw LauncherException("A job as already the same id - job is not created !");
809   }
810   LAUNCHER_MESSAGE("New job added");
811 #endif
812 }
813
814 list<int>
815 Launcher_cpp::loadJobs(const char* jobs_file)
816 {
817   list<int> new_jobs_id_list;
818
819   // Load the jobs from XML file
820   list<Launcher::Job *> jobs_list = Launcher::XML_Persistence::loadJobs(jobs_file);
821
822   // Create each job in the launcher
823   list<Launcher::Job *>::const_iterator it_job;
824   for (it_job = jobs_list.begin(); it_job != jobs_list.end(); it_job++)
825   {
826     Launcher::Job * new_job = *it_job;
827     string job_state = new_job->getState();
828
829     try
830     {
831       if (job_state == "CREATED")
832       {
833         // In this case, we ignore run_part information
834         createJob(new_job);
835         new_jobs_id_list.push_back(new_job->getNumber());
836       }
837       else if (job_state == "QUEUED"     ||
838                job_state == "RUNNING"    ||
839                job_state == "IN_PROCESS" ||
840                job_state == "PAUSED")
841       {
842         addJobDirectlyToMap(new_job);
843         new_jobs_id_list.push_back(new_job->getNumber());
844
845         // Step 4: We check that the BatchManager could resume
846         // the job
847 #ifdef WITH_LIBBATCH
848         if (new_job->getBatchManagerJobId().getReference() != new_job->getReference())
849         {
850           LAUNCHER_INFOS("BatchManager type cannot resume a job - job state is set to ERROR");
851           new_job->setState("ERROR");
852         }
853 #endif
854       }
855       else if (job_state == "FINISHED" ||
856                job_state == "FAILED"   ||
857                job_state == "ERROR")
858       {
859         // Step 2: We add run_part information
860         addJobDirectlyToMap(new_job);
861         new_jobs_id_list.push_back(new_job->getNumber());
862       }
863       else
864       {
865         LAUNCHER_INFOS("A bad job is found, state unknown " << job_state);
866         delete new_job;
867       }
868     }
869     catch(const LauncherException &ex)
870     {
871       LAUNCHER_INFOS("Cannot load the job. Exception: " << ex.msg.c_str());
872       delete new_job;
873     }
874   }
875
876   return new_jobs_id_list;
877 }
878
879 void
880 Launcher_cpp::saveJobs(const char* jobs_file)
881 {
882   // Create a sorted list from the internal job map
883   list<const Launcher::Job *> jobs_list;
884   for (int i=0; i<_job_cpt; i++)
885   {
886     map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(i);
887     if (it_job != _launcher_job_map.end())
888       jobs_list.push_back(it_job->second);
889   }
890
891   // Save the jobs in XML file
892   Launcher::XML_Persistence::saveJobs(jobs_file, jobs_list);
893 }