Salome HOME
Remove trailing white spaces.
[modules/kernel.git] / src / Launcher / Launcher.cxx
1 // Copyright (C) 2007-2019  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 #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 //=============================================================================
259 /*!
260  * Get Job result - the result directory could be changed
261  */
262 //=============================================================================
263 void
264 Launcher_cpp::getJobResults(int job_id, std::string directory)
265 {
266   LAUNCHER_MESSAGE("Get Job results");
267
268   Launcher::Job * job = findJob(job_id);
269   std::string resource_name = job->getResourceDefinition().Name;
270   try
271   {
272     if (directory != "")
273       _batchmap[job_id]->importOutputFiles(*(job->getBatchJob()), directory);
274     else
275       _batchmap[job_id]->importOutputFiles(*(job->getBatchJob()), job->getResultDirectory());
276   }
277   catch(const Batch::GenericException &ex)
278   {
279     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
280     throw LauncherException(ex.message.c_str());
281   }
282   LAUNCHER_MESSAGE("getJobResult ended");
283 }
284
285 //=============================================================================
286 /*!
287  * Clear the remote working directory
288  */
289 //=============================================================================
290 void
291 Launcher_cpp::clearJobWorkingDir(int job_id)
292 {
293   LAUNCHER_MESSAGE("Clear the remote working directory");
294
295   Launcher::Job * job = findJob(job_id);
296   try
297   {
298     _batchmap[job_id]->clearWorkingDir(*(job->getBatchJob()));
299   }
300   catch(const Batch::GenericException &ex)
301   {
302     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
303     throw LauncherException(ex.message.c_str());
304   }
305   LAUNCHER_MESSAGE("getJobResult ended");
306 }
307
308 //=============================================================================
309 /*!
310  * Get Job dump state - the result directory could be changed
311  */
312 //=============================================================================
313 bool
314 Launcher_cpp::getJobDumpState(int job_id, std::string directory)
315 {
316   bool rtn;
317   LAUNCHER_MESSAGE("Get Job dump state");
318
319   Launcher::Job * job = findJob(job_id);
320   std::string resource_name = job->getResourceDefinition().Name;
321   try
322   {
323     if (directory != "")
324       rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), directory);
325     else
326       rtn = _batchmap[job_id]->importDumpStateFile(*(job->getBatchJob()), job->getResultDirectory());
327   }
328   catch(const Batch::GenericException &ex)
329   {
330     LAUNCHER_INFOS("getJobResult is maybe incomplete, exception: " << ex.message);
331     throw LauncherException(ex.message.c_str());
332   }
333   LAUNCHER_MESSAGE("getJobResult ended");
334   return rtn;
335 }
336
337 //=============================================================================
338 /*!
339  * Get one file from the working directory - the result directory can be changed
340  */
341 //=============================================================================
342 bool
343 Launcher_cpp::getJobWorkFile(int job_id,
344                              std::string work_file,
345                              std::string directory)
346 {
347   bool rtn;
348   LAUNCHER_MESSAGE("Get working file " << work_file);
349
350   Launcher::Job * job = findJob(job_id);
351   std::string resource_name = job->getResourceDefinition().Name;
352   try
353   {
354     if (directory != "")
355       rtn = _batchmap[job_id]->importWorkFile(*(job->getBatchJob()), work_file, directory);
356     else
357       rtn = _batchmap[job_id]->importWorkFile(*(job->getBatchJob()), work_file, job->getResultDirectory());
358   }
359   catch(const Batch::GenericException &ex)
360   {
361     LAUNCHER_INFOS("getJobWorkFile is maybe incomplete, exception: " << ex.message);
362     throw LauncherException(ex.message.c_str());
363   }
364   LAUNCHER_MESSAGE("getJobWorkFile ended");
365   return rtn;
366 }
367
368 //=============================================================================
369 /*!
370  * Remove the job - into the Launcher and its batch manager
371  */
372 //=============================================================================
373 void
374 Launcher_cpp::removeJob(int job_id)
375 {
376   LAUNCHER_MESSAGE("Remove Job");
377
378   // Check if job exist
379   std::map<int, Launcher::Job *>::iterator it_job = _launcher_job_map.find(job_id);
380   if (it_job == _launcher_job_map.end())
381   {
382     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
383     throw LauncherException("Cannot find the job, is it created ?");
384   }
385
386   it_job->second->removeJob();
387   delete it_job->second;
388   _launcher_job_map.erase(it_job);
389 }
390
391 //=============================================================================
392 /*!
393  * stop the job
394  */
395 //=============================================================================
396 void
397 Launcher_cpp::stopJob(int job_id)
398 {
399   LAUNCHER_MESSAGE("Stop Job");
400
401   Launcher::Job * job = findJob(job_id);
402   job->stopJob();
403 }
404
405 std::string
406 Launcher_cpp::dumpJob(int job_id)
407 {
408   LAUNCHER_MESSAGE("dump Job");
409
410   Launcher::Job * job = findJob(job_id);
411   return Launcher::XML_Persistence::dumpJob(*job);
412 }
413
414 int
415 Launcher_cpp::restoreJob(const std::string& dumpedJob)
416 {
417   LAUNCHER_MESSAGE("restore Job");
418   Launcher::Job* new_job(nullptr);
419   int jobId = -1;
420   try
421   {
422     {
423       new_job = Launcher::XML_Persistence::createJobFromString(dumpedJob);
424     }
425     if(new_job)
426     {
427       jobId = addJob(new_job);
428     }
429     else
430       LAUNCHER_INFOS("Failed to create a new job.");
431   }
432   catch(const LauncherException &ex)
433   {
434     LAUNCHER_INFOS("Cannot load the job. Exception: " << ex.msg.c_str());
435   }
436   return jobId;
437 }
438
439 JobParameters_cpp
440 Launcher_cpp::getJobParameters(int job_id)
441 {
442   Launcher::Job * job = findJob(job_id);
443   JobParameters_cpp job_parameters;
444   job_parameters.job_name         = job->getJobName();
445   job_parameters.job_type         = job->getJobType();
446   job_parameters.job_file         = job->getJobFile();
447   job_parameters.env_file         = job->getEnvFile();
448   job_parameters.work_directory   = job->getWorkDirectory();
449   job_parameters.local_directory  = job->getLocalDirectory();
450   job_parameters.result_directory = job->getResultDirectory();
451   job_parameters.pre_command      = job->getPreCommand();
452
453   // Parameters for COORM
454   job_parameters.launcher_file = job->getLauncherFile();
455   job_parameters.launcher_args = job->getLauncherArgs();
456
457   job_parameters.in_files      = job->get_in_files();
458   job_parameters.out_files     = job->get_out_files();
459
460   job_parameters.maximum_duration = job->getMaximumDuration();
461   job_parameters.queue            = job->getQueue();
462   job_parameters.partition        = job->getPartition();
463   job_parameters.exclusive        = job->getExclusive();
464   job_parameters.mem_per_cpu      = job->getMemPerCpu();
465   job_parameters.wckey            = job->getWCKey();
466   job_parameters.extra_params     = job->getExtraParams();
467
468   resourceParams resource_params = job->getResourceRequiredParams();
469   job_parameters.resource_required.name             = resource_params.name;
470   job_parameters.resource_required.hostname         = resource_params.hostname;
471   job_parameters.resource_required.OS               = resource_params.OS;
472   job_parameters.resource_required.nb_proc          = resource_params.nb_proc;
473   job_parameters.resource_required.nb_node          = resource_params.nb_node;
474   job_parameters.resource_required.nb_proc_per_node = resource_params.nb_proc_per_node;
475   job_parameters.resource_required.cpu_clock        = resource_params.cpu_clock;
476   job_parameters.resource_required.mem_mb           = resource_params.mem_mb;
477
478   job_parameters.specific_parameters                = job->getSpecificParameters();
479
480   return job_parameters;
481 }
482
483 //=============================================================================
484 /*!
485  *  create a launcher job based on a file
486  *  \param xmlExecuteFile     : to define the execution on the batch cluster
487  */
488 //=============================================================================
489 long
490 Launcher_cpp::createJobWithFile(const std::string xmlExecuteFile,
491                                 const std::string clusterName)
492 {
493   LAUNCHER_MESSAGE("Begin of Launcher_cpp::createJobWithFile");
494
495   // Parsing xml file
496   ParserLauncherType job_params = ParseXmlFile(xmlExecuteFile);
497
498   // Creating a new job
499   std::unique_ptr<Launcher::Job_Command> new_job(new Launcher::Job_Command);
500
501   std::string cmdFile = Kernel_Utils::GetTmpFileName();
502 #ifndef WIN32
503   cmdFile += ".sh";
504 #else
505   cmdFile += ".bat";
506 #endif
507   std::ofstream os;
508   os.open(cmdFile.c_str(), std::ofstream::out );
509   os << "#! /bin/sh" << std::endl;
510   os << job_params.Command;
511   os.close();
512
513   new_job->setJobFile(cmdFile);
514   new_job->setLocalDirectory(job_params.RefDirectory);
515   new_job->setWorkDirectory(job_params.MachinesList[clusterName].WorkDirectory);
516   new_job->setEnvFile(job_params.MachinesList[clusterName].EnvFile);
517
518   for(int i=0; i < job_params.InputFile.size(); i++)
519     new_job->add_in_file(job_params.InputFile[i]);
520   for(int i=0; i < job_params.OutputFile.size();i++)
521     new_job->add_out_file(job_params.OutputFile[i]);
522
523   resourceParams p;
524   p.hostname = clusterName;
525   p.name = "";
526   p.OS = "";
527   p.nb_proc = job_params.NbOfProcesses;
528   p.nb_node = 0;
529   p.nb_proc_per_node = 0;
530   p.cpu_clock = 0;
531   p.mem_mb = 0;
532   new_job->setResourceRequiredParams(p);
533
534   createJob(new_job.get());
535   return new_job->getNumber();
536 }
537
538 //=============================================================================
539 /*!
540  *  Factory to instantiate the good batch manager for chosen cluster.
541  */
542 //=============================================================================
543 Batch::BatchManager *
544 Launcher_cpp::FactoryBatchManager(ParserResourcesType& params)
545 {
546   std::string mpi;
547   Batch::CommunicationProtocolType protocol;
548   Batch::FactBatchManager * fact;
549
550   std::string hostname = params.HostName;
551
552   switch(params.Protocol)
553   {
554     case sh:
555       protocol = Batch::SH;
556       break;
557     case rsh:
558       protocol = Batch::RSH;
559       break;
560     case ssh:
561       protocol = Batch::SSH;
562       break;
563     case rsync:
564       protocol = Batch::RSYNC;
565       break;
566     default:
567       throw LauncherException("Unknown protocol for this resource");
568       break;
569   }
570
571   switch(params.mpi)
572   {
573     case lam:
574       mpi = "lam";
575       break;
576     case mpich1:
577       mpi = "mpich1";
578       break;
579     case mpich2:
580       mpi = "mpich2";
581       break;
582     case openmpi:
583       mpi = "openmpi";
584       break;
585     case ompi:
586       mpi = "ompi";
587       break;
588     case slurmmpi:
589       mpi = "slurmmpi";
590       break;
591     case prun:
592       mpi = "prun";
593       break;
594     default:
595       mpi = "nompi";
596   }
597
598   const char * bmType;
599   switch( params.Batch )
600   {
601     case pbs:
602       bmType = "PBS";
603       break;
604     case lsf:
605       bmType = "LSF";
606       break;
607     case sge:
608       bmType = "SGE";
609       break;
610     case ccc:
611       bmType = "CCC";
612       break;
613     case slurm:
614       bmType = "SLURM";
615       break;
616     case none:
617       bmType = "LOCAL";
618       break;
619     case ll:
620       bmType = "LL";
621       break;
622     case vishnu:
623       bmType = "VISHNU";
624       break;
625     case oar:
626       bmType = "OAR";
627       break;
628     case coorm:
629       bmType = "COORM";
630       break;
631     default:
632       LAUNCHER_MESSAGE("Bad batch description of the resource: Batch = " << params.Batch);
633       throw LauncherException("No batchmanager for that cluster - Bad batch description of the resource");
634   }
635   Batch::BatchManagerCatalog & cata = Batch::BatchManagerCatalog::getInstance();
636   fact = dynamic_cast<Batch::FactBatchManager*>(cata(bmType));
637   if (fact == NULL) {
638     LAUNCHER_MESSAGE("Cannot find batch manager factory for " << bmType << ". Check your version of libBatch.");
639     throw LauncherException("Cannot find batch manager factory");
640   }
641   LAUNCHER_MESSAGE("Instantiation of batch manager of type: " << bmType);
642   Batch::BatchManager * batch_client = (*fact)(hostname.c_str(), params.UserName.c_str(),
643                                                protocol, mpi.c_str());
644   return batch_client;
645 }
646
647 //----------------------------------------------------------
648 // Without LIBBATCH - Launcher_cpp do nothing...
649 //----------------------------------------------------------
650 #else
651
652 void
653 Launcher_cpp::createJob(Launcher::Job * new_job)
654 {
655   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot create a job !!!");
656   throw LauncherException("Method Launcher_cpp::createJob is not available "
657                           "(libBatch was not present at compilation time)");
658 }
659
660 int
661 Launcher_cpp::createJob(const JobParameters_cpp& job_parameters)
662 {
663   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot create a job !!!");
664   throw LauncherException("Method Launcher_cpp::createJob is not available "
665                           "(libBatch was not present at compilation time)");
666 }
667
668 void
669 Launcher_cpp::launchJob(int job_id)
670 {
671   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot launch a job !!!");
672   throw LauncherException("Method Launcher_cpp::launchJob is not available "
673                           "(libBatch was not present at compilation time)");
674 }
675
676 std::string
677 Launcher_cpp::getJobState(int job_id)
678 {
679   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job state!!!");
680   throw LauncherException("Method Launcher_cpp::getJobState is not available "
681                           "(libBatch was not present at compilation time)");
682 }
683
684 std::string
685 Launcher_cpp::getAssignedHostnames(int job_id)
686 {
687   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job assigned hostnames!!!");
688   throw LauncherException("Method Launcher_cpp::getAssignedHostnames is not available "
689                           "(libBatch was not present at compilation time)");
690 }
691
692 void
693 Launcher_cpp::getJobResults(int job_id, std::string directory)
694 {
695   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job results!!!");
696   throw LauncherException("Method Launcher_cpp::getJobResults is not available "
697                           "(libBatch was not present at compilation time)");
698 }
699
700 void
701 Launcher_cpp::clearJobWorkingDir(int job_id)
702 {
703   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot clear directory!!!");
704   throw LauncherException("Method Launcher_cpp::clearJobWorkingDir is not available "
705                           "(libBatch was not present at compilation time)");
706 }
707
708 bool
709 Launcher_cpp::getJobDumpState(int job_id, std::string directory)
710 {
711   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job dump state!!!");
712   throw LauncherException("Method Launcher_cpp::getJobDumpState is not available "
713                           "(libBatch was not present at compilation time)");
714 }
715
716 bool
717 Launcher_cpp::getJobWorkFile(int job_id, std::string work_file, std::string directory)
718 {
719   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot get job dump state!!!");
720   throw LauncherException("Method Launcher_cpp::getJobWorkFile is not available "
721                           "(libBatch was not present at compilation time)");
722 }
723
724 void
725 Launcher_cpp::removeJob(int job_id)
726 {
727   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot remove job!!!");
728   throw LauncherException("Method Launcher_cpp::removeJob is not available "
729                           "(libBatch was not present at compilation time)");
730 }
731
732 void
733 Launcher_cpp::stopJob(int job_id)
734 {
735   throw LauncherException("Method Launcher_cpp::stopJob is not available "
736                           "(libBatch was not present at compilation time)");
737 }
738
739 std::string
740 Launcher_cpp::dumpJob(int job_id)
741 {
742   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot dump job!!!");
743   throw LauncherException("Method Launcher_cpp::dumpJob is not available "
744                           "(libBatch was not present at compilation time)");
745   return "";
746 }
747
748 int
749 Launcher_cpp::restoreJob(const std::string& dumpedJob)
750 {
751   LAUNCHER_INFOS("Launcher compiled without LIBBATCH - cannot restore job!!!");
752   throw LauncherException("Method Launcher_cpp::restoreJob is not available "
753                           "(libBatch was not present at compilation time)");
754   return 0;
755 }
756
757 long
758 Launcher_cpp::createJobWithFile( const std::string xmlExecuteFile, std::string clusterName)
759 {
760   throw LauncherException("Method Launcher_cpp::createJobWithFile is not available "
761                           "(libBatch was not present at compilation time)");
762   return 0;
763 }
764
765 #endif
766
767 ParserLauncherType
768 Launcher_cpp::ParseXmlFile(std::string xmlExecuteFile)
769 {
770   ParserLauncherType job_params;
771   SALOME_Launcher_Handler * handler = new SALOME_Launcher_Handler(job_params);
772
773   const char* aFilePath = xmlExecuteFile.c_str();
774   FILE* aFile = fopen(aFilePath, "r");
775   if (aFile != NULL)
776   {
777     xmlDocPtr aDoc = xmlReadFile(aFilePath, NULL, 0);
778     if (aDoc != NULL)
779       handler->ProcessXmlDocument(aDoc);
780     else
781     {
782       std::string message = "ResourcesManager_cpp: could not parse file: " + xmlExecuteFile;
783       LAUNCHER_MESSAGE(message);
784       delete handler;
785       throw LauncherException(message);
786     }
787     // Free the document
788     xmlFreeDoc(aDoc);
789     fclose(aFile);
790   }
791   else
792   {
793     std::string message = "ResourcesManager_cpp: file is not readable: " + xmlExecuteFile;
794     LAUNCHER_MESSAGE(message);
795     delete handler;
796     throw LauncherException(message);
797   }
798
799   // Return
800   delete handler;
801   return job_params;
802 }
803
804 std::map<int, Launcher::Job *>
805 Launcher_cpp::getJobs()
806 {
807   return _launcher_job_map;
808 }
809
810 #ifdef WITH_LIBBATCH
811 Batch::BatchManager*
812 Launcher_cpp::getBatchManager(Launcher::Job * job)
813 {
814   if(!_ResManager)
815     throw LauncherException("Resource manager is not set.");
816
817   Batch::BatchManager* result = nullptr;
818   int job_id = job->getNumber();
819
820   // Select a resource for the job
821   std::vector<std::string> ResourceList;
822   resourceParams params = job->getResourceRequiredParams();
823   // Consider only resources that can launch batch jobs
824   params.can_launch_batch_jobs = true;
825   try
826   {
827     ResourceList = _ResManager->GetFittingResources(params);
828   }
829   catch(const ResourcesException &ex)
830   {
831     throw LauncherException(ex.msg.c_str());
832   }
833   if (ResourceList.size() == 0)
834   {
835     LAUNCHER_INFOS("No adequate resource found for the job, number " << job->getNumber());
836     job->setState("ERROR");
837     throw LauncherException("No resource found the job");
838   }
839
840   // Configure the job with the resource selected - the first of the list
841   ParserResourcesType resource_definition = _ResManager->GetResourcesDescr(ResourceList[0]);
842
843   // Set resource definition to the job
844   // The job will check if the definitions needed
845   try
846   {
847     job->setResourceDefinition(resource_definition);
848   }
849   catch(const LauncherException &ex)
850   {
851     LAUNCHER_INFOS("Error in the definition of the resource, mess: " << ex.msg);
852     job->setState("ERROR");
853     throw ex;
854   }
855
856   // Step 2: We can now add a Factory if the resource is correctly define
857   std::map<int, Batch::BatchManager *>::const_iterator it = _batchmap.find(job_id);
858   if(it == _batchmap.end())
859   {
860     try
861     {
862       // Warning cannot write on one line like this, because map object is constructed before
863       // the method is called...
864       //_batchmap[job_id] = FactoryBatchManager(resource_definition);
865       result = FactoryBatchManager(resource_definition);
866       _batchmap[job_id] = result;
867     }
868     catch(const LauncherException &ex)
869     {
870       LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.msg);
871       throw ex;
872     }
873     catch(const Batch::GenericException &ex)
874     {
875       LAUNCHER_INFOS("Error during creation of the batch manager of the job, mess: " << ex.message);
876       throw LauncherException(ex.message);
877     }
878   }
879   else
880     result = it->second;
881   return result;
882 }
883 #endif
884
885 void
886 Launcher_cpp::addJobDirectlyToMap(Launcher::Job * new_job)
887 {
888   // Step 0: Calculated job_id
889   new_job->setNumber(_job_cpt);
890   _job_cpt++;
891
892 #ifdef WITH_LIBBATCH
893   // Step 1: check if resource is already in the map
894   Batch::BatchManager * bm = getBatchManager(new_job);
895
896   // Step 2: add the job to the batch manager
897   try
898   {
899     Batch::JobId batch_manager_job_id = bm->addJob(*(new_job->getBatchJob()),
900                                                    new_job->getReference());
901     new_job->setBatchManagerJobId(batch_manager_job_id);
902   }
903   catch(const Batch::GenericException &ex)
904   {
905     LAUNCHER_INFOS("Job cannot be added, exception in addJob: " << ex.message);
906     throw LauncherException(ex.message.c_str());
907   }
908
909   // Step 3: add job to launcher map
910   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(new_job->getNumber());
911   if (it_job == _launcher_job_map.end())
912   {
913     _launcher_job_map[new_job->getNumber()] = new_job;
914   }
915   else
916   {
917     LAUNCHER_INFOS("A job as already the same id: " << new_job->getNumber());
918     throw LauncherException("A job as already the same id - job is not created !");
919   }
920   LAUNCHER_MESSAGE("New job added");
921 #endif
922 }
923
924 int
925 Launcher_cpp::addJob(Launcher::Job * new_job)
926 {
927   string job_state = new_job->getState();
928   int jobId = -1;
929   if (job_state == "CREATED")
930   {
931     // In this case, we ignore run_part information
932     createJob(new_job);
933     jobId = new_job->getNumber();
934   }
935   else if (job_state == "QUEUED"     ||
936             job_state == "RUNNING"    ||
937             job_state == "IN_PROCESS" ||
938             job_state == "PAUSED")
939   {
940     addJobDirectlyToMap(new_job);
941     jobId = new_job->getNumber();
942
943     // We check that the BatchManager could resume the job
944 #ifdef WITH_LIBBATCH
945     if (new_job->getBatchManagerJobId().getReference() != new_job->getReference())
946     {
947       LAUNCHER_INFOS("BatchManager type cannot resume a job - job state is set to ERROR");
948       new_job->setState("ERROR");
949     }
950 #endif
951   }
952   else if (job_state == "FINISHED" ||
953             job_state == "FAILED"   ||
954             job_state == "ERROR")
955   {
956     // We add run_part information
957     addJobDirectlyToMap(new_job);
958     jobId = new_job->getNumber();
959   }
960   else
961   {
962     LAUNCHER_INFOS("A bad job is found, state unknown " << job_state);
963     jobId = -1;
964   }
965   return jobId;
966 }
967
968 list<int>
969 Launcher_cpp::loadJobs(const char* jobs_file)
970 {
971   list<int> new_jobs_id_list;
972
973   // Load the jobs from XML file
974   list<Launcher::Job *> jobs_list = Launcher::XML_Persistence::loadJobs(jobs_file);
975
976   // Create each job in the launcher
977   list<Launcher::Job *>::const_iterator it_job;
978   for (it_job = jobs_list.begin(); it_job != jobs_list.end(); it_job++)
979   {
980     Launcher::Job* new_job(*it_job);
981     int jobId = -1;
982     try
983     {
984       jobId = addJob(new_job);
985       if(jobId >= 0)
986         new_jobs_id_list.push_back(jobId);
987     }
988     catch(const LauncherException &ex)
989     {
990       LAUNCHER_INFOS("Cannot load the job. Exception: " << ex.msg.c_str());
991     }
992   }
993
994   return new_jobs_id_list;
995 }
996
997 void
998 Launcher_cpp::saveJobs(const char* jobs_file)
999 {
1000   // Create a sorted list from the internal job map
1001   list<const Launcher::Job *> jobs_list;
1002   {
1003     for (int i=0; i<_job_cpt; i++)
1004     {
1005       map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(i);
1006       if (it_job != _launcher_job_map.end())
1007         jobs_list.push_back(it_job->second);
1008     }
1009   }
1010   // Save the jobs in XML file
1011   Launcher::XML_Persistence::saveJobs(jobs_file, jobs_list);
1012 }
1013
1014 Launcher::Job *
1015 Launcher_cpp::findJob(int job_id)
1016 {
1017   std::map<int, Launcher::Job *>::const_iterator it_job = _launcher_job_map.find(job_id);
1018   if (it_job == _launcher_job_map.end())
1019   {
1020     LAUNCHER_INFOS("Cannot find the job, is it created ? job number: " << job_id);
1021     throw LauncherException("Cannot find the job, is it created ?");
1022   }
1023   Launcher::Job * job = it_job->second;
1024   return job;
1025 }