Salome HOME
273c51737bc815fb8542c89ad42f14faf066ebe5
[modules/jobmanager.git] / src / engine / BL_SALOMEServices.cxx
1 // Copyright (C) 2009-2012  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "BL_SALOMEServices.hxx"
21 #include <sstream>
22
23 static std::ostream & 
24 operator<<(std::ostream & os, const CORBA::Exception & e)
25 {
26   CORBA::Any tmp;
27   tmp <<=e ;
28   CORBA::TypeCode_var tc = tmp.type();
29   const char * p = tc->name ();
30   if (*p != '\0')
31     os << p;
32   else
33     os << tc->id();
34   return os;
35 }
36
37 BL::SALOMEServices::SALOMEServices()
38 {
39   int nbargs = 0; char **args = 0;
40   _orb = CORBA::ORB_init (nbargs, args);
41   _salome_naming_service = NULL;
42   _lcc = NULL;
43   _state = false;
44   _manager = NULL;
45 }
46
47 BL::SALOMEServices::~SALOMEServices() {}
48
49 void
50 BL::SALOMEServices::end()
51 {
52   if (!CORBA::is_nil(_salome_launcher))
53     _salome_launcher->removeObserver(_this());
54   if (_salome_naming_service)
55     delete _salome_naming_service;
56   if (_lcc)
57     delete _lcc;
58 }
59
60 bool
61 BL::SALOMEServices::initNS()
62 {
63   bool return_value = true;
64   _salome_naming_service = new SALOME_NamingService(_orb);
65   _lcc = new SALOME_LifeCycleCORBA(_salome_naming_service);
66   CORBA::Object_var obj = _salome_naming_service->Resolve("/SalomeLauncher");
67   _salome_launcher = Engines::SalomeLauncher::_narrow(obj);
68
69   if (CORBA::is_nil(_salome_launcher))
70   {
71     DEBMSG("SALOME Launcher is not reachable!")
72     return_value = false;
73   }
74   _salome_launcher->addObserver(_this());
75   _remove_ref(); // POA will automatically destroy the object
76
77   obj = _salome_naming_service->Resolve("/ResourcesManager");
78   _resources_manager = Engines::ResourcesManager::_narrow(obj);
79   if (CORBA::is_nil(_resources_manager))
80   {
81     DEBMSG("SALOME Resource Manager is not reachable !");
82     return_value = false;
83   }
84
85   _state = return_value;
86   return return_value;
87 }
88
89 std::list<std::string> 
90 BL::SALOMEServices::getResourceList()
91 {
92   std::list<std::string> resource_list;
93   
94   if (_state)
95   {
96     Engines::ResourceParameters params;
97     _lcc->preSet(params);
98     Engines::ResourceList * resourceList = NULL;
99     try
100     {
101       resourceList = _resources_manager->GetFittingResources(params);
102     }
103     catch (const SALOME::SALOME_Exception & ex)
104     {
105       DEBMSG("SALOME Exception in addResource ! " << ex.details.text.in());
106     }
107     catch (const CORBA::SystemException& ex)
108     {
109       DEBMSG("Receive SALOME System Exception: " << ex);
110       DEBMSG("Check SALOME servers...");
111     }
112     if (resourceList)
113     {
114       for (int i = 0; i < resourceList->length(); i++)
115       {
116         const char* aResource = (*resourceList)[i];
117         resource_list.push_back(aResource);
118       }
119       delete resourceList;
120     }
121   }
122   return resource_list;
123 }
124
125 BL::ResourceDescr
126 BL::SALOMEServices::getResourceDescr(const std::string& name)
127 {
128   Engines::ResourceDefinition * resource_definition = NULL;
129   BL::ResourceDescr resource_descr;
130
131   try 
132   {
133     resource_definition = _resources_manager-> GetResourceDefinition(name.c_str());
134   }
135   catch (const SALOME::SALOME_Exception & ex)
136   {
137     DEBMSG("SALOME Exception in addResource ! " << ex.details.text.in());
138   }
139   catch (const CORBA::SystemException& ex)
140   {
141     DEBMSG("Receive SALOME System Exception: " << ex);
142     DEBMSG("Check SALOME servers...");
143   }
144
145   if(resource_definition)
146   {
147     resource_descr.name = resource_definition->name.in();
148     resource_descr.hostname = resource_definition->hostname.in();
149     resource_descr.protocol = resource_definition->protocol.in();
150     resource_descr.username = resource_definition->username.in();
151     resource_descr.applipath = resource_definition->applipath.in();
152     for (int i = 0; i < resource_definition->componentList.length(); i++)
153     {
154       resource_descr.componentList.push_back(resource_definition->componentList[i].in());
155     }
156
157     resource_descr.OS = resource_definition->OS.in();
158     resource_descr.mem_mb = resource_definition->mem_mb;
159     resource_descr.cpu_clock = resource_definition->cpu_clock;
160     resource_descr.nb_node = resource_definition->nb_node;
161     resource_descr.nb_proc_per_node = resource_definition->nb_proc_per_node;
162     resource_descr.batch = resource_definition->batch.in();
163     resource_descr.mpiImpl = resource_definition->mpiImpl.in();
164     resource_descr.iprotocol = resource_definition->iprotocol.in();
165     resource_descr.is_cluster_head = resource_definition->is_cluster_head;
166     resource_descr.working_directory = resource_definition->working_directory.in();
167
168     delete resource_definition;
169   }
170   return resource_descr;
171 }
172
173 void
174 BL::SALOMEServices::addResource(BL::ResourceDescr & new_resource)
175 {
176   Engines::ResourceDefinition_var resource_definition = new Engines::ResourceDefinition;
177
178   resource_definition->name = CORBA::string_dup(new_resource.name.c_str());
179   resource_definition->hostname = CORBA::string_dup(new_resource.hostname.c_str());
180   resource_definition->protocol = CORBA::string_dup(new_resource.protocol.c_str());
181   resource_definition->username = CORBA::string_dup(new_resource.username.c_str());
182   resource_definition->applipath = CORBA::string_dup(new_resource.applipath.c_str());
183
184   int i = 0;
185   std::list<std::string>::iterator it = new_resource.componentList.begin();
186   resource_definition->componentList.length(new_resource.componentList.size());
187   for(; it != new_resource.componentList.end(); it++)
188   {
189     resource_definition->componentList[i] = CORBA::string_dup((*it).c_str());
190     i++;
191   }
192
193   resource_definition->OS = CORBA::string_dup(new_resource.OS.c_str());
194   resource_definition->mem_mb = new_resource.mem_mb;
195   resource_definition->cpu_clock = new_resource.cpu_clock;
196   resource_definition->nb_node = new_resource.nb_node;
197   resource_definition->nb_proc_per_node = new_resource.nb_proc_per_node;  
198   resource_definition->batch = CORBA::string_dup(new_resource.batch.c_str());
199   resource_definition->mpiImpl = CORBA::string_dup(new_resource.mpiImpl.c_str());
200   resource_definition->iprotocol = CORBA::string_dup(new_resource.iprotocol.c_str());
201   resource_definition->is_cluster_head = new_resource.is_cluster_head;
202   resource_definition->working_directory = CORBA::string_dup(new_resource.working_directory.c_str());
203
204   try
205   {
206     _resources_manager->AddResource(resource_definition, true, "");
207   }
208   catch (const SALOME::SALOME_Exception & ex)
209   {
210     DEBMSG("SALOME Exception in addResource ! " << ex.details.text.in());
211   }
212   catch (const CORBA::SystemException& ex)
213   {
214     DEBMSG("Receive SALOME System Exception: " << ex);
215     DEBMSG("Check SALOME servers...");
216   }
217 }
218
219 void 
220 BL::SALOMEServices::removeResource(const std::string & name)
221 {
222   try
223   {
224     _resources_manager->RemoveResource(name.c_str(), true, "");
225   }
226   catch (const SALOME::SALOME_Exception & ex)
227   {
228     DEBMSG("SALOME Exception in removeResource ! " << ex.details.text.in());
229   }
230   catch (const CORBA::SystemException& ex)
231   {
232     DEBMSG("Receive SALOME System Exception: " << ex);
233     DEBMSG("Check SALOME servers...");
234   }
235 }
236
237 std::string
238 BL::SALOMEServices::create_job(BL::Job * job)
239 {
240   DEBMSG("Begin of create_job");
241   std::string ret = "";
242   Engines::JobParameters_var job_parameters = new Engines::JobParameters;
243
244   // Job type
245   if (job->getType() == BL::Job::COMMAND)
246   {
247     job_parameters->job_type = CORBA::string_dup("command");
248   }
249   else if (job->getType() == BL::Job::YACS_SCHEMA)
250   {
251     job_parameters->job_type = CORBA::string_dup("yacs_file");
252   }
253   else if (job->getType() == BL::Job::PYTHON_SALOME)
254   {
255     job_parameters->job_type = CORBA::string_dup("python_salome");
256   }
257
258   // Specific parameters
259   if (job->getType() == BL::Job::YACS_SCHEMA)
260   {
261     if (job->getDumpYACSState() > 0)
262     {
263       job_parameters->specific_parameters.length(job_parameters->specific_parameters.length() + 1);
264       std::ostringstream oss;
265       oss << job->getDumpYACSState();
266       Engines::Parameter_var new_parameter = new Engines::Parameter;
267       new_parameter->name = CORBA::string_dup("EnableDumpYACS");
268       new_parameter->value = CORBA::string_dup(oss.str().c_str());
269       job_parameters->specific_parameters[job_parameters->specific_parameters.length() - 1] = new_parameter;
270     }
271   }
272   if (job->getLoadLevelerJobType() != "")
273   {
274     job_parameters->specific_parameters.length(job_parameters->specific_parameters.length() + 1);
275     Engines::Parameter_var new_parameter = new Engines::Parameter;
276     new_parameter->name = CORBA::string_dup("LoalLevelerJobType");
277     new_parameter->value = CORBA::string_dup(job->getLoadLevelerJobType().c_str());
278     job_parameters->specific_parameters[job_parameters->specific_parameters.length() - 1] = new_parameter;
279   }
280
281   // Files
282   job_parameters->job_name = CORBA::string_dup(job->getName().c_str());
283   job_parameters->job_file = CORBA::string_dup(job->getJobFile().c_str());
284   job_parameters->env_file = CORBA::string_dup(job->getEnvFile().c_str());
285   BL::Job::FilesParam files = job->getFilesParameters();
286   std::list<std::string>::iterator it;
287   int i = 0;
288   int j = 0;
289
290   job_parameters->in_files.length(files.input_files_list.size());
291   for (it = files.input_files_list.begin() ; it != files.input_files_list.end(); it++)
292   {
293     job_parameters->in_files[i] = CORBA::string_dup((*it).c_str());
294     i++;
295   }
296
297   job_parameters->out_files.length(files.output_files_list.size());
298   for (it = files.output_files_list.begin() ; it != files.output_files_list.end(); it++)
299   {
300     job_parameters->out_files[j] = CORBA::string_dup((*it).c_str());
301     j++;
302   }
303   job_parameters->local_directory = CORBA::string_dup("");
304   job_parameters->result_directory = CORBA::string_dup(files.result_directory.c_str());
305
306   BL::Job::BatchParam cpp_batch_params =  job->getBatchParameters();
307   job_parameters->work_directory = CORBA::string_dup(cpp_batch_params.batch_directory.c_str());
308
309   // Resource
310   job_parameters->maximum_duration = CORBA::string_dup(cpp_batch_params.maximum_duration.c_str());
311   job_parameters->resource_required.name = CORBA::string_dup(job->getResource().c_str());
312   job_parameters->resource_required.nb_proc = cpp_batch_params.nb_proc;
313   job_parameters->queue = CORBA::string_dup(job->getBatchQueue().c_str());
314
315   // Memory
316   CORBA::Long memory;
317   std::string ram = cpp_batch_params.expected_memory.substr(0,cpp_batch_params.expected_memory.size()-2);
318   std::istringstream iss(ram);
319   iss >> memory;
320   std::string unity = cpp_batch_params.expected_memory.substr(cpp_batch_params.expected_memory.size()-2, 2);
321   if((unity.find("gb") != std::string::npos))
322     memory = memory * 1024;
323   job_parameters->resource_required.mem_mb = memory;
324
325   // Create Job
326   try
327   {
328     int job_id = _salome_launcher->createJob(job_parameters);
329     job->setSalomeLauncherId(job_id);
330   }
331   catch (const SALOME::SALOME_Exception & ex)
332   {
333     DEBMSG("SALOME Exception in createJob !");
334     ret = ex.details.text.in();
335   }
336   catch (const CORBA::SystemException& ex)
337   {
338     DEBMSG("Receive SALOME System Exception: " << ex);
339     DEBMSG("Check SALOME servers...");
340     ret = "SALOME System Exception - see logs";
341   }
342   return ret;
343 }
344
345 std::string
346 BL::SALOMEServices::start_job(BL::Job * job)
347 {
348   std::string ret = "";
349   // Launch Job !
350   try
351   {
352     _salome_launcher->launchJob(job->getSalomeLauncherId());
353   }
354   catch (const SALOME::SALOME_Exception & ex)
355   {
356     DEBMSG("SALOME Exception in launchJob !");
357     ret = ex.details.text.in();
358   }
359   catch (const CORBA::SystemException& ex)
360   {
361     DEBMSG("Receive SALOME System Exception: " << ex);
362     DEBMSG("Check SALOME servers...");
363     ret = "SALOME System Exception - see logs";
364   }
365   return ret;
366 }
367
368 std::string
369 BL::SALOMEServices::refresh_job(BL::Job * job)
370 {
371   std::string ret = "";
372
373   // Refresh Job !
374   try
375   {
376     CORBA::String_var result = _salome_launcher->getJobState(job->getSalomeLauncherId());
377     ret = result.in();
378   }
379   catch (const SALOME::SALOME_Exception & ex)
380   {
381     DEBMSG("SALOME Exception in getJobState !");
382     ret = ex.details.text.in();
383   }
384   catch (const CORBA::SystemException& ex)
385   {
386     DEBMSG("Receive SALOME System Exception: " << ex);
387     DEBMSG("Check SALOME servers...");
388     ret = "SALOME System Exception - see logs";
389   }
390   return ret;
391 }
392
393 std::string
394 BL::SALOMEServices::delete_job(BL::Job * job)
395 {
396   std::string ret = "";
397   // Delete Job !
398   try
399   {
400     _salome_launcher->removeJob(job->getSalomeLauncherId());
401   }
402   catch (const SALOME::SALOME_Exception & ex)
403   {
404     DEBMSG("SALOME Exception in removeJob !");
405     ret = ex.details.text.in();
406   }
407   catch (const CORBA::SystemException& ex)
408   {
409     DEBMSG("Receive SALOME System Exception: " << ex);
410     DEBMSG("Check SALOME servers...");
411     ret = "SALOME System Exception - see logs";
412   }
413   return ret;
414 }
415
416 std::string
417 BL::SALOMEServices::stop_job(BL::Job * job)
418 {
419   std::string ret = "";
420   try
421   {
422     _salome_launcher->stopJob(job->getSalomeLauncherId());
423   }
424   catch (const SALOME::SALOME_Exception & ex)
425   {
426     DEBMSG("SALOME Exception in stopJob !");
427     ret = ex.details.text.in();
428   }
429   catch (const CORBA::SystemException& ex)
430   {
431     DEBMSG("Receive SALOME System Exception: " << ex);
432     DEBMSG("Check SALOME servers...");
433     ret = "SALOME System Exception - see logs";
434   }
435   return ret;
436 }
437
438 std::string
439 BL::SALOMEServices::get_results_job(BL::Job * job)
440 {
441   std::string ret = "";
442
443   BL::Job::FilesParam files = job->getFilesParameters();
444   CORBA::String_var directory = CORBA::string_dup(files.result_directory.c_str());
445
446   // get job results !
447   try
448   {
449     _salome_launcher->getJobResults(job->getSalomeLauncherId(), directory);
450   }
451   catch (const SALOME::SALOME_Exception & ex)
452   {
453     DEBMSG("SALOME Exception in refresh_job !");
454     ret = ex.details.text.in();
455   }
456   catch (const CORBA::SystemException& ex)
457   {
458     DEBMSG("Receive SALOME System Exception: " << ex);
459     DEBMSG("Check SALOME servers...");
460     ret = "SALOME System Exception - see logs";
461   }
462   return ret;
463 }
464
465 std::string
466 BL::SALOMEServices::save_jobs(const std::string & file_name)
467 {
468   CORBA::String_var file = CORBA::string_dup(file_name.c_str());
469   std::string ret = "";
470   try
471   {
472     _salome_launcher->saveJobs(file);
473   }
474   catch (const SALOME::SALOME_Exception & ex)
475   {
476     DEBMSG("SALOME Exception in saveJobs !");
477     ret = ex.details.text.in();
478   }
479   catch (const CORBA::SystemException& ex)
480   {
481     DEBMSG("Receive CORBA System Exception: " << ex);
482     DEBMSG("Check SALOME servers...");
483     ret = "CORBA System Exception - see SALOME logs";
484   }
485   return ret;
486 }
487
488 std::string
489 BL::SALOMEServices::load_jobs(const std::string & file_name)
490 {
491   CORBA::String_var file = CORBA::string_dup(file_name.c_str());
492   std::string ret = "";
493   try
494   {
495     _salome_launcher->loadJobs(file);
496   }
497   catch (const SALOME::SALOME_Exception & ex)
498   {
499     DEBMSG("SALOME Exception in loadJobs !");
500     ret = ex.details.text.in();
501   }
502   catch (const CORBA::SystemException& ex)
503   {
504     DEBMSG("Receive CORBA System Exception: " << ex);
505     DEBMSG("Check SALOME servers...");
506     ret = "CORBA System Exception - see SALOME logs";
507   }
508   return ret;
509 }
510
511 void
512 BL::SALOMEServices::notify(const char* event_name, const char * event_data)
513 {
514   DEBMSG("Launcher event received " << event_name << " " << event_data);
515
516   std::string event(event_name);
517   std::string data(event_data);
518
519   if (event == "SAVE_JOBS")
520   {
521     _manager->launcher_event_save_jobs(data);
522   }
523   else if (event == "LOAD_JOBS")
524   {
525     _manager->launcher_event_load_jobs(data);
526   }
527   else if (event == "NEW_JOB")
528   {
529     _manager->launcher_event_new_job(data);
530   }
531   else if (event == "REMOVE_JOB")
532   {
533     _manager->launcher_event_remove_job(data);
534   }
535   else if (event == "UPDATE_JOB_STATE")
536   {
537     _manager->launcher_event_update_job_state(data);
538   }
539   else
540   {
541     DEBMSG("Unkown launcher event received");
542   }
543 }
544
545 BL::Job * 
546 BL::SALOMEServices::get_new_job(int job_number)
547 {
548   DEBMSG("Start of BL::SALOMEServices::get_new_job");
549   BL::Job * job_return = NULL;
550   Engines::JobParameters * job_parameters = NULL;
551   try
552   {
553     job_parameters = _salome_launcher->getJobParameters(job_number);
554   }
555   catch (const SALOME::SALOME_Exception & ex)
556   {
557     DEBMSG("SALOME Exception in saveJobs !");
558   }
559   catch (const CORBA::SystemException& ex)
560   {
561     DEBMSG("Receive CORBA System Exception: " << ex);
562     DEBMSG("Check SALOME servers...");
563   }
564
565   if (job_parameters)
566   {
567     job_return = new BL::Job();
568     job_return->setSalomeLauncherId(job_number);
569
570     job_return->setName(job_parameters->job_name.in());
571     job_return->setType(job_parameters->job_type.in());
572     job_return->setJobFile(job_parameters->job_file.in());
573     job_return->setEnvFile(job_parameters->env_file.in());
574     job_return->setBatchQueue(job_parameters->queue.in());
575
576     BL::Job::FilesParam param;
577     param.result_directory = job_parameters->result_directory.in();
578     for (CORBA::ULong i = 0; i < job_parameters->in_files.length(); i++)
579       param.input_files_list.push_back(job_parameters->in_files[i].in());
580     for (CORBA::ULong i = 0; i < job_parameters->out_files.length(); i++)
581       param.output_files_list.push_back(job_parameters->out_files[i].in());
582     job_return->setFilesParameters(param);
583
584     BL::Job::BatchParam batch_param;
585     batch_param.batch_directory = job_parameters->work_directory.in();
586     batch_param.maximum_duration = job_parameters->maximum_duration.in();
587     batch_param.nb_proc = job_parameters->resource_required.nb_proc;
588     std::ostringstream mem_stream;
589     mem_stream << job_parameters->resource_required.mem_mb << "mb";
590     batch_param.expected_memory = mem_stream.str();
591     job_return->setBatchParameters(batch_param);
592
593     job_return->setResource(job_parameters->resource_required.name.in());
594
595     // Specific parameters
596     for (CORBA::ULong i = 0; i < job_parameters->specific_parameters.length(); i++)
597     {
598       if (std::string(job_parameters->specific_parameters[i].name.in()) == "EnableDumpYACS")
599       {
600         std::string user_value = job_parameters->specific_parameters[i].value.in();
601         std::istringstream iss(user_value);
602         int value;
603         iss >> value;
604         job_return->setDumpYACSState(value);
605       }
606       if (std::string(job_parameters->specific_parameters[i].name.in()) == "LoalLevelerJobType")
607       {
608         std::string user_value = job_parameters->specific_parameters[i].value.in();
609         job_return->setLoadLevelerJobType(user_value);
610       }
611     }
612
613     // Get current state
614     std::string result_job = job_return->setStringState(refresh_job(job_return));
615     if (result_job != "RefreshError") {}
616     else
617     {
618       // Error in getting state
619       DEBMSG("Error in getting state of the new job!");
620       delete job_return;
621       job_return = NULL;
622     }
623     delete job_parameters;
624   }
625
626   return job_return;
627 }