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