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