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