Salome HOME
CMake: fixed minor bug: when a _ROOT_DIR variable was set by the user after
[modules/kernel.git] / src / LifeCycleCORBA / SALOME_LifeCycleCORBA.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 //  SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++
24 //  File   : SALOME_LifeCycleCORBA.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SALOME
27
28 #include <iostream>
29 #include <fstream>
30 #include <sstream>
31 #include <iomanip>
32
33 #include <time.h>
34 #ifndef WIN32
35   #include <sys/time.h>
36   #include <unistd.h>
37 #endif
38
39 #include "Basics_Utils.hxx"
40 #include "utilities.h"
41
42 #include <ServiceUnreachable.hxx>
43
44 #include "SALOME_LifeCycleCORBA.hxx"
45 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
46 #include CORBA_CLIENT_HEADER(SALOME_Session)
47 #include CORBA_CLIENT_HEADER(DSC_Engines)
48 #include CORBA_CLIENT_HEADER(SALOME_Registry)
49 #include CORBA_CLIENT_HEADER(SALOMEDS)
50 #include CORBA_CLIENT_HEADER(Logger)
51 #include CORBA_CLIENT_HEADER(SALOME_Launcher)
52
53 #include "SALOME_ContainerManager.hxx"
54 #include "SALOME_Component_i.hxx"
55 #include "SALOME_NamingService.hxx"
56 #include "SALOME_FileTransferCORBA.hxx"
57
58 IncompatibleComponent::IncompatibleComponent( void ):
59   SALOME_Exception( "IncompatibleComponent" )
60 {
61 }
62
63 IncompatibleComponent::IncompatibleComponent(const IncompatibleComponent &ex):
64   SALOME_Exception( ex )
65 {
66 }
67
68 /*! \class SALOME_LifeCycleCORBA
69     \brief A class to manage life cycle of SALOME components.
70
71 */
72
73 //=============================================================================
74 /*!
75  *  Constructor
76  */
77 //=============================================================================
78
79 SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns)
80 {
81   // be sure to have an instance of traceCollector, when used via SWIG
82   // in a Python module
83   int argc = 0;
84   char *xargv = (char*)"";
85   char **argv = &xargv;
86   CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
87   //  LocalTraceCollector *myThreadTrace = SALOMETraceCollector::instance(orb);
88   _NSnew=0;
89   if (!ns)
90     {
91       _NS = new SALOME_NamingService(orb);
92       _NSnew=_NS;
93     }
94   else _NS = ns;
95   //add try catch
96   _NS->Change_Directory("/"); // mpv 250105: current directory may be not root
97                               // (in SALOMEDS for an example)
98   // not enough: set a current directory in naming service is not thread safe
99   // if naming service instance is shared among several threads...
100   // ==> allways use absolute path and dot rely on current directory!
101
102   CORBA::Object_var obj =
103     _NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
104   if (CORBA::is_nil(obj))
105     throw SALOME_Exception("Error: Cannot resolve ContainerManager in Naming Service");
106   _ContManager=Engines::ContainerManager::_narrow(obj);
107
108   obj = _NS->Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS);
109   if (CORBA::is_nil(obj))
110     throw SALOME_Exception("Error: Cannot resolve ResourceManager in Naming Service");
111   _ResManager=Engines::ResourcesManager::_narrow(obj);
112 }
113
114 //=============================================================================
115 /*!
116  *  Destructor
117  */
118 //=============================================================================
119
120 SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA()
121 {
122   if(_NSnew)delete _NSnew;
123 }
124
125 //=============================================================================
126 /*! \brief Find an already existing and registered component instance.
127  *
128  *  \param params         container parameters like type or name...
129  *  \param componentName  the name of component class
130  *  \param studyId        default = 0  : multistudy instance
131  *  \return a CORBA reference of the component instance, or _nil if not found
132  */
133 //=============================================================================
134 Engines::EngineComponent_ptr
135 SALOME_LifeCycleCORBA::FindComponent(const Engines::ContainerParameters& params,
136                                      const char *componentName,
137                                      int studyId)
138 {
139   if (! isKnownComponentClass(componentName))
140     return Engines::EngineComponent::_nil();
141
142   Engines::ContainerParameters new_params(params);
143   new_params.resource_params.componentList.length(1);
144   new_params.resource_params.componentList[0] = componentName;
145   new_params.resource_params.can_run_containers = true;
146   Engines::ResourceList_var listOfResources;
147   try
148     {
149       listOfResources = _ResManager->GetFittingResources(new_params.resource_params);
150     }
151   catch( const SALOME::SALOME_Exception& ex )
152     {
153       return Engines::EngineComponent::_nil();
154     }
155
156   Engines::EngineComponent_var compo = _FindComponent(new_params,
157                                                 componentName,
158                                                 studyId,
159                                                 listOfResources);
160
161   return compo._retn();
162 }
163
164 //=============================================================================
165 /*! \brief Load a component instance on a container defined by its parameters
166  *
167  *  \param params         container parameters like type or name...
168  *  \param componentName  the name of component class
169  *  \param studyId        default = 0  : multistudy instance
170  *  \return a CORBA reference of the component instance, or _nil if problem
171  */
172 //=============================================================================
173
174 Engines::EngineComponent_ptr
175 SALOME_LifeCycleCORBA::LoadComponent(const Engines::ContainerParameters& params,
176                                      const char *componentName,
177                                      int studyId)
178 {
179   // --- Check if Component Name is known in ModuleCatalog
180
181   if (! isKnownComponentClass(componentName))
182     return Engines::EngineComponent::_nil();
183
184   Engines::ContainerParameters new_params(params);
185   new_params.resource_params.componentList.length(1);
186   new_params.resource_params.componentList[0] = componentName;
187   new_params.resource_params.can_run_containers = true;
188
189   Engines::ResourceList_var listOfResources;
190   try
191     {
192       listOfResources = _ResManager->GetFittingResources(new_params.resource_params);
193     }
194   catch( const SALOME::SALOME_Exception& ex )
195     {
196       return Engines::EngineComponent::_nil();
197     }
198   new_params.resource_params.resList = listOfResources;
199
200   Engines::EngineComponent_var compo = _LoadComponent(new_params,
201                                                 componentName,
202                                                 studyId);
203
204   return compo._retn();
205 }
206
207 //=============================================================================
208 /*! \brief Find an already existing and registered component instance or load a new
209  *         component instance on a container defined by its parameters.
210  *
211  *  \param params         container parameters like type or name...
212  *  \param componentName  the name of component class
213  *  \param studyId        default = 0  : multistudy instance
214  *  \return a CORBA reference of the component instance, or _nil if problem
215  */
216 //=============================================================================
217
218 Engines::EngineComponent_ptr
219 SALOME_LifeCycleCORBA::
220 FindOrLoad_Component(const Engines::ContainerParameters& params,
221                      const char *componentName,
222                      int studyId)
223 {
224   // --- Check if Component Name is known in ModuleCatalog
225
226   if (! isKnownComponentClass(componentName))
227     return Engines::EngineComponent::_nil();
228
229   Engines::ContainerParameters new_params(params);
230   new_params.resource_params.componentList.length(1);
231   new_params.resource_params.componentList[0] = componentName;
232   new_params.resource_params.can_run_containers = true;
233
234   Engines::ResourceList_var listOfResources;
235   try
236     {
237       listOfResources = _ResManager->GetFittingResources(new_params.resource_params);
238     }
239   catch( const SALOME::SALOME_Exception& ex )
240     {
241       return Engines::EngineComponent::_nil();
242     }
243
244   Engines::EngineComponent_var compo = _FindComponent(new_params,
245                                                 componentName,
246                                                 studyId,
247                                                 listOfResources);
248
249   if(CORBA::is_nil(compo))
250   {
251     new_params.resource_params.resList = listOfResources;
252     compo = _LoadComponent(new_params,
253                            componentName,
254                            studyId);
255   }
256
257   return compo._retn();
258 }
259
260 //=============================================================================
261 /*! \brief Find an already existing and registered component instance or load a new
262  *         component instance on a container defined by name
263  *
264  *  \param containerName  the name of container, under one of the forms
265  *           - 1 aContainer (local container)
266  *           - 2 machine/aContainer (container on hostname = machine)
267  *  \param componentName  the name of component class
268  *  \return a CORBA reference of the component instance, or _nil if problem
269  */
270 //=============================================================================
271
272 Engines::EngineComponent_ptr
273 SALOME_LifeCycleCORBA::FindOrLoad_Component(const char *containerName,
274                                             const char *componentName)
275 {
276   MESSAGE("SALOME_LifeCycleCORBA::FindOrLoad_Component INTERACTIF " << containerName << " " << componentName ) ;
277
278   // --- Check if Component Name is known in ModuleCatalog
279   if (! isKnownComponentClass(componentName))
280     return Engines::EngineComponent::_nil();
281
282   // --- Check if containerName contains machine name (if yes: rg>0)
283   char *stContainer=strdup(containerName);
284   std::string st2Container(stContainer);
285   int rg=st2Container.find("/");
286
287   Engines::ContainerParameters params;
288   preSet(params);
289   if (rg<0)
290   {
291     // containerName doesn't contain "/" => Local container
292     params.container_name = CORBA::string_dup(stContainer);
293   }
294   else
295   {
296     stContainer[rg]='\0';
297     params.container_name = CORBA::string_dup(stContainer+rg+1);
298     params.resource_params.hostname = CORBA::string_dup(stContainer);
299   }
300   params.isMPI = false;
301   SCRUTE(params.container_name);
302   free(stContainer);
303   return FindOrLoad_Component(params, componentName);
304 }
305
306 //=============================================================================
307 /*! \brief Check if the component class is known in module catalog
308  *
309  *  \param componentName  the name of component class
310  *  \return true if found, false otherwise
311  */
312 //=============================================================================
313
314 bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName)
315 {
316   try
317   {
318     CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
319     SALOME_ModuleCatalog::ModuleCatalog_var Catalog =
320       SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
321     ASSERT(! CORBA::is_nil(Catalog));
322     SALOME_ModuleCatalog::Acomponent_var compoInfo =
323       Catalog->GetComponent(componentName);
324     if (CORBA::is_nil (compoInfo))
325     {
326       MESSAGE("Catalog Error: Component not found in the catalog " << componentName);
327       return false;
328     }
329     else return true;
330   }
331   catch (ServiceUnreachable&)
332   {
333     INFOS("Caught exception: Naming Service Unreachable");
334   }
335   catch (...)
336   {
337     INFOS("Caught unknown exception.");
338   }
339   return false;
340 }
341
342 //=============================================================================
343 /*! \brief Initialisation of a given Engines::ResourceParameters with default values.
344  */
345 //=============================================================================
346
347 void
348 SALOME_LifeCycleCORBA::preSet(Engines::ResourceParameters& params)
349 {
350   params.name = "";
351   params.hostname = "";
352   params.OS = "";
353   params.nb_proc = 0;
354   params.mem_mb = 0;
355   params.cpu_clock = 0;
356   params.nb_node = 0;
357   params.nb_proc_per_node = 0;
358   params.policy = "";
359   params.can_launch_batch_jobs = false;
360   params.can_run_containers = false;
361 }
362
363 //=============================================================================
364 /*! \brief Initialisation of a given Engines::ContainerParameters with default values.
365  */
366 //=============================================================================
367
368 void SALOME_LifeCycleCORBA::preSet( Engines::ContainerParameters& params)
369 {
370   params.container_name = "";
371   params.mode = "";
372   params.workingdir = "";
373   params.nb_proc = 0;
374   params.isMPI = false;
375   params.parallelLib = "";
376   SALOME_LifeCycleCORBA::preSet(params.resource_params);
377 }
378
379 //=============================================================================
380 /*!
381  *  \return a number of processors not 0, only for MPI containers
382  */
383 //=============================================================================
384
385 int SALOME_LifeCycleCORBA::NbProc(const Engines::ContainerParameters& params)
386 {
387   if( !params.isMPI )
388     return 0;
389   else if( params.nb_proc <= 0 )
390     return 1;
391   else
392     return params.nb_proc;
393 }
394
395 //=============================================================================
396 /*! \brief Get the container manager
397  *
398  *  \return the container Manager
399  */
400 //=============================================================================
401
402 Engines::ContainerManager_ptr SALOME_LifeCycleCORBA::getContainerManager()
403 {
404  Engines::ContainerManager_var contManager =
405    Engines::ContainerManager::_duplicate(_ContManager);
406  return contManager._retn();
407 }
408
409 //=============================================================================
410 /*! \brief Get the resources manager
411  *
412  *  \return the container Manager
413  */
414 //=============================================================================
415
416 Engines::ResourcesManager_ptr SALOME_LifeCycleCORBA::getResourcesManager()
417 {
418  Engines::ResourcesManager_var resManager =
419    Engines::ResourcesManager::_duplicate(_ResManager);
420  return resManager._retn();
421 }
422
423 //=============================================================================
424 /*! \brief shutdown all the SALOME servers except SALOME_Session_Server, omniNames and notifd
425  */
426 //=============================================================================
427
428 void SALOME_LifeCycleCORBA::shutdownServers()
429 {
430   // get each Container from NamingService => shutdown it
431   // (the order is inverse to the order of servers initialization)
432
433   SALOME::Session_var session = SALOME::Session::_nil();
434   CORBA::Long pid = 0;
435   CORBA::Object_var objS = _NS->Resolve("/Kernel/Session");
436   if (!CORBA::is_nil(objS))
437   {
438     session = SALOME::Session::_narrow(objS);
439     if (!CORBA::is_nil(session))
440     {
441       pid = session->getPID();
442       session->Shutdown();
443     }
444   }
445
446   std::string hostname = Kernel_Utils::GetHostname();
447
448   // 1) ConnectionManager
449   try
450     {
451       CORBA::Object_var objCnM=_NS->Resolve("/ConnectionManager");
452       Engines::ConnectionManager_var connMan=Engines::ConnectionManager::_narrow(objCnM);
453       if ( !CORBA::is_nil(connMan) && ( pid != connMan->getPID() ) )
454         connMan->ShutdownWithExit();
455     }
456   catch(const CORBA::Exception& e)
457     {
458        // ignore and continue
459     }
460
461   timespec ts_req;
462   ts_req.tv_nsec=100000000;
463   ts_req.tv_sec=0;
464
465 //Wait some time so that ConnectionManager be completely shutdown
466 #ifndef WIN32
467   nanosleep(&ts_req,0);
468 #endif
469
470   // 2) SALOMEDS
471   try
472     {
473       CORBA::Object_var objSDS = _NS->Resolve("/myStudyManager");
474       SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(objSDS) ;
475       if ( !CORBA::is_nil(studyManager) && ( pid != studyManager->getPID() ) )
476         studyManager->Shutdown();
477     }
478   catch(const CORBA::Exception& e)
479     {
480        // ignore and continue
481     }
482
483 //Wait some time so that study be completely shutdown
484 #ifndef WIN32
485   nanosleep(&ts_req,0);
486 #endif
487
488   // 3) ModuleCatalog
489   try
490     {
491       CORBA::Object_var objMC=_NS->Resolve("/Kernel/ModulCatalog");
492       SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objMC);
493       if ( !CORBA::is_nil(catalog) && ( pid != catalog->getPID() ) )
494         catalog->shutdown();
495     }
496   catch(const CORBA::Exception& e)
497     {
498        // ignore and continue
499     }
500
501 //Wait some time so that ModulCatalog be completely shutdown
502 #ifndef WIN32
503   nanosleep(&ts_req,0);
504 #endif
505
506   // 4) SalomeLauncher
507   try
508     {
509       CORBA::Object_var objSL = _NS->Resolve("/SalomeLauncher");
510       Engines::SalomeLauncher_var launcher = Engines::SalomeLauncher::_narrow(objSL);
511       if (!CORBA::is_nil(launcher) && (pid != launcher->getPID()))
512         launcher->Shutdown();
513     }
514   catch(const CORBA::Exception& e)
515     {
516        // ignore and continue
517     }
518
519 //Wait some time so that launcher be completely shutdown
520 #ifndef WIN32
521   nanosleep(&ts_req,0);
522 #endif
523
524   // 5) Registry
525   try
526     {
527       CORBA::Object_var objR = _NS->Resolve("/Registry");
528       Registry::Components_var registry = Registry::Components::_narrow(objR);
529       if ( !CORBA::is_nil(registry) && ( pid != registry->getPID() ) )
530           registry->Shutdown();
531     }
532   catch(const CORBA::Exception& e)
533     {
534        // ignore and continue
535     }
536
537   /*
538   // 6) Session
539   if ( !CORBA::is_nil( session ) ) {
540     try
541     {
542       session->Shutdown();
543     }
544     catch(const CORBA::Exception& e)
545     {
546       // ignore and continue
547     }
548   }
549   */
550
551   // 7) Logger
552   int argc = 0;
553   char *xargv = (char*)"";
554   char **argv = &xargv;
555   CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
556
557   CORBA::Object_var objLog = CORBA::Object::_nil();
558   CosNaming::NamingContext_var inc;
559   CORBA::Object_var theObj = CORBA::Object::_nil();
560   std::string stdname = "Logger";
561   CosNaming::Name name;
562   name.length(1);
563   name[0].id = CORBA::string_dup(stdname.c_str());
564   try
565   {
566     if(!CORBA::is_nil(orb))
567       theObj = orb->resolve_initial_references("NameService");
568     if (!CORBA::is_nil(theObj))
569       inc = CosNaming::NamingContext::_narrow(theObj);
570   }
571   catch(...)
572   {
573   }
574   if(!CORBA::is_nil(inc))
575   {
576     try
577     {
578       objLog = inc->resolve(name);
579       SALOME_Logger::Logger_var logger = SALOME_Logger::Logger::_narrow(objLog);
580       if ( !CORBA::is_nil(logger) )
581         logger->shutdown();
582     }
583     catch(...)
584     {
585     }
586   }
587 }
588
589 //=============================================================================
590 /*! \brief shutdown  omniNames and notifd
591  */
592 //=============================================================================
593
594 void SALOME_LifeCycleCORBA::killOmniNames()
595 {
596   std::string portNumber (::getenv ("NSPORT") );
597   if ( !portNumber.empty() )
598   {
599 #ifdef WIN32
600 #else
601     std::string cmd ;
602     cmd = std::string( "ps -eo pid,command | grep -v grep | grep -E \"omniNames.*")
603       + portNumber
604       + std::string("\" | awk '{cmd=sprintf(\"kill -9 %s\",$1); system(cmd)}'" );
605     MESSAGE(cmd);
606     try {
607       system ( cmd.c_str() );
608     }
609     catch ( ... ) {
610     }
611 #endif
612   }
613
614   // NPAL 18309  (Kill Notifd)
615
616   std::string python_exe;
617
618   python_exe = std::string("python");
619 #ifdef WIN32
620   #ifdef _DEBUG_
621     python_exe += std::string("_d");
622   #endif
623 #endif
624
625   if ( !portNumber.empty() )
626   {
627     std::string cmd = ("from killSalomeWithPort import killNotifdAndClean; ");
628     cmd += std::string("killNotifdAndClean(") + portNumber + "); ";
629     cmd  = python_exe + std::string(" -c \"") + cmd +"\" > /dev/null 2> /dev/null";
630     MESSAGE(cmd);
631     system( cmd.c_str() );
632   }
633
634 #ifdef WITH_PORTMANAGER
635   // shutdown portmanager
636   if ( !portNumber.empty() )
637   {
638     std::string cmd = ("from PortManager import releasePort; ");
639     cmd += std::string("releasePort(") + portNumber + "); ";
640     cmd  = python_exe + std::string(" -c \"") + cmd +"\" > /dev/null 2> /dev/null";
641     MESSAGE(cmd);
642     system( cmd.c_str() );
643   }
644 #endif
645 }
646
647 //=============================================================================
648 /*! \brief Find an already existing and registered component instance.
649  *
650  * - build a list of machines on which an instance of the component is running,
651  * - find the best machine among the list
652  *
653  *  \param params         machine parameters like type or name...
654  *  \param componentName  the name of component class
655  *  \param studyId        default = 0  : multistudy instance
656  *  \param listOfMachines list of machine address
657  *  \return a CORBA reference of the component instance, or _nil if not found
658  */
659 //=============================================================================
660
661 Engines::EngineComponent_ptr
662 SALOME_LifeCycleCORBA::
663 _FindComponent(const Engines::ContainerParameters& params,
664                const char *componentName,
665                int studyId,
666                const Engines::ResourceList& listOfResources)
667 {
668   // --- build the list of machines on which the component is already running
669   const char *containerName = params.container_name;
670   int nbproc = NbProc(params);
671
672   Engines::ResourceList_var resourcesOK = new Engines::ResourceList;
673
674   unsigned int lghtOfresourcesOK = 0;
675   resourcesOK->length(listOfResources.length());
676
677   for(unsigned int i=0; i < listOfResources.length(); i++)
678   {
679     const char * currentResource = listOfResources[i];
680     Engines::ResourceDefinition_var resource_definition =
681         _ResManager->GetResourceDefinition(currentResource);
682     CORBA::Object_var obj = _NS->ResolveComponent(resource_definition->hostname.in(),
683                                                   containerName,
684                                                   componentName,
685                                                   nbproc);
686     if (!CORBA::is_nil(obj))
687       resourcesOK[lghtOfresourcesOK++] = CORBA::string_dup(currentResource);
688   }
689
690   // --- find the best machine among the list
691   if(lghtOfresourcesOK != 0)
692   {
693     resourcesOK->length(lghtOfresourcesOK);
694     CORBA::String_var bestResource = _ResManager->FindFirst(resourcesOK);
695     Engines::ResourceDefinition_var resource_definition =
696         _ResManager->GetResourceDefinition(bestResource);
697     CORBA::Object_var obj = _NS->ResolveComponent(resource_definition->hostname.in(),
698                                                   containerName,
699                                                   componentName,
700                                                   nbproc);
701     return Engines::EngineComponent::_narrow(obj);
702   }
703   else
704     return Engines::EngineComponent::_nil();
705 }
706
707 //=============================================================================
708 /*! \brief  Load a component instance.
709  *
710  *  - Finds a container in the list of machine or start one.
711  *  - Try to load the component library in the container,
712  *  - then create an instance of the component.
713  *
714  *  \param params         machine parameters like type or name...
715  *  \param componentName  the name of component class
716  *  \param studyId        default = 0  : multistudy instance
717  *  \return a CORBA reference of the component instance, or _nil if problem
718  */
719 //=============================================================================
720
721 Engines::EngineComponent_ptr
722 SALOME_LifeCycleCORBA::
723 _LoadComponent(const Engines::ContainerParameters& params,
724               const char *componentName,
725               int studyId)
726 {
727   MESSAGE("_LoadComponent, required " << params.container_name <<
728           " " << componentName << " " << NbProc(params));
729
730   Engines::ContainerParameters local_params(params);
731   local_params.mode = CORBA::string_dup("findorstart");
732   Engines::Container_var cont = _ContManager->GiveContainer(local_params);
733   if (CORBA::is_nil(cont)) return Engines::EngineComponent::_nil();
734
735   char* reason;
736   bool isLoadable = cont->load_component_Library(componentName,reason);
737   if (!isLoadable)
738     {
739       //std::cerr << reason << std::endl;
740       CORBA::string_free(reason);
741       return Engines::EngineComponent::_nil();
742     }
743   CORBA::string_free(reason);
744
745   Engines::EngineComponent_var myInstance =
746     cont->create_component_instance(componentName, studyId);
747   return myInstance._retn();
748 }
749
750 //=============================================================================
751 /*! \brief  Load a parallel component instance.
752  *
753  *  \param params         machine parameters like type or name...
754  *  \param componentName  the name of component class
755  *  \param studyId        default = 0  : multistudy instance
756  *  \return a CORBA reference of the parallel component instance, or _nil if problem
757  */
758 //=============================================================================
759 Engines::EngineComponent_ptr
760 SALOME_LifeCycleCORBA::Load_ParallelComponent(const Engines::ContainerParameters& params,
761                                               const char *componentName,
762                                               int studyId)
763 {
764   MESSAGE("Entering LoadParallelComponent");
765
766 /*MESSAGE("Parameters : ");
767   MESSAGE("Container name : " << params.container_name);
768   MESSAGE("Number of component nodes : " << params.nb_component_nodes);
769   MESSAGE("Component Name : " << componentName);*/
770
771   Engines::ContainerParameters parms(params);
772   parms.resource_params.componentList.length(1);
773   parms.resource_params.componentList[0] = componentName;
774   parms.mode = CORBA::string_dup("findorstart");
775
776   MESSAGE("Starting Parallel Container");
777   Engines::Container_var cont = _ContManager->GiveContainer(parms);
778   if (CORBA::is_nil(cont)) {
779     INFOS("FindOrStartParallelContainer() returns a NULL container !");
780     return Engines::EngineComponent::_nil();
781   }
782
783   MESSAGE("Loading component library");
784   char* reason;
785   bool isLoadable = cont->load_component_Library(componentName,reason);
786   if (!isLoadable) {
787     INFOS(componentName <<" library is not loadable !");
788     //std::cerr << reason << std::endl;
789     CORBA::string_free(reason);
790     return Engines::EngineComponent::_nil();
791   }
792   CORBA::string_free(reason);
793
794   MESSAGE("Creating component instance");
795   // @PARALLEL@ permits to identify that the component requested
796   // is a parallel component.
797   std::string name = std::string(componentName);
798   Engines::EngineComponent_var myInstance = cont->create_component_instance(name.c_str(), studyId);
799   if (CORBA::is_nil(myInstance))
800     INFOS("create_component_instance returns a NULL component !");
801   return myInstance._retn();
802 }
803
804 /*! \brief copy a file from a source host to a destination host
805  * \param hostSrc the source host
806  * \param fileSrc the file to copy from the source host to the destination host
807  * \param hostDest the destination host
808  * \param fileDest the destination file
809  */
810 void SALOME_LifeCycleCORBA::copyFile(const char* hostSrc, const char* fileSrc, const char* hostDest, const char* fileDest)
811 {
812   if(strcmp(hostDest,"localhost") == 0)
813     {
814       //if localhost use a shortcut
815       SALOME_FileTransferCORBA transfer(hostSrc,fileSrc);
816       transfer.getLocalFile(fileDest);
817       return;
818     }
819
820   Engines::ContainerManager_var contManager = getContainerManager();
821
822   Engines::ContainerParameters params;
823   preSet(params);
824
825   params.resource_params.hostname = hostDest;
826   params.mode = CORBA::string_dup("findorstart");
827   Engines::Container_var containerDest = contManager->GiveContainer(params);
828
829   params.resource_params.hostname = hostSrc;
830   Engines::Container_var containerSrc = contManager->GiveContainer(params);
831
832   containerDest->copyFile(containerSrc,fileSrc,fileDest);
833 }
834
835 /*! \brief get the naming service used by the life cycle
836  *
837  *  \return the naming service
838  */
839 SALOME_NamingService * SALOME_LifeCycleCORBA::namingService()
840 {
841   return _NS;
842 }
843
844 /*! \brief get the orb used by the life cycle
845  *
846  *  \return the orb
847  */
848 CORBA::ORB_ptr SALOME_LifeCycleCORBA::orb()
849 {
850   return _NS->orb();
851 }