Back to index

salome-kernel  6.5.0
SALOME_Launcher.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "SALOME_Launcher.hxx"
00024 #include "BatchTest.hxx"
00025 #include "OpUtil.hxx"
00026 #include "SALOME_ContainerManager.hxx"
00027 #include "Utils_CorbaException.hxx"
00028 
00029 
00030 #include "Launcher_Job_Command.hxx"
00031 #include "Launcher_Job_YACSFile.hxx"
00032 #include "Launcher_Job_PythonSALOME.hxx"
00033 
00034 #ifdef WIN32
00035 # include <process.h>
00036 #else
00037 # include <unistd.h>
00038 #endif
00039 #include <sys/types.h>
00040 #include <vector>
00041 
00042 #include <libxml/parser.h>
00043 #include <stdio.h>
00044 #include <sstream>
00045 
00046 const char *SALOME_Launcher::_LauncherNameInNS = "/SalomeLauncher";
00047 
00048 //=============================================================================
00053 //=============================================================================
00054 SALOME_Launcher::SALOME_Launcher(CORBA::ORB_ptr orb, PortableServer::POA_var poa) : _l()
00055 {
00056   MESSAGE("SALOME_Launcher constructor");
00057   _NS = new SALOME_NamingService(orb);
00058   _ResManager = new SALOME_ResourcesManager(orb,poa,_NS);
00059   _l.SetResourcesManager(_ResManager->GetImpl());
00060   _ContManager = new SALOME_ContainerManager(orb,poa,_ResManager,_NS);
00061   _ResManager->_remove_ref();
00062   _ContManager->_remove_ref();
00063 
00064   _orb = CORBA::ORB::_duplicate(orb) ;
00065   _poa = PortableServer::POA::_duplicate(poa) ;
00066   PortableServer::ObjectId_var id = _poa->activate_object(this);
00067   CORBA::Object_var obj = _poa->id_to_reference(id);
00068   Engines::SalomeLauncher_var refContMan = Engines::SalomeLauncher::_narrow(obj);
00069 
00070   _NS->Register(refContMan,_LauncherNameInNS);
00071   MESSAGE("SALOME_Launcher constructor end");
00072 }
00073 
00074 //=============================================================================
00078 //=============================================================================
00079 SALOME_Launcher::~SALOME_Launcher()
00080 {
00081   MESSAGE("SALOME_Launcher destructor");
00082   delete _NS;
00083   MESSAGE("SALOME_Launcher destructor end");
00084 }
00085 
00086 
00087 CORBA::Long 
00088 SALOME_Launcher::createJob(const Engines::JobParameters & job_parameters)
00089 {
00090   std::string job_type = job_parameters.job_type.in();
00091 
00092   if (job_type != "command" && job_type != "yacs_file" && job_type != "python_salome")
00093   {
00094     std::string message("SALOME_Launcher::createJob: bad job type: ");
00095     message += job_type;
00096     THROW_SALOME_CORBA_EXCEPTION(message.c_str(), SALOME::INTERNAL_ERROR);
00097   }
00098 
00099   Launcher::Job * new_job; // It is Launcher_cpp that is going to destroy it
00100 
00101   if (job_type == "command")
00102     new_job = new Launcher::Job_Command();
00103   else if (job_type == "yacs_file")
00104     new_job = new Launcher::Job_YACSFile();
00105   else if (job_type == "python_salome")
00106     new_job = new Launcher::Job_PythonSALOME();
00107 
00108   // Name
00109   new_job->setJobName(job_parameters.job_name.in());
00110 
00111   // Directories
00112   std::string work_directory = job_parameters.work_directory.in();
00113   std::string local_directory = job_parameters.local_directory.in();
00114   std::string result_directory = job_parameters.result_directory.in();
00115   new_job->setWorkDirectory(work_directory);
00116   new_job->setLocalDirectory(local_directory);
00117   new_job->setResultDirectory(result_directory);
00118 
00119   // Job File
00120   std::string job_file = job_parameters.job_file.in();
00121   try
00122   {
00123     new_job->setJobFile(job_file);
00124   }
00125   catch(const LauncherException &ex)
00126   {
00127     INFOS(ex.msg.c_str());
00128     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
00129   }
00130 
00131   // Files
00132   std::string env_file = job_parameters.env_file.in();
00133   new_job->setEnvFile(env_file);
00134   for (CORBA::ULong i = 0; i < job_parameters.in_files.length(); i++)
00135     new_job->add_in_file(job_parameters.in_files[i].in());
00136   for (CORBA::ULong i = 0; i < job_parameters.out_files.length(); i++)
00137     new_job->add_out_file(job_parameters.out_files[i].in());
00138 
00139   // Expected During Time
00140   try
00141   {
00142     std::string maximum_duration = job_parameters.maximum_duration.in();
00143     new_job->setMaximumDuration(maximum_duration);
00144   }
00145   catch(const LauncherException &ex){
00146     INFOS(ex.msg.c_str());
00147     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
00148   }
00149 
00150   // Queue
00151   std::string queue = job_parameters.queue.in();
00152   new_job->setQueue(queue);
00153 
00154   // Resources requirements
00155   try
00156   {
00157     resourceParams p;
00158     p.name = job_parameters.resource_required.name;
00159     p.hostname = job_parameters.resource_required.hostname;
00160     p.OS = job_parameters.resource_required.OS;
00161     p.nb_proc = job_parameters.resource_required.nb_proc;
00162     p.nb_node = job_parameters.resource_required.nb_node;
00163     p.nb_proc_per_node = job_parameters.resource_required.nb_proc_per_node;
00164     p.cpu_clock = job_parameters.resource_required.cpu_clock;
00165     p.mem_mb = job_parameters.resource_required.mem_mb;
00166     new_job->setResourceRequiredParams(p);
00167   }
00168   catch(const LauncherException &ex){
00169     INFOS(ex.msg.c_str());
00170     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
00171   }
00172 
00173   // Adding specific parameters to the job
00174   for (CORBA::ULong i = 0; i < job_parameters.specific_parameters.length(); i++)
00175     new_job->addSpecificParameter(job_parameters.specific_parameters[i].name.in(),
00176                                   job_parameters.specific_parameters[i].value.in());
00177   try
00178   {
00179     new_job->checkSpecificParameters();
00180   }
00181   catch(const LauncherException &ex)
00182   {
00183     INFOS(ex.msg.c_str());
00184     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
00185   }
00186 
00187   try
00188   {
00189     _l.createJob(new_job);
00190     std::ostringstream job_id;
00191     job_id << new_job->getNumber();
00192     notifyObservers("NEW_JOB", job_id.str());
00193   }
00194   catch(const LauncherException &ex)
00195   {
00196     INFOS(ex.msg.c_str());
00197     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00198   }
00199   return new_job->getNumber();
00200 }
00201 
00202 void 
00203 SALOME_Launcher::launchJob(CORBA::Long job_id)
00204 {
00205   try
00206   {
00207     _l.launchJob(job_id);
00208   }
00209   catch(const LauncherException &ex)
00210   {
00211     INFOS(ex.msg.c_str());
00212     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00213   }
00214 }
00215 
00216 char *
00217 SALOME_Launcher::getJobState(CORBA::Long job_id)
00218 {
00219   std::string result;
00220   try
00221   {
00222     result = _l.getJobState(job_id);
00223   }
00224   catch(const LauncherException &ex)
00225   {
00226     INFOS(ex.msg.c_str());
00227     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00228   }
00229   return CORBA::string_dup(result.c_str());
00230 }
00231 
00232 void
00233 SALOME_Launcher::getJobResults(CORBA::Long job_id, const char * directory)
00234 {
00235   try
00236   {
00237     _l.getJobResults(job_id, directory);
00238   }
00239   catch(const LauncherException &ex)
00240   {
00241     INFOS(ex.msg.c_str());
00242     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00243   }
00244 }
00245 
00246 CORBA::Boolean
00247 SALOME_Launcher::getJobDumpState(CORBA::Long job_id, const char * directory)
00248 {
00249   CORBA::Boolean rtn = false;
00250   try
00251   {
00252     rtn = _l.getJobDumpState(job_id, directory);
00253   }
00254   catch(const LauncherException &ex)
00255   {
00256     INFOS(ex.msg.c_str());
00257     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00258   }
00259   return rtn;
00260 }
00261 
00262 void 
00263 SALOME_Launcher::removeJob(CORBA::Long job_id)
00264 {
00265   try
00266   {
00267     _l.removeJob(job_id);
00268     std::ostringstream job_id_str;
00269     job_id_str << job_id;
00270     notifyObservers("REMOVE_JOB", job_id_str.str());
00271   }
00272   catch(const LauncherException &ex)
00273   {
00274     INFOS(ex.msg.c_str());
00275     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00276   }
00277 }
00278 
00279 void 
00280 SALOME_Launcher::stopJob(CORBA::Long job_id)
00281 {
00282   try
00283   {
00284     _l.stopJob(job_id);
00285     std::ostringstream job_id_str;
00286     job_id_str << job_id;
00287     notifyObservers("UPDATE_JOB_STATE", job_id_str.str());
00288   }
00289   catch(const LauncherException &ex)
00290   {
00291     INFOS(ex.msg.c_str());
00292     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
00293   }
00294 }
00295 
00296 //=============================================================================
00302 //=============================================================================
00303 CORBA::Long 
00304 SALOME_Launcher::createJobWithFile(const char * xmlExecuteFile,
00305                                    const char * clusterName)
00306 {
00307   CORBA::Long jobId;
00308   try{
00309     jobId = _l.createJobWithFile(xmlExecuteFile, clusterName);
00310   }
00311   catch(const LauncherException &ex){
00312     INFOS(ex.msg.c_str());
00313     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
00314   }
00315 
00316   return jobId;
00317 }
00318 
00319 //=============================================================================
00324 //=============================================================================
00325 CORBA::Boolean 
00326 SALOME_Launcher::testBatch(const Engines::ResourceParameters& params)
00327 {
00328   MESSAGE("BEGIN OF SALOME_Launcher::testBatch");
00329   CORBA::Boolean rtn = false;
00330   try
00331   {
00332     // find a cluster matching the structure params
00333     Engines::ResourceList *aMachineList = _ResManager->GetFittingResources(params);
00334     if (aMachineList->length() == 0)
00335       throw SALOME_Exception("No resources have been found with your parameters");
00336 
00337     const Engines::ResourceDefinition* p = _ResManager->GetResourceDefinition((*aMachineList)[0]);
00338         std::string resource_name(p->name);
00339     INFOS("Choose resource for test: " <<  resource_name);
00340     
00341     BatchTest t(*p);
00342     if (t.test()) 
00343     {
00344       rtn = true;
00345     }
00346   }
00347   catch(const LauncherException &ex){
00348     INFOS(ex.msg.c_str());
00349     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
00350   }
00351   return rtn;
00352 }
00353 
00354 //=============================================================================
00358 //=============================================================================
00359 void SALOME_Launcher::Shutdown()
00360 {
00361   MESSAGE("Shutdown");
00362   _NS->Destroy_Name(_LauncherNameInNS);
00363   _ContManager->Shutdown();
00364   _ResManager->Shutdown();
00365   PortableServer::ObjectId_var oid = _poa->servant_to_id(this);
00366   _poa->deactivate_object(oid);
00367   if(!CORBA::is_nil(_orb))
00368     _orb->shutdown(0);
00369 }
00370 
00371 //=============================================================================
00375 //=============================================================================
00376 CORBA::Long SALOME_Launcher::getPID()
00377 {
00378   return 
00379 #ifndef WIN32
00380     (CORBA::Long)getpid();
00381 #else
00382     (CORBA::Long)_getpid();
00383 #endif
00384 }
00385 
00386 //=============================================================================
00390 //=============================================================================
00391 Engines::JobsList *
00392 SALOME_Launcher::getJobsList()
00393 {
00394   Engines::JobsList_var jobs_list = new Engines::JobsList();
00395   std::map<int, Launcher::Job *> cpp_jobs = _l.getJobs();
00396   std::map<int, Launcher::Job *>::const_iterator it_job;
00397   int list_id = 0;
00398   for(it_job = cpp_jobs.begin(); it_job != cpp_jobs.end(); it_job++)
00399   {
00400     int number          = it_job->first;
00401     try
00402     {
00403       // Prepare CORBA job description
00404       Engines::JobDescription_var job_descr = new Engines::JobDescription();
00405       Engines::JobParameters_var job_parameters = getJobParameters(number);
00406       job_descr->job_id = number;
00407       job_descr->job_parameters = job_parameters;
00408 
00409       // Add job description to the sequence
00410       jobs_list->length(list_id + 1);
00411       jobs_list[list_id] = job_descr;
00412       list_id++;
00413     }
00414     catch (...) {}
00415   }
00416   return jobs_list._retn();
00417 }
00418 
00419 //=============================================================================
00423 //=============================================================================
00424 Engines::JobParameters *
00425 SALOME_Launcher::getJobParameters(CORBA::Long job_id)
00426 {
00427   std::map<int, Launcher::Job *> cpp_jobs = _l.getJobs();
00428   std::map<int, Launcher::Job *>::const_iterator it_job = cpp_jobs.find(job_id);
00429   if (it_job == cpp_jobs.end())
00430   {
00431     INFOS("Cannot find the job, is it created ? job number: " << job_id);
00432     THROW_SALOME_CORBA_EXCEPTION("Job does not exist", SALOME::INTERNAL_ERROR);
00433   }
00434 
00435   Launcher::Job * job = it_job->second;
00436   Engines::JobParameters_var job_parameters = new Engines::JobParameters;
00437   job_parameters->job_name         = CORBA::string_dup(job->getJobName().c_str());
00438   job_parameters->job_type         = CORBA::string_dup(job->getJobType().c_str());
00439   job_parameters->job_file         = CORBA::string_dup(job->getJobFile().c_str());
00440   job_parameters->env_file         = CORBA::string_dup(job->getEnvFile().c_str());
00441   job_parameters->work_directory   = CORBA::string_dup(job->getWorkDirectory().c_str());
00442   job_parameters->local_directory  = CORBA::string_dup(job->getLocalDirectory().c_str());
00443   job_parameters->result_directory = CORBA::string_dup(job->getResultDirectory().c_str());
00444 
00445   int i = 0;
00446   int j = 0;
00447   std::list<std::string> in_files  = job->get_in_files();
00448   std::list<std::string> out_files = job->get_out_files();
00449   job_parameters->in_files.length(in_files.size());
00450   for(std::list<std::string>::iterator it = in_files.begin(); it != in_files.end(); it++)
00451   {
00452     job_parameters->in_files[i] = CORBA::string_dup((*it).c_str());
00453     i++;
00454   }
00455   job_parameters->out_files.length(out_files.size());
00456   for(std::list<std::string>::iterator it = out_files.begin(); it != out_files.end(); it++)
00457   {
00458     job_parameters->out_files[j] = CORBA::string_dup((*it).c_str());
00459     j++;
00460   }
00461 
00462   job_parameters->maximum_duration = CORBA::string_dup(job->getMaximumDuration().c_str());
00463   job_parameters->queue            = CORBA::string_dup(job->getQueue().c_str());
00464 
00465   resourceParams resource_params = job->getResourceRequiredParams();
00466   job_parameters->resource_required.name             = CORBA::string_dup(resource_params.name.c_str());
00467   job_parameters->resource_required.hostname         = CORBA::string_dup(resource_params.hostname.c_str());
00468   job_parameters->resource_required.OS               = CORBA::string_dup(resource_params.OS.c_str());
00469   job_parameters->resource_required.nb_proc          = resource_params.nb_proc;
00470   job_parameters->resource_required.nb_node          = resource_params.nb_node;
00471   job_parameters->resource_required.nb_proc_per_node = resource_params.nb_proc_per_node;
00472   job_parameters->resource_required.cpu_clock        = resource_params.cpu_clock;
00473   job_parameters->resource_required.mem_mb           = resource_params.mem_mb;
00474 
00475   std::map<std::string, std::string> specific_parameters = job->getSpecificParameters();
00476   if (!specific_parameters.empty())
00477   {
00478     job_parameters->specific_parameters.length(specific_parameters.size());
00479     std::map<std::string, std::string>::const_iterator it_specific;
00480     CORBA::ULong i = 0;
00481     for (it_specific = specific_parameters.begin() ; it_specific != specific_parameters.end(); it_specific++)
00482     {
00483       Engines::Parameter_var new_param = new Engines::Parameter;
00484       new_param->name  = CORBA::string_dup((it_specific->first).c_str());
00485       new_param->value = CORBA::string_dup((it_specific->second).c_str());
00486       job_parameters->specific_parameters[i] = new_param;
00487       i++;
00488     }
00489   }
00490 
00491   return job_parameters._retn();
00492 }
00493 
00494 //=============================================================================
00498 //=============================================================================
00499 void
00500 SALOME_Launcher::loadJobs(const char* jobs_file)
00501 {
00502   // Step 1: check jobs_file read access
00503   FILE* xml_file = fopen(jobs_file, "r");
00504   if (xml_file == NULL)
00505   {
00506     std::string error = "Error opening jobs_file in SALOME_Launcher::loadJobs: " + std::string(jobs_file);
00507     INFOS(error);
00508     THROW_SALOME_CORBA_EXCEPTION(error.c_str(), SALOME::INTERNAL_ERROR);
00509   }
00510 
00511   // Step 2: read xml file
00512   xmlDocPtr doc = xmlReadFile(jobs_file, NULL, 0);
00513   if (doc == NULL)
00514   {
00515     std::string error = "Error in xmlReadFile in SALOME_Launcher::loadJobs, could not parse file: " + std::string(jobs_file);
00516     INFOS(error);
00517     fclose(xml_file);
00518     THROW_SALOME_CORBA_EXCEPTION(error.c_str(), SALOME::INTERNAL_ERROR);
00519   }
00520 
00521   // Step 3: Find jobs
00522   xmlNodePtr root_node = xmlDocGetRootElement(doc);
00523   xmlNodePtr xmlCurrentNode = root_node->xmlChildrenNode;
00524   if (!xmlStrcmp(root_node->name, xmlCharStrdup("jobs")))
00525   {
00526     while(xmlCurrentNode != NULL)
00527     {
00528       if (!xmlStrcmp(xmlCurrentNode->name, xmlCharStrdup("job")))
00529       {
00530         INFOS("A job is found");
00531         Launcher::Job * new_job; // It is Launcher_cpp that is going to destroy it
00532         xmlNodePtr job_node = xmlCurrentNode;
00533 
00534         // Begin Job
00535         if (!xmlHasProp(job_node, xmlCharStrdup("type"))  ||
00536             !xmlHasProp(job_node, xmlCharStrdup("name")))
00537         {
00538           INFOS("A bad job is found, type or name not found");
00539           break;
00540         }
00541         xmlChar* type = xmlGetProp(job_node, xmlCharStrdup("type"));
00542         xmlChar* name = xmlGetProp(job_node, xmlCharStrdup("name"));
00543         std::string job_type((const char*) type);
00544         if (job_type == "command")
00545           new_job = new Launcher::Job_Command();
00546         else if (job_type == "yacs_file")
00547           new_job = new Launcher::Job_YACSFile();
00548         else if (job_type == "python_salome")
00549           new_job = new Launcher::Job_PythonSALOME();
00550         new_job->setJobName(std::string((const char *)name));
00551         xmlFree(type);
00552         xmlFree(name);
00553 
00554         xmlNodePtr user_node = xmlFirstElementChild(job_node);
00555         xmlNodePtr run_node = xmlNextElementSibling(user_node);
00556         if (user_node == NULL || run_node == NULL)
00557         {
00558           INFOS("A bad job is found, user_part or run_part not found");
00559           delete new_job;
00560           break;
00561         }
00562         if (xmlStrcmp(user_node->name, xmlCharStrdup("user_part")) ||
00563             xmlStrcmp(run_node->name, xmlCharStrdup("run_part")))
00564         {
00565           INFOS("A bad job is found, cannot get a correct user_part or run_part node");
00566           delete new_job;
00567           break;
00568         }
00569 
00570         // Add user part
00571 
00572         // Get job_file env_file work_directory local_directory result_directory
00573         xmlNodePtr job_file_node         = xmlFirstElementChild(user_node);
00574         xmlNodePtr env_file_node         = xmlNextElementSibling(job_file_node);
00575         xmlNodePtr work_directory_node   = xmlNextElementSibling(env_file_node);
00576         xmlNodePtr local_directory_node  = xmlNextElementSibling(work_directory_node);
00577         xmlNodePtr result_directory_node = xmlNextElementSibling(local_directory_node);
00578         if (job_file_node         == NULL ||
00579             env_file_node         == NULL ||
00580             work_directory_node   == NULL ||
00581             local_directory_node  == NULL ||
00582             result_directory_node == NULL
00583            )
00584         {
00585           INFOS("A bad job is found, some user_part are not found");
00586           delete new_job;
00587           break;
00588         }
00589         if (xmlStrcmp(job_file_node->name,         xmlCharStrdup("job_file"))         ||
00590             xmlStrcmp(env_file_node->name,         xmlCharStrdup("env_file"))         ||
00591             xmlStrcmp(work_directory_node->name,   xmlCharStrdup("work_directory"))   ||
00592             xmlStrcmp(local_directory_node->name,  xmlCharStrdup("local_directory"))  ||
00593             xmlStrcmp(result_directory_node->name, xmlCharStrdup("result_directory"))
00594            )
00595         {
00596           INFOS("A bad job is found, some user part node are not in the rigth or does not have a correct name");
00597           delete new_job;
00598           break;
00599         }
00600         xmlChar* job_file         = xmlNodeGetContent(job_file_node);
00601         try
00602         {
00603           new_job->setJobFile(std::string((const char *)job_file));
00604         }
00605         catch(const LauncherException &ex)
00606         {
00607           INFOS("Exception receice for job_file, cannot add the job" << ex.msg.c_str());
00608           delete new_job;
00609           xmlFree(job_file);
00610           break;
00611         }
00612         xmlChar* env_file         = xmlNodeGetContent(env_file_node);
00613         xmlChar* work_directory   = xmlNodeGetContent(work_directory_node);
00614         xmlChar* local_directory  = xmlNodeGetContent(local_directory_node);
00615         xmlChar* result_directory = xmlNodeGetContent(result_directory_node);
00616         new_job->setEnvFile(std::string((const char *)env_file));
00617         new_job->setWorkDirectory(std::string((const char *)work_directory));
00618         new_job->setLocalDirectory(std::string((const char *)local_directory));
00619         new_job->setResultDirectory(std::string((const char *)result_directory));
00620         xmlFree(job_file);
00621         xmlFree(env_file);
00622         xmlFree(work_directory);
00623         xmlFree(local_directory);
00624         xmlFree(result_directory);
00625 
00626         // Get in and out files
00627         xmlNodePtr files_node = xmlNextElementSibling(result_directory_node);
00628         if (files_node == NULL)
00629         {
00630           INFOS("A bad job is found, user_part files is not found");
00631           delete new_job;
00632           break;
00633         }
00634         if (xmlStrcmp(files_node->name, xmlCharStrdup("files")))
00635         {
00636           INFOS("A bad job is found, files node are not in the rigth place or does not have a correct name or does not exist");
00637           delete new_job;
00638           break;
00639         }
00640         xmlNodePtr file_node = xmlFirstElementChild(files_node);
00641         while (file_node != NULL)
00642         {
00643           if (!xmlStrcmp(file_node->name, xmlCharStrdup("in_file")))
00644           {
00645             xmlChar* in_file = xmlNodeGetContent(file_node);
00646             new_job->add_in_file(std::string((const char *)in_file));
00647             xmlFree(in_file);
00648           }
00649           else if (!xmlStrcmp(file_node->name, xmlCharStrdup("out_file")))
00650           {
00651             xmlChar* out_file = xmlNodeGetContent(file_node);
00652             new_job->add_out_file(std::string((const char *)out_file));
00653             xmlFree(out_file);
00654           }
00655           file_node = xmlNextElementSibling(file_node);
00656         }
00657 
00658         // Get resource part
00659         xmlNodePtr res_node = xmlNextElementSibling(files_node);
00660         xmlNodePtr maximum_duration_node = xmlNextElementSibling(res_node);
00661         xmlNodePtr queue_node = xmlNextElementSibling(maximum_duration_node);
00662         if (res_node              == NULL ||
00663             maximum_duration_node == NULL ||
00664             queue_node            == NULL
00665            )
00666         {
00667           INFOS("A bad job is found, some user_part are not found");
00668           delete new_job;
00669           break;
00670         }
00671         if (xmlStrcmp(res_node->name,              xmlCharStrdup("resource_params"))  ||
00672             xmlStrcmp(maximum_duration_node->name, xmlCharStrdup("maximum_duration")) ||
00673             xmlStrcmp(queue_node->name,            xmlCharStrdup("queue"))
00674            )
00675         {
00676           INFOS("A bad job is found, some user part node are not in the rigth or does not have a correct name");
00677           delete new_job;
00678           break;
00679         }
00680         xmlChar* maximum_duration = xmlNodeGetContent(maximum_duration_node);
00681         try
00682         {
00683           new_job->setMaximumDuration(std::string((const char *)maximum_duration));
00684         }
00685         catch(const LauncherException &ex)
00686         {
00687           INFOS("Exception receice for maximum_duration, cannot add the job" << ex.msg.c_str());
00688           delete new_job;
00689           xmlFree(maximum_duration);
00690           break;
00691         }
00692         xmlChar* queue            = xmlNodeGetContent(queue_node);
00693         new_job->setQueue(std::string((const char *)queue));
00694         xmlFree(maximum_duration);
00695         xmlFree(queue);
00696 
00697         xmlNodePtr specific_node = xmlNextElementSibling(queue_node);
00698         if (specific_node == NULL)
00699         {
00700           INFOS("A bad job is found, specific_parameters part is not found");
00701           delete new_job;
00702           break;
00703         }
00704         xmlNodePtr parameter_node = xmlFirstElementChild(specific_node);
00705         while (parameter_node != NULL)
00706         {
00707           if (!xmlStrcmp(parameter_node->name, xmlCharStrdup("specific_parameter")))
00708           {
00709             xmlNodePtr name_node = xmlFirstElementChild(parameter_node);
00710             xmlNodePtr value_node = xmlNextElementSibling(name_node);
00711             if (name_node == NULL ||
00712                 value_node == NULL)
00713             {
00714               INFOS("A bad job is found, specific_parameter parts are not found");
00715               delete new_job;
00716               break;
00717             }
00718             if (xmlStrcmp(name_node->name, xmlCharStrdup("name")) ||
00719                 xmlStrcmp(value_node->name, xmlCharStrdup("value")))
00720             {
00721               INFOS("A bad job is found, specific_parameter bad parts are found");
00722               delete new_job;
00723               break;
00724             }
00725 
00726             xmlChar* name  = xmlNodeGetContent(name_node);
00727             xmlChar* value = xmlNodeGetContent(value_node);
00728             try
00729             {
00730               new_job->addSpecificParameter(std::string((const char*)name), std::string((const char*)value));
00731               xmlFree(name);
00732               xmlFree(value);
00733             }
00734             catch(const LauncherException &ex)
00735             {
00736               INFOS("Exception receice for a specific parameter, cannot add the job" << ex.msg.c_str());
00737               delete new_job;
00738               xmlFree(name);
00739               xmlFree(value);
00740               break;
00741             }
00742           }
00743           else
00744           {
00745             INFOS("A bad job is found, specific_parameters part is bad, a node that is not a specific parameter is found");
00746             delete new_job;
00747             break;
00748           }
00749           parameter_node = xmlNextElementSibling(parameter_node);
00750         }
00751 
00752         xmlNodePtr res_name_node             = xmlFirstElementChild(res_node);
00753         xmlNodePtr res_hostname_node         = xmlNextElementSibling(res_name_node);
00754         xmlNodePtr res_os_node               = xmlNextElementSibling(res_hostname_node);
00755         xmlNodePtr res_nb_proc_node          = xmlNextElementSibling(res_os_node);
00756         xmlNodePtr res_nb_node_node          = xmlNextElementSibling(res_nb_proc_node);
00757         xmlNodePtr res_nb_proc_per_node_node = xmlNextElementSibling(res_nb_node_node);
00758         xmlNodePtr res_cpu_clock_node        = xmlNextElementSibling(res_nb_proc_per_node_node);
00759         xmlNodePtr res_mem_mb_node           = xmlNextElementSibling(res_cpu_clock_node);
00760         if (res_name_node             == NULL ||
00761             res_hostname_node         == NULL ||
00762             res_os_node               == NULL ||
00763             res_nb_proc_node          == NULL ||
00764             res_nb_node_node          == NULL ||
00765             res_nb_proc_per_node_node == NULL ||
00766             res_cpu_clock_node        == NULL ||
00767             res_mem_mb_node           == NULL
00768            )
00769         {
00770           INFOS("A bad job is found, some resource_params user_part are not found");
00771           delete new_job;
00772           break;
00773         }
00774         if (xmlStrcmp(res_name_node->name,             xmlCharStrdup("name"))             ||
00775             xmlStrcmp(res_hostname_node->name,         xmlCharStrdup("hostname"))         ||
00776             xmlStrcmp(res_os_node->name,               xmlCharStrdup("OS"))               ||
00777             xmlStrcmp(res_nb_proc_node->name,          xmlCharStrdup("nb_proc"))          ||
00778             xmlStrcmp(res_nb_node_node->name,          xmlCharStrdup("nb_node"))          ||
00779             xmlStrcmp(res_nb_proc_per_node_node->name, xmlCharStrdup("nb_proc_per_node")) ||
00780             xmlStrcmp(res_cpu_clock_node->name,        xmlCharStrdup("cpu_clock"))        ||
00781             xmlStrcmp(res_mem_mb_node->name,           xmlCharStrdup("mem_mb"))
00782            )
00783         {
00784           INFOS("A bad job is found, some resource_params user_part node are not in the rigth or does not have a correct name");
00785           delete new_job;
00786           break;
00787         }
00788         xmlChar* res_name     = xmlNodeGetContent(res_name_node);
00789         xmlChar* res_hostname = xmlNodeGetContent(res_hostname_node);
00790         xmlChar* res_os       = xmlNodeGetContent(res_os_node);
00791         resourceParams p;
00792         p.name     = std::string((const char*) res_name);
00793         p.hostname = std::string((const char*) res_hostname);
00794         p.OS       = std::string((const char*) res_os);
00795         xmlFree(res_name);
00796         xmlFree(res_hostname);
00797         xmlFree(res_os);
00798         xmlChar* res_nb_proc          = xmlNodeGetContent(res_nb_proc_node);
00799         xmlChar* res_nb_node          = xmlNodeGetContent(res_nb_node_node);
00800         xmlChar* res_nb_proc_per_node = xmlNodeGetContent(res_nb_proc_per_node_node);
00801         xmlChar* res_cpu_clock        = xmlNodeGetContent(res_cpu_clock_node);
00802         xmlChar* res_mem_mb           = xmlNodeGetContent(res_mem_mb_node);
00803         bool import_value = true;
00804         std::istringstream nb_proc_stream((const char *) res_nb_proc);
00805         if (!(nb_proc_stream >> p.nb_proc))
00806           import_value = false;
00807         std::istringstream nb_node_stream((const char *) res_nb_node);
00808         if (!(nb_node_stream >> p.nb_node))
00809           import_value = false;
00810         std::istringstream nb_proc_per_node_stream((const char *) res_nb_proc_per_node);
00811         if (!(nb_proc_per_node_stream >> p.nb_proc_per_node))
00812           import_value = false;
00813         std::istringstream cpu_clock_stream((const char *) res_cpu_clock);
00814         if (!(cpu_clock_stream >> p.cpu_clock))
00815           import_value = false;
00816         std::istringstream mem_mb_stream((const char *) res_mem_mb);
00817         if (!(mem_mb_stream >> p.mem_mb))
00818           import_value = false;
00819         xmlFree(res_nb_proc);
00820         xmlFree(res_nb_node);
00821         xmlFree(res_nb_proc_per_node);
00822         xmlFree(res_cpu_clock);
00823         xmlFree(res_mem_mb);
00824         if (!import_value)
00825         {
00826           INFOS("A bad job is found, some resource_params value are not correct");
00827           delete new_job;
00828           break;
00829         }
00830         try
00831         {
00832           new_job->setResourceRequiredParams(p);
00833         }
00834         catch(const LauncherException &ex)
00835         {
00836           INFOS("A bad job is found, an error when inserting resource_params:" << ex.msg.c_str());
00837           delete new_job;
00838           break;
00839         }
00840 
00841         // We finally get run part to figure out what to do
00842         xmlNodePtr job_state_node             = xmlFirstElementChild(run_node);
00843         xmlNodePtr resource_choosed_name_node = xmlNextElementSibling(job_state_node);
00844         xmlNodePtr job_reference_node         = xmlNextElementSibling(resource_choosed_name_node);
00845         if (job_state_node             == NULL ||
00846             resource_choosed_name_node == NULL ||
00847             job_reference_node         == NULL
00848            )
00849         {
00850           INFOS("A bad job is found, some run_part are not found");
00851           delete new_job;
00852           break;
00853         }
00854         if (xmlStrcmp(job_state_node->name,             xmlCharStrdup("job_state"))             ||
00855             xmlStrcmp(resource_choosed_name_node->name, xmlCharStrdup("resource_choosed_name")) ||
00856             xmlStrcmp(job_reference_node->name,         xmlCharStrdup("job_reference"))
00857            )
00858         {
00859           INFOS("A bad job is found, some run_part nodes are not in the rigth or does not have a correct name");
00860           delete new_job;
00861           break;
00862         }
00863         xmlChar* job_state_xml             = xmlNodeGetContent(job_state_node);
00864         xmlChar* resource_choosed_name_xml = xmlNodeGetContent(resource_choosed_name_node);
00865         xmlChar* job_reference_xml         = xmlNodeGetContent(job_reference_node);
00866         std::string job_state((const char *) job_state_xml);
00867         std::string resource_choosed_name((const char *) resource_choosed_name_xml);
00868         std::string job_reference((const char *) job_reference_xml);
00869         xmlFree(job_state_xml);
00870         xmlFree(resource_choosed_name_xml);
00871         xmlFree(job_reference_xml);
00872 
00873         if (job_state == "CREATED")
00874         {
00875           // In this case, we ignore run_part informations
00876           try
00877           {
00878             _l.createJob(new_job);
00879             std::ostringstream job_id;
00880             job_id << new_job->getNumber();
00881             notifyObservers("NEW_JOB", job_id.str());
00882           }
00883           catch(const LauncherException &ex)
00884           {
00885             INFOS("Load failed: " << ex.msg.c_str());
00886           }
00887         }
00888         else if (job_state == "QUEUED"     ||
00889                  job_state == "RUNNING"    ||
00890                  job_state == "IN_PROCESS" ||
00891                  job_state == "PAUSED")
00892         {
00893           try
00894           {
00895             new_job->setState(job_state);
00896             _l.addJobDirectlyToMap(new_job, job_reference);
00897 
00898             // Step 4: We check that the BatchManager could resume
00899             // the job
00900 #ifdef WITH_LIBBATCH
00901             if (new_job->getBatchManagerJobId().getReference() != job_reference)
00902             {
00903               INFOS("BatchManager type cannot resume a job - job state is set to ERROR");
00904               new_job->setState("ERROR");
00905             }
00906 #endif
00907             std::ostringstream job_id;
00908             job_id << new_job->getNumber();
00909             notifyObservers("NEW_JOB", job_id.str());
00910           }
00911           catch(const LauncherException &ex)
00912           {
00913             INFOS("Cannot load the job! Exception: " << ex.msg.c_str());
00914             delete new_job;
00915           }
00916         }
00917         else if (job_state == "FINISHED" ||
00918                  job_state == "FAILED"   ||
00919                  job_state == "ERROR")
00920         {
00921           try
00922           {
00923             // Step 2: We add run_part informations
00924             new_job->setState(job_state);
00925             _l.addJobDirectlyToMap(new_job, job_reference);
00926             std::ostringstream job_id;
00927             job_id << new_job->getNumber();
00928             notifyObservers("NEW_JOB", job_id.str());
00929           }
00930           catch(const LauncherException &ex)
00931           {
00932             INFOS("Cannot load the job! Exception: " << ex.msg.c_str());
00933             delete new_job;
00934           }
00935         }
00936         else
00937         {
00938           INFOS("A bad job is found, state unknown " << job_state);
00939           delete new_job;
00940         }
00941 
00942       }
00943       xmlCurrentNode = xmlCurrentNode->next;
00944     }
00945   }
00946   else
00947   {
00948     xmlFreeDoc(doc);
00949     fclose(xml_file);
00950     std::string error = "Error in xml file, could not find root_node named jobs: " + std::string(jobs_file);
00951     INFOS(error);
00952     THROW_SALOME_CORBA_EXCEPTION(error.c_str(), SALOME::INTERNAL_ERROR);
00953   }
00954 
00955   // Clean
00956   xmlFreeDoc(doc);
00957   fclose(xml_file);
00958   notifyObservers("LOAD_JOBS", jobs_file);
00959 }
00960 
00961 //=============================================================================
00965 //=============================================================================
00966 void
00967 SALOME_Launcher::saveJobs(const char* jobs_file)
00968 {
00969 
00970   // Step 1: check jobs_file write access
00971   FILE* xml_file = fopen(jobs_file, "w");
00972   if (xml_file == NULL)
00973   {
00974     std::string error = "Error opening jobs_file in SALOME_Launcher::saveJobs: " + std::string(jobs_file);
00975     INFOS(error);
00976     THROW_SALOME_CORBA_EXCEPTION(error.c_str(), SALOME::INTERNAL_ERROR);
00977   }
00978 
00979   // Step 2: First lines
00980   xmlKeepBlanksDefault(0);
00981   xmlDocPtr doc = xmlNewDoc(xmlCharStrdup("1.0"));
00982   xmlNodePtr root_node = xmlNewNode(NULL, xmlCharStrdup("jobs"));
00983   xmlDocSetRootElement(doc, root_node);
00984   xmlNodePtr doc_comment = xmlNewDocComment(doc, xmlCharStrdup("SALOME Launcher save jobs file"));
00985   xmlAddPrevSibling(root_node, doc_comment);
00986 
00987   // Step 3: For each job write it on the xml document
00988   // We could put a mutex but are not foing to do that currently
00989   std::map<int, Launcher::Job *> jobs_list = _l.getJobs();
00990   std::map<int, Launcher::Job *>::const_iterator it_job;
00991   for(it_job = jobs_list.begin(); it_job != jobs_list.end(); it_job++)
00992   {
00993     it_job->second->addToXmlDocument(root_node);
00994   }
00995 
00996   // Final step: write file
00997   int isOk = xmlSaveFormatFile(jobs_file, doc, 1);
00998   if (!isOk)
00999   {
01000     std::string error = "Error during xml file saving in SALOME_Launcher::saveJobs: " + std::string(jobs_file);
01001     INFOS(error);
01002     xmlFreeDoc(doc);
01003     fclose(xml_file);
01004     THROW_SALOME_CORBA_EXCEPTION(error.c_str(), SALOME::INTERNAL_ERROR);
01005   }
01006 
01007   // Clean
01008   xmlFreeDoc(doc);
01009   fclose(xml_file);
01010   MESSAGE("SALOME_Launcher::saveJobs : WRITING DONE!");
01011   notifyObservers("SAVE_JOBS", jobs_file);
01012 }
01013 
01014 //=============================================================================
01018 //=============================================================================
01019 void
01020 SALOME_Launcher::addObserver(Engines::SalomeLauncherObserver_ptr observer)
01021 {
01022   bool new_observer = true;
01023   std::list<Engines::SalomeLauncherObserver_var>::iterator iter = _observers.begin();
01024   while(iter != _observers.end())
01025   {
01026     if (std::string(_orb->object_to_string(*iter)) ==
01027         std::string(_orb->object_to_string(observer)))
01028     {
01029       new_observer = false;
01030       break;
01031     }
01032     iter++;
01033   }
01034   if (new_observer)
01035     _observers.push_back(Engines::SalomeLauncherObserver::_duplicate(observer));
01036 
01037   // We notify the new observer with all jobs that are currently in the Launcher
01038   std::map<int, Launcher::Job *> cpp_jobs = _l.getJobs();
01039   std::map<int, Launcher::Job *>::const_iterator it_job;
01040   for(it_job = cpp_jobs.begin(); it_job != cpp_jobs.end(); it_job++)
01041   {
01042     int number = it_job->first;
01043     std::ostringstream job_id;
01044     job_id << number;
01045     try
01046     {
01047       observer->notify("NEW_JOB", job_id.str().c_str());
01048     }
01049     catch (...) 
01050     {
01051        MESSAGE("Notify Observer, exception catch");
01052     }
01053 
01054   }
01055 }
01056 
01057 //=============================================================================
01061 //=============================================================================
01062 void
01063 SALOME_Launcher::removeObserver(Engines::SalomeLauncherObserver_ptr observer)
01064 {
01065   std::list<Engines::SalomeLauncherObserver_var>::iterator iter = _observers.begin();
01066   while(iter != _observers.end())
01067   {
01068     if (std::string(_orb->object_to_string(*iter)) ==
01069         std::string(_orb->object_to_string(observer)))
01070     {
01071       // Observer found
01072       iter =_observers.erase(iter++);
01073     }
01074     else
01075     {
01076       iter++;
01077     }
01078   }
01079 }
01080 
01081 //=============================================================================
01085 //=============================================================================
01086 void
01087 SALOME_Launcher::notifyObservers(const std::string & event_name,
01088                                  const std::string & event_data)
01089 {
01090   std::list<Engines::SalomeLauncherObserver_var>::iterator iter = _observers.begin();
01091   while(iter != _observers.end())
01092   {
01093     try
01094     {
01095       (*iter)->notify(CORBA::string_dup(event_name.c_str()),
01096                       CORBA::string_dup(event_data.c_str()));
01097     }
01098     catch (...) 
01099     {
01100        MESSAGE("Notify Observer, exception catch");
01101     }
01102     iter++;
01103   }
01104 
01105 }