Salome HOME
Merge remote branch 'origin/rbe/fix-resource-manager-thread-safe' into V7_5_BR
[modules/yacs.git] / src / Launcher / SALOME_Launcher.cxx
1 // Copyright (C) 2007-2014  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 "SALOME_Launcher.hxx"
24 #include "BatchTest.hxx"
25 #include "OpUtil.hxx"
26 #include "SALOME_ContainerManager.hxx"
27 #include "SALOME_ResourcesManager.hxx"
28 #include "Utils_CorbaException.hxx"
29
30
31 #include "Launcher_Job_Command.hxx"
32 #include "Launcher_Job_YACSFile.hxx"
33 #include "Launcher_Job_PythonSALOME.hxx"
34
35 #ifdef WIN32
36 # include <process.h>
37 #else
38 # include <unistd.h>
39 #endif
40 #include <sys/types.h>
41 #include <vector>
42 #include <list>
43
44 #include <stdio.h>
45 #include <sstream>
46
47 using namespace std;
48
49 const char *SALOME_Launcher::_LauncherNameInNS = "/SalomeLauncher";
50
51 //=============================================================================
52 /*! 
53  *  Constructor
54  *  \param orb
55  */
56 //=============================================================================
57 SALOME_Launcher::SALOME_Launcher(CORBA::ORB_ptr orb, PortableServer::POA_var poa) : _l()
58 {
59   MESSAGE("SALOME_Launcher constructor");
60   _NS = new SALOME_NamingService(orb);
61   _ResManager = new SALOME_ResourcesManager(orb,poa,_NS);
62   _l.SetResourcesManager(_ResManager->GetImpl());
63   _ContManager = new SALOME_ContainerManager(orb,poa,_NS);
64   _ResManager->_remove_ref();
65   _ContManager->_remove_ref();
66
67   _orb = CORBA::ORB::_duplicate(orb) ;
68   _poa = PortableServer::POA::_duplicate(poa) ;
69   PortableServer::ObjectId_var id = _poa->activate_object(this);
70   CORBA::Object_var obj = _poa->id_to_reference(id);
71   Engines::SalomeLauncher_var refContMan = Engines::SalomeLauncher::_narrow(obj);
72
73   _NS->Register(refContMan,_LauncherNameInNS);
74   MESSAGE("SALOME_Launcher constructor end");
75 }
76
77 //=============================================================================
78 /*! 
79  * destructor
80  */
81 //=============================================================================
82 SALOME_Launcher::~SALOME_Launcher()
83 {
84   MESSAGE("SALOME_Launcher destructor");
85   delete _NS;
86   MESSAGE("SALOME_Launcher destructor end");
87 }
88
89
90 CORBA::Long 
91 SALOME_Launcher::createJob(const Engines::JobParameters & job_parameters)
92 {
93   std::string job_type = job_parameters.job_type.in();
94
95   if (job_type != "command" && job_type != "yacs_file" && job_type != "python_salome")
96   {
97     std::string message("SALOME_Launcher::createJob: bad job type: ");
98     message += job_type;
99     THROW_SALOME_CORBA_EXCEPTION(message.c_str(), SALOME::INTERNAL_ERROR);
100   }
101
102   Launcher::Job * new_job; // It is Launcher_cpp that is going to destroy it
103
104   if (job_type == "command")
105     new_job = new Launcher::Job_Command();
106   else if (job_type == "yacs_file")
107     new_job = new Launcher::Job_YACSFile();
108   else if (job_type == "python_salome")
109     new_job = new Launcher::Job_PythonSALOME();
110
111   // Name
112   new_job->setJobName(job_parameters.job_name.in());
113
114   // Directories
115   std::string work_directory = job_parameters.work_directory.in();
116   std::string local_directory = job_parameters.local_directory.in();
117   std::string result_directory = job_parameters.result_directory.in();
118   new_job->setWorkDirectory(work_directory);
119   new_job->setLocalDirectory(local_directory);
120   new_job->setResultDirectory(result_directory);
121
122   // Parameters for COORM
123   std::string launcher_file = job_parameters.launcher_file.in();
124   std::string launcher_args = job_parameters.launcher_args.in();
125   new_job->setLauncherFile(launcher_file);
126   new_job->setLauncherArgs(launcher_args);
127
128   // Job File
129   std::string job_file = job_parameters.job_file.in();
130   try
131   {
132     new_job->setJobFile(job_file);
133   }
134   catch(const LauncherException &ex)
135   {
136     INFOS(ex.msg.c_str());
137     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
138   }
139
140   // Files
141   std::string env_file = job_parameters.env_file.in();
142   new_job->setEnvFile(env_file);
143   for (CORBA::ULong i = 0; i < job_parameters.in_files.length(); i++)
144     new_job->add_in_file(job_parameters.in_files[i].in());
145   for (CORBA::ULong i = 0; i < job_parameters.out_files.length(); i++)
146     new_job->add_out_file(job_parameters.out_files[i].in());
147
148   // Expected During Time
149   try
150   {
151     std::string maximum_duration = job_parameters.maximum_duration.in();
152     new_job->setMaximumDuration(maximum_duration);
153   }
154   catch(const LauncherException &ex){
155     INFOS(ex.msg.c_str());
156     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
157   }
158
159   // Queue
160   std::string queue = job_parameters.queue.in();
161   new_job->setQueue(queue);
162
163   // Exclusive
164   new_job->setExclusive(job_parameters.exclusive);
165
166   // Memory required per CPU
167   new_job->setMemPerCpu(job_parameters.mem_per_cpu);
168
169   // WC Key
170   std::string wckey = job_parameters.wckey.in();
171   new_job->setWCKey(wckey);
172
173   // Extra params
174   std::string extra_params = job_parameters.extra_params.in();
175   new_job->setExtraParams(extra_params);
176
177   // Resources requirements
178   try
179   {
180     resourceParams p;
181     p.name = job_parameters.resource_required.name;
182     p.hostname = job_parameters.resource_required.hostname;
183     p.OS = job_parameters.resource_required.OS;
184     p.nb_proc = job_parameters.resource_required.nb_proc;
185     p.nb_node = job_parameters.resource_required.nb_node;
186     p.nb_proc_per_node = job_parameters.resource_required.nb_proc_per_node;
187     p.cpu_clock = job_parameters.resource_required.cpu_clock;
188     p.mem_mb = job_parameters.resource_required.mem_mb;
189     new_job->setResourceRequiredParams(p);
190   }
191   catch(const LauncherException &ex){
192     INFOS(ex.msg.c_str());
193     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
194   }
195
196   // Adding specific parameters to the job
197   for (CORBA::ULong i = 0; i < job_parameters.specific_parameters.length(); i++)
198     new_job->addSpecificParameter(job_parameters.specific_parameters[i].name.in(),
199                                   job_parameters.specific_parameters[i].value.in());
200   try
201   {
202     new_job->checkSpecificParameters();
203   }
204   catch(const LauncherException &ex)
205   {
206     INFOS(ex.msg.c_str());
207     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
208   }
209
210   try
211   {
212     _l.createJob(new_job);
213     std::ostringstream job_id;
214     job_id << new_job->getNumber();
215     notifyObservers("NEW_JOB", job_id.str());
216   }
217   catch(const LauncherException &ex)
218   {
219     INFOS(ex.msg.c_str());
220     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
221   }
222   return new_job->getNumber();
223 }
224
225 void 
226 SALOME_Launcher::launchJob(CORBA::Long job_id)
227 {
228   try
229   {
230     _l.launchJob(job_id);
231   }
232   catch(const LauncherException &ex)
233   {
234     INFOS(ex.msg.c_str());
235     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
236   }
237 }
238
239 char *
240 SALOME_Launcher::getJobState(CORBA::Long job_id)
241 {
242   std::string result;
243   try
244   {
245     result = _l.getJobState(job_id);
246   }
247   catch(const LauncherException &ex)
248   {
249     INFOS(ex.msg.c_str());
250     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
251   }
252   return CORBA::string_dup(result.c_str());
253 }
254
255 // Get names or ids of hosts assigned to the job
256 char *
257 SALOME_Launcher::getAssignedHostnames(CORBA::Long job_id)
258 {
259   std::string result;
260   try
261   {
262     result = _l.getAssignedHostnames(job_id);
263   }
264   catch(const LauncherException &ex)
265   {
266     INFOS(ex.msg.c_str());
267     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
268   }
269   return CORBA::string_dup(result.c_str());
270 }
271
272 void
273 SALOME_Launcher::getJobResults(CORBA::Long job_id, const char * directory)
274 {
275   try
276   {
277     _l.getJobResults(job_id, directory);
278   }
279   catch(const LauncherException &ex)
280   {
281     INFOS(ex.msg.c_str());
282     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
283   }
284 }
285
286 CORBA::Boolean
287 SALOME_Launcher::getJobDumpState(CORBA::Long job_id, const char * directory)
288 {
289   CORBA::Boolean rtn = false;
290   try
291   {
292     rtn = _l.getJobDumpState(job_id, directory);
293   }
294   catch(const LauncherException &ex)
295   {
296     INFOS(ex.msg.c_str());
297     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
298   }
299   return rtn;
300 }
301
302 void 
303 SALOME_Launcher::removeJob(CORBA::Long job_id)
304 {
305   try
306   {
307     _l.removeJob(job_id);
308     std::ostringstream job_id_str;
309     job_id_str << job_id;
310     notifyObservers("REMOVE_JOB", job_id_str.str());
311   }
312   catch(const LauncherException &ex)
313   {
314     INFOS(ex.msg.c_str());
315     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
316   }
317 }
318
319 void 
320 SALOME_Launcher::stopJob(CORBA::Long job_id)
321 {
322   try
323   {
324     _l.stopJob(job_id);
325     std::ostringstream job_id_str;
326     job_id_str << job_id;
327     notifyObservers("UPDATE_JOB_STATE", job_id_str.str());
328   }
329   catch(const LauncherException &ex)
330   {
331     INFOS(ex.msg.c_str());
332     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::BAD_PARAM);
333   }
334 }
335
336 //=============================================================================
337 /*! CORBA Method:
338  *  Create a job in the launcher with a file
339  *  \param xmlExecuteFile     : .xml to parse that contains job description
340  *  \param clusterName        : machine choosed
341  */
342 //=============================================================================
343 CORBA::Long 
344 SALOME_Launcher::createJobWithFile(const char * xmlExecuteFile,
345                                    const char * clusterName)
346 {
347   CORBA::Long jobId;
348   try{
349     jobId = _l.createJobWithFile(xmlExecuteFile, clusterName);
350   }
351   catch(const LauncherException &ex){
352     INFOS(ex.msg.c_str());
353     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
354   }
355
356   return jobId;
357 }
358
359 //=============================================================================
360 /*! CORBA Method:
361  *  the test batch configuration 
362  *  \param params             : The batch cluster
363  */
364 //=============================================================================
365 CORBA::Boolean 
366 SALOME_Launcher::testBatch(const Engines::ResourceParameters& params)
367 {
368   MESSAGE("BEGIN OF SALOME_Launcher::testBatch");
369   CORBA::Boolean rtn = false;
370   try
371   {
372     // Consider only resources that can run batch jobs
373     Engines::ResourceParameters new_params(params);
374     new_params.can_launch_batch_jobs = true;
375
376     // find a resource matching the required parameters
377     Engines::ResourceList *aMachineList = _ResManager->GetFittingResources(new_params);
378     if (aMachineList->length() == 0)
379       throw SALOME_Exception("No resources have been found with your parameters");
380
381     const Engines::ResourceDefinition* p = _ResManager->GetResourceDefinition((*aMachineList)[0]);
382         std::string resource_name(p->name);
383     INFOS("Choose resource for test: " <<  resource_name);
384     
385     BatchTest t(*p);
386     if (t.test()) 
387     {
388       rtn = true;
389     }
390   }
391   catch(const LauncherException &ex){
392     INFOS(ex.msg.c_str());
393     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(),SALOME::INTERNAL_ERROR);
394   }
395   return rtn;
396 }
397
398 //=============================================================================
399 /*! CORBA method:
400  *  shutdown all the containers, then the ContainerManager servant
401  */
402 //=============================================================================
403 void SALOME_Launcher::Shutdown()
404 {
405   MESSAGE("Shutdown");
406   _NS->Destroy_Name(_LauncherNameInNS);
407   _ContManager->Shutdown();
408   _ResManager->Shutdown();
409   PortableServer::ObjectId_var oid = _poa->servant_to_id(this);
410   _poa->deactivate_object(oid);
411   if(!CORBA::is_nil(_orb))
412     _orb->shutdown(0);
413 }
414
415 //=============================================================================
416 /*! CORBA Method:
417  *  Returns the PID of the process
418  */
419 //=============================================================================
420 CORBA::Long SALOME_Launcher::getPID()
421 {
422   return 
423 #ifndef WIN32
424     (CORBA::Long)getpid();
425 #else
426     (CORBA::Long)_getpid();
427 #endif
428 }
429
430 //=============================================================================
431 /*! CORBA Method:
432  *  Returns current launcher jobs list
433  */
434 //=============================================================================
435 Engines::JobsList *
436 SALOME_Launcher::getJobsList()
437 {
438   Engines::JobsList_var jobs_list = new Engines::JobsList();
439   std::map<int, Launcher::Job *> cpp_jobs = _l.getJobs();
440   std::map<int, Launcher::Job *>::const_iterator it_job;
441   int list_id = 0;
442   for(it_job = cpp_jobs.begin(); it_job != cpp_jobs.end(); it_job++)
443   {
444     int number          = it_job->first;
445     try
446     {
447       // Prepare CORBA job description
448       Engines::JobDescription_var job_descr = new Engines::JobDescription();
449       Engines::JobParameters_var job_parameters = getJobParameters(number);
450       job_descr->job_id = number;
451       job_descr->job_parameters = job_parameters;
452
453       // Add job description to the sequence
454       jobs_list->length(list_id + 1);
455       jobs_list[list_id] = job_descr;
456       list_id++;
457     }
458     catch (...) {}
459   }
460   return jobs_list._retn();
461 }
462
463 //=============================================================================
464 /*! CORBA Method:
465  * Returns the job description
466  */
467 //=============================================================================
468 Engines::JobParameters *
469 SALOME_Launcher::getJobParameters(CORBA::Long job_id)
470 {
471   std::map<int, Launcher::Job *> cpp_jobs = _l.getJobs();
472   std::map<int, Launcher::Job *>::const_iterator it_job = cpp_jobs.find(job_id);
473   if (it_job == cpp_jobs.end())
474   {
475     INFOS("Cannot find the job, is it created ? job number: " << job_id);
476     THROW_SALOME_CORBA_EXCEPTION("Job does not exist", SALOME::INTERNAL_ERROR);
477   }
478
479   Launcher::Job * job = it_job->second;
480   Engines::JobParameters_var job_parameters = new Engines::JobParameters;
481   job_parameters->job_name         = CORBA::string_dup(job->getJobName().c_str());
482   job_parameters->job_type         = CORBA::string_dup(job->getJobType().c_str());
483   job_parameters->job_file         = CORBA::string_dup(job->getJobFile().c_str());
484   job_parameters->env_file         = CORBA::string_dup(job->getEnvFile().c_str());
485   job_parameters->work_directory   = CORBA::string_dup(job->getWorkDirectory().c_str());
486   job_parameters->local_directory  = CORBA::string_dup(job->getLocalDirectory().c_str());
487   job_parameters->result_directory = CORBA::string_dup(job->getResultDirectory().c_str());
488
489   // Parameters for COORM
490   job_parameters->launcher_file = CORBA::string_dup(job->getLauncherFile().c_str());
491   job_parameters->launcher_args = CORBA::string_dup(job->getLauncherArgs().c_str());
492
493   int i = 0;
494   int j = 0;
495   std::list<std::string> in_files  = job->get_in_files();
496   std::list<std::string> out_files = job->get_out_files();
497   job_parameters->in_files.length(in_files.size());
498   for(std::list<std::string>::iterator it = in_files.begin(); it != in_files.end(); it++)
499   {
500     job_parameters->in_files[i] = CORBA::string_dup((*it).c_str());
501     i++;
502   }
503   job_parameters->out_files.length(out_files.size());
504   for(std::list<std::string>::iterator it = out_files.begin(); it != out_files.end(); it++)
505   {
506     job_parameters->out_files[j] = CORBA::string_dup((*it).c_str());
507     j++;
508   }
509
510   job_parameters->maximum_duration = CORBA::string_dup(job->getMaximumDuration().c_str());
511   job_parameters->queue            = CORBA::string_dup(job->getQueue().c_str());
512   job_parameters->exclusive        = job->getExclusive();
513   job_parameters->mem_per_cpu      = job->getMemPerCpu();
514   job_parameters->wckey            = CORBA::string_dup(job->getWCKey().c_str());
515   job_parameters->extra_params     = CORBA::string_dup(job->getExtraParams().c_str());
516
517   resourceParams resource_params = job->getResourceRequiredParams();
518   job_parameters->resource_required.name             = CORBA::string_dup(resource_params.name.c_str());
519   job_parameters->resource_required.hostname         = CORBA::string_dup(resource_params.hostname.c_str());
520   job_parameters->resource_required.OS               = CORBA::string_dup(resource_params.OS.c_str());
521   job_parameters->resource_required.nb_proc          = resource_params.nb_proc;
522   job_parameters->resource_required.nb_node          = resource_params.nb_node;
523   job_parameters->resource_required.nb_proc_per_node = resource_params.nb_proc_per_node;
524   job_parameters->resource_required.cpu_clock        = resource_params.cpu_clock;
525   job_parameters->resource_required.mem_mb           = resource_params.mem_mb;
526
527   std::map<std::string, std::string> specific_parameters = job->getSpecificParameters();
528   if (!specific_parameters.empty())
529   {
530     job_parameters->specific_parameters.length(specific_parameters.size());
531     std::map<std::string, std::string>::const_iterator it_specific;
532     CORBA::ULong i = 0;
533     for (it_specific = specific_parameters.begin() ; it_specific != specific_parameters.end(); it_specific++)
534     {
535       Engines::Parameter_var new_param = new Engines::Parameter;
536       new_param->name  = CORBA::string_dup((it_specific->first).c_str());
537       new_param->value = CORBA::string_dup((it_specific->second).c_str());
538       job_parameters->specific_parameters[i] = new_param;
539       i++;
540     }
541   }
542
543   return job_parameters._retn();
544 }
545
546 //=============================================================================
547 /*! CORBA Method:
548  *  Loads jobs saved in jobs_file
549  */
550 //=============================================================================
551 void
552 SALOME_Launcher::loadJobs(const char* jobs_file)
553 {
554   list<int> new_jobs_id_list;
555   try
556   {
557     // Load the jobs in Launcher
558     new_jobs_id_list = _l.loadJobs(jobs_file);
559   }
560   catch (const LauncherException & ex)
561   {
562     INFOS(ex.msg.c_str());
563     THROW_SALOME_CORBA_EXCEPTION(ex.msg.c_str(), SALOME::INTERNAL_ERROR);
564   }
565
566   // Notify observers of the new jobs
567   list<int>::const_iterator it_jobs_id;
568   for (it_jobs_id = new_jobs_id_list.begin(); it_jobs_id != new_jobs_id_list.end(); it_jobs_id++)
569   {
570     ostringstream job_id_sstr;
571     job_id_sstr << *it_jobs_id;
572     notifyObservers("NEW_JOB", job_id_sstr.str());
573   }
574   notifyObservers("LOAD_JOBS", jobs_file);
575 }
576
577 //=============================================================================
578 /*! CORBA Method:
579  *  Save jobs of Launcher (in any steps) in file jobs_file
580  */
581 //=============================================================================
582 void
583 SALOME_Launcher::saveJobs(const char* jobs_file)
584 {
585   _l.saveJobs(jobs_file);
586   notifyObservers("SAVE_JOBS", jobs_file);
587 }
588
589 //=============================================================================
590 /*! CORBA Method:
591  *  Add a new observer to the launcher
592  */
593 //=============================================================================
594 void
595 SALOME_Launcher::addObserver(Engines::SalomeLauncherObserver_ptr observer)
596 {
597   bool new_observer = true;
598   std::list<Engines::SalomeLauncherObserver_var>::iterator iter = _observers.begin();
599   while(iter != _observers.end())
600   {
601     if (std::string(_orb->object_to_string(*iter)) ==
602         std::string(_orb->object_to_string(observer)))
603     {
604       new_observer = false;
605       break;
606     }
607     iter++;
608   }
609   if (new_observer)
610     _observers.push_back(Engines::SalomeLauncherObserver::_duplicate(observer));
611
612   // We notify the new observer with all jobs that are currently in the Launcher
613   std::map<int, Launcher::Job *> cpp_jobs = _l.getJobs();
614   std::map<int, Launcher::Job *>::const_iterator it_job;
615   for(it_job = cpp_jobs.begin(); it_job != cpp_jobs.end(); it_job++)
616   {
617     int number = it_job->first;
618     std::ostringstream job_id;
619     job_id << number;
620     try
621     {
622       observer->notify("NEW_JOB", job_id.str().c_str());
623     }
624     catch (...) 
625     {
626        MESSAGE("Notify Observer, exception catch");
627     }
628
629   }
630 }
631
632 //=============================================================================
633 /*! CORBA Method:
634  *  Add a new observer to the launcher
635  */
636 //=============================================================================
637 void
638 SALOME_Launcher::removeObserver(Engines::SalomeLauncherObserver_ptr observer)
639 {
640   std::list<Engines::SalomeLauncherObserver_var>::iterator iter = _observers.begin();
641   while(iter != _observers.end())
642   {
643     if (std::string(_orb->object_to_string(*iter)) ==
644         std::string(_orb->object_to_string(observer)))
645     {
646       // Observer found
647       iter =_observers.erase(iter++);
648     }
649     else
650     {
651       iter++;
652     }
653   }
654 }
655
656 //=============================================================================
657 /*! Internal Method:
658  *  Notify observers on a new event
659  */
660 //=============================================================================
661 void
662 SALOME_Launcher::notifyObservers(const std::string & event_name,
663                                  const std::string & event_data)
664 {
665   std::list<Engines::SalomeLauncherObserver_var>::iterator iter = _observers.begin();
666   while(iter != _observers.end())
667   {
668     try
669     {
670       (*iter)->notify(CORBA::string_dup(event_name.c_str()),
671                       CORBA::string_dup(event_data.c_str()));
672     }
673     catch (...) 
674     {
675        MESSAGE("Notify Observer, exception catch");
676     }
677     iter++;
678   }
679
680 }