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