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