Salome HOME
Merge remote-tracking branch 'origin/vsr/fix_single_study_pb' into pre/fix_single_study
[modules/kernel.git] / src / Launcher / Launcher.cxx
1 // Copyright (C) 2007-2014  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 -> instanciate 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  * Get Job dump state - the result directory could be changed
255  */ 
256 //=============================================================================
257 bool
258 Launcher_cpp::getJobDumpState(int job_id, std::string directory)
259 {
260   bool rtn;
261   LAUNCHER_MESSAGE("Get Job dump state");
262
263   // Check if job exist
264   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
265   if (it_job == _launcher_job_map.end())
266   {
267     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
268     throw LauncherException("Cannot find the job, is it created ?");
269   }
270
271   Launcher::Job * job = it_job->second;
272   std::string resource_name = job->getResourceDefinition().Name;
273   try 
274   {
275     if (directory != "")
276       rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), directory);
277     else
278       rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), job->getResultDirectory());
279   }
280   catch(const Batch::GenericException &ex)
281   {
282     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
283     throw LauncherException(ex.message.c_str());
284   }
285   LAUNCHER_MESSAGE("getJobResult ended");
286   return rtn;
287 }
288
289 //=============================================================================
290 /*!
291  * Remove the job - into the Launcher and its batch manager
292  */ 
293 //=============================================================================
294 void
295 Launcher_cpp::removeJob(int job_id)
296 {
297   LAUNCHER_MESSAGE("Remove Job");
298
299   // Check if job exist
300   std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
301   if (it_job == _launcher_job_map.end())
302   {
303     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
304     throw LauncherException("Cannot find the job, is it created ?");
305   }
306
307   it_job->second->removeJob();
308   delete it_job->second;
309   _launcher_job_map.erase(it_job);
310 }
311
312 //=============================================================================
313 /*!
314  * stop the job
315  */ 
316 //=============================================================================
317 void
318 Launcher_cpp::stopJob(int job_id)
319 {
320   LAUNCHER_MESSAGE("Stop Job");
321
322   // Check if job exist
323   std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
324   if (it_job == _launcher_job_map.end())
325   {
326     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
327     throw LauncherException("Cannot find the job, is it created ?");
328   }
329
330   it_job->second->stopJob();
331 }
332
333 //=============================================================================
334 /*! 
335  *  create a launcher job based on a file
336  *  \param xmlExecuteFile     : to define the execution on the batch cluster
337  */
338 //=============================================================================
339 long 
340 Launcher_cpp::createJobWithFile(const std::string xmlExecuteFile, 
341                                 const std::string clusterName)
342 {
343   LAUNCHER_MESSAGE("Begin of Launcher_cpp::createJobWithFile");
344
345   // Parsing xml file
346   ParserLauncherType job_params = ParseXmlFile(xmlExecuteFile);
347
348   // Creating a new job
349   Launcher::Job_Command * new_job = new Launcher::Job_Command();
350
351   std::string cmdFile = Kernel_Utils::GetTmpFileName();  
352 #ifndef WIN32
353   cmdFile += ".sh";
354 #else
355   cmdFile += ".bat";
356 #endif
357   std::ofstream os;
358   os.open(cmdFile.c_str(), std::ofstream::out );
359   os << "#! /bin/sh" << std::endl;
360   os << job_params.Command;
361   os.close();
362
363   new_job->setJobFile(cmdFile);
364   new_job->setLocalDirectory(job_params.RefDirectory);
365   new_job->setWorkDirectory(job_params.MachinesList[clusterName].WorkDirectory);
366   new_job->setEnvFile(job_params.MachinesList[clusterName].EnvFile);
367
368   for(int i=0; i < job_params.InputFile.size(); i++)
369     new_job->add_in_file(job_params.InputFile[i]);
370   for(int i=0; i < job_params.OutputFile.size();i++)
371     new_job->add_out_file(job_params.OutputFile[i]);
372
373   resourceParams p;
374   p.hostname = clusterName;
375   p.name = "";
376   p.OS = "";
377   p.nb_proc = job_params.NbOfProcesses;
378   p.nb_node = 0;
379   p.nb_proc_per_node = 0;
380   p.cpu_clock = 0;
381   p.mem_mb = 0;
382   new_job->setResourceRequiredParams(p);
383
384   createJob(new_job);
385   return new_job->getNumber();
386 }
387
388 //=============================================================================
389 /*!
390  *  Factory to instanciate the good batch manager for choosen cluster.
391  */ 
392 //=============================================================================
393 Batch::BatchManager *
394 Launcher_cpp::FactoryBatchManager(ParserResourcesType& params)
395 {
396   std::string mpi;
397   Batch::CommunicationProtocolType protocol;
398   Batch::FactBatchManager * fact;
399
400   std::string hostname = params.HostName;
401
402   switch(params.Protocol)
403   {
404     case sh:
405       protocol = Batch::SH;
406       break;
407     case rsh:
408       protocol = Batch::RSH;
409       break;
410     case ssh:
411       protocol = Batch::SSH;
412       break;
413     default:
414       throw LauncherException("Unknown protocol for this resource");
415       break;
416   }
417
418   switch(params.mpi)
419   {
420     case lam:
421       mpi = "lam";
422       break;
423     case mpich1:
424       mpi = "mpich1";
425       break;
426     case mpich2:
427       mpi = "mpich2";
428       break;
429     case openmpi:
430       mpi = "openmpi";
431       break;
432     case ompi:
433       mpi = "ompi";
434       break;
435     case slurmmpi:
436       mpi = "slurmmpi";
437       break;
438     case prun:
439       mpi = "prun";
440       break;
441     default:
442       mpi = "nompi";
443   }
444
445   const char * bmType;
446   switch( params.Batch )
447   {
448     case pbs:
449       bmType = "PBS";
450       break;
451     case lsf:
452       bmType = "LSF";
453       break;
454     case sge:
455       bmType = "SGE";
456       break;
457     case ccc:
458       bmType = "CCC";
459       break;
460     case slurm:
461       bmType = "SLURM";
462       break;
463     case none:
464       bmType = "LOCAL";
465       break;
466     case ll:
467       bmType = "LL";
468       break;
469     case vishnu:
470       bmType = "VISHNU";
471       break;
472     case oar:
473       bmType = "OAR";
474       break;
475     case coorm:
476       bmType = "COORM";
477       break;
478     default:
479       LAUNCHER_MESSAGE("Bad batch description of the resource: Batch = " << params.Batch);
480       throw LauncherException("No batchmanager for that cluster - Bad batch description of the resource");
481   }
482   Batch::BatchManagerCatalog & cata = Batch::BatchManagerCatalog::getInstance();
483   fact = dynamic_cast<Batch::FactBatchManager*>(cata(bmType));
484   if (fact == NULL) {
485     LAUNCHER_MESSAGE("Cannot find batch manager factory for " << bmType << ". Check your version of libBatch.");
486     throw LauncherException("Cannot find batch manager factory");
487   }
488   LAUNCHER_MESSAGE("Instanciation of batch manager of type: " << bmType);
489   Batch::BatchManager * batch_client = (*fact)(hostname.c_str(), params.UserName.c_str(),
490                                                protocol, mpi.c_str());
491   return batch_client;
492 }
493
494 //----------------------------------------------------------
495 // Without LIBBATCH - Launcher_cpp do nothing...
496 //----------------------------------------------------------
497 #else
498
499 void 
500 Launcher_cpp::createJob(Launcher::Job * new_job)
501 {
502   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot create a job !!!");
503   delete new_job;
504   throw LauncherException("Method Launcher_cpp::createJob is not available "
505                           "(libBatch was not present at compilation time)");
506 }
507
508 void 
509 Launcher_cpp::launchJob(int job_id)
510 {
511   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot launch a job !!!");
512   throw LauncherException("Method Launcher_cpp::launchJob is not available "
513                           "(libBatch was not present at compilation time)");
514 }
515
516 const char *
517 Launcher_cpp::getJobState(int job_id)
518 {
519   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job state!!!");
520   throw LauncherException("Method Launcher_cpp::getJobState is not available "
521                           "(libBatch was not present at compilation time)");
522 }
523
524 const char *
525 Launcher_cpp::getAssignedHostnames(int job_id)
526 {
527   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job assigned hostnames!!!");
528   throw LauncherException("Method Launcher_cpp::getAssignedHostnames is not available "
529                           "(libBatch was not present at compilation time)");
530 }
531
532 void
533 Launcher_cpp::getJobResults(int job_id, std::string directory)
534 {
535   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job results!!!");
536   throw LauncherException("Method Launcher_cpp::getJobResults is not available "
537                           "(libBatch was not present at compilation time)");
538 }
539
540 bool
541 Launcher_cpp::getJobDumpState(int job_id, std::string directory)
542 {
543   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job dump state!!!");
544   throw LauncherException("Method Launcher_cpp::getJobDumpState is not available "
545                           "(libBatch was not present at compilation time)");
546 }
547
548 void
549 Launcher_cpp::removeJob(int job_id)
550 {
551   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot remove job!!!");
552   throw LauncherException("Method Launcher_cpp::removeJob is not available "
553                           "(libBatch was not present at compilation time)");
554 }
555
556 void
557 Launcher_cpp::stopJob(int job_id)
558 {
559   throw LauncherException("Method Launcher_cpp::stopJob is not available "
560                           "(libBatch was not present at compilation time)");
561 }
562
563 long 
564 Launcher_cpp::createJobWithFile( const std::string xmlExecuteFile, std::string clusterName)
565 {
566   throw LauncherException("Method Launcher_cpp::createJobWithFile is not available "
567                           "(libBatch was not present at compilation time)");
568   return 0;
569 }
570
571 #endif
572
573 ParserLauncherType 
574 Launcher_cpp::ParseXmlFile(std::string xmlExecuteFile)
575 {
576   ParserLauncherType job_params;
577   SALOME_Launcher_Handler * handler = new SALOME_Launcher_Handler(job_params);
578
579   const char* aFilePath = xmlExecuteFile.c_str();
580   FILE* aFile = fopen(aFilePath, "r");
581   if (aFile != NULL)
582   {
583     xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
584     if (aDoc != NULL)
585       handler->ProcessXmlDocument(aDoc);
586     else
587     {
588       std::string message = "ResourcesManager_cpp: could not parse file: " + xmlExecuteFile;
589       LAUNCHER_MESSAGE(message);
590       delete handler;
591       throw LauncherException(message);
592     }
593     // Free the document
594     xmlFreeDoc(aDoc);
595     fclose(aFile);
596   }
597   else
598   {
599     std::string message = "ResourcesManager_cpp: file is not readable: " + xmlExecuteFile;
600     LAUNCHER_MESSAGE(message);
601     delete handler;
602     throw LauncherException(message);
603   }
604
605   // Return
606   delete handler;
607   return job_params;
608 }
609
610 std::map<int, Launcher::Job *>
611 Launcher_cpp::getJobs()
612 {
613   return _launcher_job_map;
614 }
615
616 void 
617 Launcher_cpp::createBatchManagerForJob(Launcher::Job * job)
618 {
619   int job_id = job->getNumber();
620
621   // Select a ressource for the job
622   std::vector<std::string> ResourceList;
623   resourceParams params = job->getResourceRequiredParams();
624   // Consider only resources that can launch batch jobs
625   params.can_launch_batch_jobs = true;
626   try
627   {
628     ResourceList = _ResManager->GetFittingResources(params);
629   }
630   catch(const ResourcesException &ex)
631   {
632     throw LauncherException(ex.msg.c_str());
633   }
634   if (ResourceList.size() == 0)
635   {
636     LAUNCHER_INFOS("No adequate resource found for the job, number " << job->getNumber());
637     job->setState("ERROR");
638     throw LauncherException("No resource found the job");
639   }
640
641   // Configure the job with the resource selected - the first of the list
642   ParserResourcesType resource_definition = _ResManager->GetResourcesDescr(ResourceList[0]);
643
644   // Set resource definition to the job
645   // The job will check if the definitions needed
646   try
647   {
648     job->setResourceDefinition(resource_definition);
649   }
650   catch(const LauncherException &ex)
651   {
652     LAUNCHER_INFOS("Error in the definition of the resource, mess: " << ex.msg);
653     job->setState("ERROR");
654     throw ex;
655   }
656
657   // Step 2: We can now add a Factory if the resource is correctly define
658 #ifdef WITH_LIBBATCH
659   std::map<int, Batch::BatchManager *>::const_iterator it = _batchmap.find(job_id);
660   if(it == _batchmap.end())
661   {
662     try
663     {
664       // Warning cannot write on one line like this, because map object is constructed before
665       // the method is called...
666       //_batchmap[job_id] = FactoryBatchManager(resource_definition);
667       Batch::BatchManager * batch_client = FactoryBatchManager(resource_definition);
668       _batchmap[job_id] = batch_client;
669     }
670     catch(const LauncherException &ex)
671     {
672       LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.msg);
673       throw ex;
674     }
675     catch(const Batch::GenericException &ex)
676     {
677       LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.message);
678       throw LauncherException(ex.message);
679     }
680   }
681 #endif
682 }
683
684 void 
685 Launcher_cpp::addJobDirectlyToMap(Launcher::Job * new_job)
686 {
687   // Step 0: Calculated job_id
688   pthread_mutex_lock(_job_cpt_mutex);
689   int job_id = _job_cpt;
690   _job_cpt++;
691   new_job->setNumber(job_id);
692   pthread_mutex_unlock(_job_cpt_mutex);
693
694   // Step 1: check if resource is already in the map
695   createBatchManagerForJob(new_job);
696
697   // Step 2: add the job to the batch manager
698 #ifdef WITH_LIBBATCH
699   try
700   {
701     Batch::JobId batch_manager_job_id = _batchmap[job_id]->addJob(*(new_job->getBatchJob()),
702                                                                   new_job->getReference());
703     new_job->setBatchManagerJobId(batch_manager_job_id);
704   }
705   catch(const Batch::GenericException &ex)
706   {
707     LAUNCHER_INFOS("Job cannot be added, exception in addJob: " << ex.message);
708     throw LauncherException(ex.message.c_str());
709   }
710
711   // Step 3: add job to launcher map
712   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(new_job->getNumber());
713   if (it_job == _launcher_job_map.end())
714     _launcher_job_map[new_job->getNumber()] = new_job;
715   else
716   {
717     LAUNCHER_INFOS("A job as already the same id: " << new_job->getNumber());
718     delete new_job;
719     throw LauncherException("A job as already the same id - job is not created !");
720   }
721   LAUNCHER_MESSAGE("New job added");
722 #endif
723 }
724
725 list<int>
726 Launcher_cpp::loadJobs(const char* jobs_file)
727 {
728   list<int> new_jobs_id_list;
729
730   // Load the jobs from XML file
731   list<Launcher::Job *> jobs_list = Launcher::XML_Persistence::loadJobs(jobs_file);
732
733   // Create each job in the launcher
734   list<Launcher::Job *>::const_iterator it_job;
735   for (it_job = jobs_list.begin(); it_job != jobs_list.end(); it_job++)
736   {
737     Launcher::Job * new_job = *it_job;
738     string job_state = new_job->getState();
739
740     try
741     {
742       if (job_state == "CREATED")
743       {
744         // In this case, we ignore run_part informations
745         createJob(new_job);
746         new_jobs_id_list.push_back(new_job->getNumber());
747       }
748       else if (job_state == "QUEUED"     ||
749                job_state == "RUNNING"    ||
750                job_state == "IN_PROCESS" ||
751                job_state == "PAUSED")
752       {
753         addJobDirectlyToMap(new_job);
754         new_jobs_id_list.push_back(new_job->getNumber());
755
756         // Step 4: We check that the BatchManager could resume
757         // the job
758 #ifdef WITH_LIBBATCH
759         if (new_job->getBatchManagerJobId().getReference() != new_job->getReference())
760         {
761           LAUNCHER_INFOS("BatchManager type cannot resume a job - job state is set to ERROR");
762           new_job->setState("ERROR");
763         }
764 #endif
765       }
766       else if (job_state == "FINISHED" ||
767                job_state == "FAILED"   ||
768                job_state == "ERROR")
769       {
770         // Step 2: We add run_part informations
771         addJobDirectlyToMap(new_job);
772         new_jobs_id_list.push_back(new_job->getNumber());
773       }
774       else
775       {
776         LAUNCHER_INFOS("A bad job is found, state unknown " << job_state);
777         delete new_job;
778       }
779     }
780     catch(const LauncherException &ex)
781     {
782       LAUNCHER_INFOS("Cannot load the job. Exception: " << ex.msg.c_str());
783       delete new_job;
784     }
785   }
786
787   return new_jobs_id_list;
788 }
789
790 void
791 Launcher_cpp::saveJobs(const char* jobs_file)
792 {
793   // Create a sorted list from the internal job map
794   list<const Launcher::Job *> jobs_list;
795   for (int i=0; i<_job_cpt; i++)
796   {
797     map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(i);
798     if (it_job != _launcher_job_map.end())
799       jobs_list.push_back(it_job->second);
800   }
801
802   // Save the jobs in XML file
803   Launcher::XML_Persistence::saveJobs(jobs_file, jobs_list);
804 }