1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <libxml/parser.h>
25 #include "Launcher_XML_Persistence.hxx"
26 #include "Launcher_Job_Command.hxx"
27 #include "Launcher_Job_YACSFile.hxx"
28 #include "Launcher_Job_PythonSALOME.hxx"
29 #include "Launcher_Job_Writer.hxx"
37 XML_Persistence::loadJobs(const char* jobs_file)
39 // Step 1: check jobs_file read access
40 FILE* xml_file = fopen(jobs_file, "r");
43 std::string error = "Error opening jobs_file in SALOME_Launcher::loadJobs: " + std::string(jobs_file);
44 LAUNCHER_INFOS(error);
45 throw LauncherException(error);
48 // Step 2: read xml file
49 xmlDocPtr doc = xmlReadFile(jobs_file, NULL, 0);
52 std::string error = "Error in xmlReadFile in SALOME_Launcher::loadJobs, could not parse file: " + std::string(jobs_file);
53 LAUNCHER_INFOS(error);
55 throw LauncherException(error);
59 list<Job *> jobs_list;
60 xmlNodePtr root_node = xmlDocGetRootElement(doc);
61 xmlNodePtr xmlCurrentNode = root_node->xmlChildrenNode;
62 if (!xmlStrcmp(root_node->name, xmlCharStrdup("jobs")))
64 while(xmlCurrentNode != NULL)
66 if (!xmlStrcmp(xmlCurrentNode->name, xmlCharStrdup("job")))
68 LAUNCHER_INFOS("A job is found");
69 Launcher::Job * new_job; // It is Launcher_cpp that is going to destroy it
70 xmlNodePtr job_node = xmlCurrentNode;
73 if (!xmlHasProp(job_node, xmlCharStrdup("type")) ||
74 !xmlHasProp(job_node, xmlCharStrdup("name")))
76 LAUNCHER_INFOS("A bad job is found, type or name not found");
79 xmlChar* type = xmlGetProp(job_node, xmlCharStrdup("type"));
80 xmlChar* name = xmlGetProp(job_node, xmlCharStrdup("name"));
81 std::string job_type((const char*) type);
82 if (job_type == "command")
83 new_job = new Launcher::Job_Command();
84 else if (job_type == "yacs_file")
85 new_job = new Launcher::Job_YACSFile();
86 else if (job_type == "python_salome")
87 new_job = new Launcher::Job_PythonSALOME();
88 new_job->setJobName(std::string((const char *)name));
92 xmlNodePtr user_node = xmlFirstElementChild(job_node);
93 xmlNodePtr run_node = xmlNextElementSibling(user_node);
94 if (user_node == NULL || run_node == NULL)
96 LAUNCHER_INFOS("A bad job is found, user_part or run_part not found");
100 if (xmlStrcmp(user_node->name, xmlCharStrdup("user_part")) ||
101 xmlStrcmp(run_node->name, xmlCharStrdup("run_part")))
103 LAUNCHER_INFOS("A bad job is found, cannot get a correct user_part or run_part node");
110 // Get job_file env_file work_directory local_directory result_directory
111 xmlNodePtr job_file_node = xmlFirstElementChild(user_node);
112 xmlNodePtr env_file_node = xmlNextElementSibling(job_file_node);
113 xmlNodePtr work_directory_node = xmlNextElementSibling(env_file_node);
114 xmlNodePtr local_directory_node = xmlNextElementSibling(work_directory_node);
115 xmlNodePtr result_directory_node = xmlNextElementSibling(local_directory_node);
117 // Parameters for COORM
118 xmlNodePtr launcher_file_node = xmlNextElementSibling(result_directory_node);
120 if (job_file_node == NULL ||
121 env_file_node == NULL ||
122 work_directory_node == NULL ||
123 local_directory_node == NULL ||
124 result_directory_node == NULL ||
126 launcher_file_node == NULL
129 LAUNCHER_INFOS("A bad job is found, some user_part are not found");
133 if (xmlStrcmp(job_file_node->name, xmlCharStrdup("job_file")) ||
134 xmlStrcmp(env_file_node->name, xmlCharStrdup("env_file")) ||
135 xmlStrcmp(work_directory_node->name, xmlCharStrdup("work_directory")) ||
136 xmlStrcmp(local_directory_node->name, xmlCharStrdup("local_directory")) ||
137 xmlStrcmp(result_directory_node->name, xmlCharStrdup("result_directory")) ||
139 xmlStrcmp(launcher_file_node->name, xmlCharStrdup("launcher_file"))
142 LAUNCHER_INFOS("A bad job is found, some user part node are not in the rigth or does not have a correct name");
146 xmlChar* job_file = xmlNodeGetContent(job_file_node);
149 new_job->setJobFile(std::string((const char *)job_file));
151 catch(const LauncherException &ex)
153 LAUNCHER_INFOS("Exception receice for job_file, cannot add the job" << ex.msg.c_str());
158 xmlChar* env_file = xmlNodeGetContent(env_file_node);
159 xmlChar* work_directory = xmlNodeGetContent(work_directory_node);
160 xmlChar* local_directory = xmlNodeGetContent(local_directory_node);
161 xmlChar* result_directory = xmlNodeGetContent(result_directory_node);
163 // Parameters for COORM
164 xmlChar* launcher_file = xmlNodeGetContent(launcher_file_node);
166 new_job->setEnvFile(std::string((const char *)env_file));
167 new_job->setWorkDirectory(std::string((const char *)work_directory));
168 new_job->setLocalDirectory(std::string((const char *)local_directory));
169 new_job->setResultDirectory(std::string((const char *)result_directory));
171 // Parameters for COORM
172 new_job->setLauncherFile(std::string((const char *)launcher_file));
176 xmlFree(work_directory);
177 xmlFree(local_directory);
178 xmlFree(result_directory);
180 // Parameters for COORM
181 xmlFree(launcher_file);
183 // Get in and out files
184 xmlNodePtr files_node = xmlNextElementSibling(launcher_file_node);
185 if (files_node == NULL)
187 LAUNCHER_INFOS("A bad job is found, user_part files is not found");
191 if (xmlStrcmp(files_node->name, xmlCharStrdup("files")))
193 LAUNCHER_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");
197 xmlNodePtr file_node = xmlFirstElementChild(files_node);
198 while (file_node != NULL)
200 if (!xmlStrcmp(file_node->name, xmlCharStrdup("in_file")))
202 xmlChar* in_file = xmlNodeGetContent(file_node);
203 new_job->add_in_file(std::string((const char *)in_file));
206 else if (!xmlStrcmp(file_node->name, xmlCharStrdup("out_file")))
208 xmlChar* out_file = xmlNodeGetContent(file_node);
209 new_job->add_out_file(std::string((const char *)out_file));
212 file_node = xmlNextElementSibling(file_node);
216 xmlNodePtr res_node = xmlNextElementSibling(files_node);
217 xmlNodePtr maximum_duration_node = xmlNextElementSibling(res_node);
218 xmlNodePtr queue_node = xmlNextElementSibling(maximum_duration_node);
219 xmlNodePtr exclusive_node = xmlNextElementSibling(queue_node);
220 xmlNodePtr mem_per_cpu_node = xmlNextElementSibling(exclusive_node);
221 xmlNodePtr launcher_args_node = xmlNextElementSibling(mem_per_cpu_node);
222 if (res_node == NULL ||
223 maximum_duration_node == NULL ||
224 queue_node == NULL ||
225 exclusive_node == NULL ||
226 mem_per_cpu_node == NULL ||
228 launcher_args_node == NULL
231 LAUNCHER_INFOS("A bad job is found, some user_part are not found");
235 if (xmlStrcmp(res_node->name, xmlCharStrdup("resource_params")) ||
236 xmlStrcmp(maximum_duration_node->name, xmlCharStrdup("maximum_duration")) ||
237 xmlStrcmp(queue_node->name, xmlCharStrdup("queue")) ||
238 xmlStrcmp(exclusive_node->name, xmlCharStrdup("exclusive")) ||
239 xmlStrcmp(mem_per_cpu_node->name, xmlCharStrdup("mem_per_cpu")) ||
241 xmlStrcmp(launcher_args_node->name, xmlCharStrdup("launcher_args"))
244 LAUNCHER_INFOS("A bad job is found, some user part node are not in the rigth or does not have a correct name");
248 xmlChar* maximum_duration = xmlNodeGetContent(maximum_duration_node);
251 new_job->setMaximumDuration(std::string((const char *)maximum_duration));
253 catch(const LauncherException &ex)
255 LAUNCHER_INFOS("Exception receice for maximum_duration, cannot add the job" << ex.msg.c_str());
257 xmlFree(maximum_duration);
260 xmlChar* queue = xmlNodeGetContent(queue_node);
261 new_job->setQueue(std::string((const char *)queue));
262 xmlFree(maximum_duration);
265 xmlChar* exclusive = xmlNodeGetContent(exclusive_node);
268 new_job->setExclusiveStr(std::string((const char *)exclusive));
270 catch(const LauncherException &ex)
272 LAUNCHER_INFOS("Exception received for exclusive, cannot add the job. " << ex.msg.c_str());
279 xmlChar* mem_per_cpu_str = xmlNodeGetContent(mem_per_cpu_node);
280 std::istringstream mem_per_cpu_stream((const char *)mem_per_cpu_str);
281 unsigned long mem_per_cpu = 0;
282 if (!(mem_per_cpu_stream >> mem_per_cpu))
284 LAUNCHER_INFOS("A bad job is found, mem_per_cpu parameter is not correct");
289 new_job->setMemPerCpu(mem_per_cpu);
292 xmlChar* launcher_args = xmlNodeGetContent(launcher_args_node);
293 new_job->setLauncherArgs(std::string((const char *)launcher_args));
294 xmlFree(launcher_args);
296 xmlNodePtr specific_node = xmlNextElementSibling(launcher_args_node);
297 if (specific_node == NULL)
299 LAUNCHER_INFOS("A bad job is found, specific_parameters part is not found");
303 xmlNodePtr parameter_node = xmlFirstElementChild(specific_node);
304 while (parameter_node != NULL)
306 if (!xmlStrcmp(parameter_node->name, xmlCharStrdup("specific_parameter")))
308 xmlNodePtr name_node = xmlFirstElementChild(parameter_node);
309 xmlNodePtr value_node = xmlNextElementSibling(name_node);
310 if (name_node == NULL ||
313 LAUNCHER_INFOS("A bad job is found, specific_parameter parts are not found");
317 if (xmlStrcmp(name_node->name, xmlCharStrdup("name")) ||
318 xmlStrcmp(value_node->name, xmlCharStrdup("value")))
320 LAUNCHER_INFOS("A bad job is found, specific_parameter bad parts are found");
325 xmlChar* name = xmlNodeGetContent(name_node);
326 xmlChar* value = xmlNodeGetContent(value_node);
329 new_job->addSpecificParameter(std::string((const char*)name), std::string((const char*)value));
333 catch(const LauncherException &ex)
335 LAUNCHER_INFOS("Exception receice for a specific parameter, cannot add the job" << ex.msg.c_str());
344 LAUNCHER_INFOS("A bad job is found, specific_parameters part is bad, a node that is not a specific parameter is found");
348 parameter_node = xmlNextElementSibling(parameter_node);
351 xmlNodePtr res_name_node = xmlFirstElementChild(res_node);
352 xmlNodePtr res_hostname_node = xmlNextElementSibling(res_name_node);
353 xmlNodePtr res_os_node = xmlNextElementSibling(res_hostname_node);
354 xmlNodePtr res_nb_proc_node = xmlNextElementSibling(res_os_node);
355 xmlNodePtr res_nb_node_node = xmlNextElementSibling(res_nb_proc_node);
356 xmlNodePtr res_nb_proc_per_node_node = xmlNextElementSibling(res_nb_node_node);
357 xmlNodePtr res_cpu_clock_node = xmlNextElementSibling(res_nb_proc_per_node_node);
358 xmlNodePtr res_mem_mb_node = xmlNextElementSibling(res_cpu_clock_node);
359 if (res_name_node == NULL ||
360 res_hostname_node == NULL ||
361 res_os_node == NULL ||
362 res_nb_proc_node == NULL ||
363 res_nb_node_node == NULL ||
364 res_nb_proc_per_node_node == NULL ||
365 res_cpu_clock_node == NULL ||
366 res_mem_mb_node == NULL
369 LAUNCHER_INFOS("A bad job is found, some resource_params user_part are not found");
373 if (xmlStrcmp(res_name_node->name, xmlCharStrdup("name")) ||
374 xmlStrcmp(res_hostname_node->name, xmlCharStrdup("hostname")) ||
375 xmlStrcmp(res_os_node->name, xmlCharStrdup("OS")) ||
376 xmlStrcmp(res_nb_proc_node->name, xmlCharStrdup("nb_proc")) ||
377 xmlStrcmp(res_nb_node_node->name, xmlCharStrdup("nb_node")) ||
378 xmlStrcmp(res_nb_proc_per_node_node->name, xmlCharStrdup("nb_proc_per_node")) ||
379 xmlStrcmp(res_cpu_clock_node->name, xmlCharStrdup("cpu_clock")) ||
380 xmlStrcmp(res_mem_mb_node->name, xmlCharStrdup("mem_mb"))
383 LAUNCHER_INFOS("A bad job is found, some resource_params user_part node are not in the rigth or does not have a correct name");
387 xmlChar* res_name = xmlNodeGetContent(res_name_node);
388 xmlChar* res_hostname = xmlNodeGetContent(res_hostname_node);
389 xmlChar* res_os = xmlNodeGetContent(res_os_node);
391 p.name = std::string((const char*) res_name);
392 p.hostname = std::string((const char*) res_hostname);
393 p.OS = std::string((const char*) res_os);
395 xmlFree(res_hostname);
397 xmlChar* res_nb_proc = xmlNodeGetContent(res_nb_proc_node);
398 xmlChar* res_nb_node = xmlNodeGetContent(res_nb_node_node);
399 xmlChar* res_nb_proc_per_node = xmlNodeGetContent(res_nb_proc_per_node_node);
400 xmlChar* res_cpu_clock = xmlNodeGetContent(res_cpu_clock_node);
401 xmlChar* res_mem_mb = xmlNodeGetContent(res_mem_mb_node);
402 bool import_value = true;
403 std::istringstream nb_proc_stream((const char *) res_nb_proc);
404 if (!(nb_proc_stream >> p.nb_proc))
405 import_value = false;
406 std::istringstream nb_node_stream((const char *) res_nb_node);
407 if (!(nb_node_stream >> p.nb_node))
408 import_value = false;
409 std::istringstream nb_proc_per_node_stream((const char *) res_nb_proc_per_node);
410 if (!(nb_proc_per_node_stream >> p.nb_proc_per_node))
411 import_value = false;
412 std::istringstream cpu_clock_stream((const char *) res_cpu_clock);
413 if (!(cpu_clock_stream >> p.cpu_clock))
414 import_value = false;
415 std::istringstream mem_mb_stream((const char *) res_mem_mb);
416 if (!(mem_mb_stream >> p.mem_mb))
417 import_value = false;
418 xmlFree(res_nb_proc);
419 xmlFree(res_nb_node);
420 xmlFree(res_nb_proc_per_node);
421 xmlFree(res_cpu_clock);
425 LAUNCHER_INFOS("A bad job is found, some resource_params value are not correct");
431 new_job->setResourceRequiredParams(p);
433 catch(const LauncherException &ex)
435 LAUNCHER_INFOS("A bad job is found, an error when inserting resource_params:" << ex.msg.c_str());
440 // We finally get run part to figure out what to do
441 xmlNodePtr job_state_node = xmlFirstElementChild(run_node);
442 xmlNodePtr resource_choosed_name_node = xmlNextElementSibling(job_state_node);
443 xmlNodePtr job_reference_node = xmlNextElementSibling(resource_choosed_name_node);
444 if (job_state_node == NULL ||
445 resource_choosed_name_node == NULL ||
446 job_reference_node == NULL
449 LAUNCHER_INFOS("A bad job is found, some run_part are not found");
453 if (xmlStrcmp(job_state_node->name, xmlCharStrdup("job_state")) ||
454 xmlStrcmp(resource_choosed_name_node->name, xmlCharStrdup("resource_choosed_name")) ||
455 xmlStrcmp(job_reference_node->name, xmlCharStrdup("job_reference"))
458 LAUNCHER_INFOS("A bad job is found, some run_part nodes are not in the rigth or does not have a correct name");
462 xmlChar* job_state_xml = xmlNodeGetContent(job_state_node);
463 xmlChar* resource_choosed_name_xml = xmlNodeGetContent(resource_choosed_name_node);
464 xmlChar* job_reference_xml = xmlNodeGetContent(job_reference_node);
465 std::string job_state((const char *) job_state_xml);
466 std::string resource_choosed_name((const char *) resource_choosed_name_xml);
467 std::string job_reference((const char *) job_reference_xml);
468 xmlFree(job_state_xml);
469 xmlFree(resource_choosed_name_xml);
470 xmlFree(job_reference_xml);
471 new_job->setState(job_state);
472 new_job->setReference(job_reference);
474 jobs_list.push_back(new_job);
476 xmlCurrentNode = xmlCurrentNode->next;
483 std::string error = "Error in xml file, could not find root_node named jobs: " + std::string(jobs_file);
484 LAUNCHER_INFOS(error);
485 throw LauncherException(error);
496 XML_Persistence::saveJobs(const char* jobs_file, const list<const Job *> & jobs_list)
498 // Step 1: check jobs_file write access
499 FILE* xml_file = fopen(jobs_file, "w");
500 if (xml_file == NULL)
502 std::string error = "Error opening jobs_file in SALOME_Launcher::saveJobs: " + std::string(jobs_file);
503 LAUNCHER_INFOS(error);
504 throw LauncherException(error);
507 // Step 2: First lines
508 xmlKeepBlanksDefault(0);
509 xmlDocPtr doc = xmlNewDoc(xmlCharStrdup("1.0"));
510 xmlNodePtr root_node = xmlNewNode(NULL, xmlCharStrdup("jobs"));
511 xmlDocSetRootElement(doc, root_node);
512 xmlNodePtr doc_comment = xmlNewDocComment(doc, xmlCharStrdup("SALOME Launcher save jobs file"));
513 xmlAddPrevSibling(root_node, doc_comment);
515 // Step 3: For each job write it on the xml document
516 // We could put a mutex but are not foing to do that currently
517 list<const Job *>::const_iterator it_job;
518 for (it_job = jobs_list.begin(); it_job != jobs_list.end(); it_job++)
520 addToXmlDocument(root_node, *it_job);
523 // Final step: write file
524 int isOk = xmlSaveFormatFile(jobs_file, doc, 1);
527 std::string error = "Error during xml file saving in SALOME_Launcher::saveJobs: " + std::string(jobs_file);
528 LAUNCHER_INFOS(error);
531 throw LauncherException(error);
537 LAUNCHER_MESSAGE("SALOME_Launcher::saveJobs : WRITING DONE!");