]> SALOME platform Git repositories - modules/kernel.git/blob - src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx
Salome HOME
PR: mergefrom_BSEC_br1_14Mar04
[modules/kernel.git] / src / LifeCycleCORBA / SALOME_LifeCycleCORBA.cxx
1 //  SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++
2 //
3 //  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOME_LifeCycleCORBA.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SALOME
27 //  $Header$
28
29 #include <iostream>
30 #include <fstream>
31 #include <sstream>
32 #include <iomanip>
33 using namespace std;
34
35 #include "OpUtil.hxx"
36 #include "utilities.h"
37
38 #include <ServiceUnreachable.hxx>
39
40 #include "SALOME_LifeCycleCORBA.hxx"
41 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
42 #include "SALOME_NamingService.hxx"
43
44 SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA()
45 {
46   _NS = NULL;
47   _FactoryServer = NULL ;
48 }
49
50 SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns)
51 {
52   _NS = ns;
53   _FactoryServer = NULL ;
54 }
55
56 SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA()
57 {
58 }
59
60 string SALOME_LifeCycleCORBA::ContainerName(
61                                          const char * aComputerContainer ,
62                                          string * theComputer ,
63                                          string * theContainer ) {
64   char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ;
65   strcpy( ContainerName , aComputerContainer ) ;
66   string theComputerContainer("/Containers/");
67   char * slash = strchr( ContainerName , '/' ) ;
68   if ( !slash ) {
69     *theComputer = GetHostname() ;
70     theComputerContainer += *theComputer ;
71     theComputerContainer += "/" ;
72     *theContainer = ContainerName ;
73     theComputerContainer += *theContainer ;
74   }
75   else {
76     slash[ 0 ] = '\0' ;
77     slash += 1 ;
78     *theContainer = slash ;
79     if ( !strcmp( ContainerName , "localhost" ) ) {
80       *theComputer = GetHostname() ;
81     }
82     else {
83       *theComputer = ContainerName ;
84     }
85     theComputerContainer += *theComputer ;
86     theComputerContainer += "/" ;
87     theComputerContainer += *theContainer ;
88   }
89   return theComputerContainer ;
90 }
91
92 string SALOME_LifeCycleCORBA::ComputerPath(
93                                          const char * theComputer ) {
94 //  CORBA::String_var path;
95 //   CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
96 //   SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
97 //                   SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
98 //   try {
99 //     path = Catalog->GetPathPrefix( theComputer );
100 //   }
101 //   catch (SALOME_ModuleCatalog::NotFound&) {
102 //     MESSAGE("GetPathPrefix(" << theComputer << ") not found!");
103 //     path = "" ;
104 //   }
105 // Modification provisoire B. Secher en attendant le gestionnaire de ressources
106 // 21/10/2003
107 // Le KERNEL_ROOT_DIR sera a lire dans le catalogue de machines
108 // en attendant on suppose qu'il est identique au KERNEL_ROOT_DIR local
109   string path = string(getenv("KERNEL_ROOT_DIR")) + "/bin/salome/";
110   SCRUTE( path ) ;
111   return path;
112 }
113
114 Engines::Container_var SALOME_LifeCycleCORBA::FindContainer(const char *containerName ) {
115   ASSERT(_NS != NULL);
116   string cont ;
117   if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ...
118     string theComputer ;
119     string theContainer ;
120     cont = ContainerName( containerName , &theComputer , &theContainer ) ;
121   }
122   else {
123     cont = containerName ;
124   }
125   try {
126
127     SCRUTE( cont );
128
129     CORBA::Object_var obj = _NS->Resolve( cont.c_str() );
130     if( !CORBA::is_nil( obj ) ) {
131       return Engines::Container::_narrow( obj ) ;
132     }
133   }
134   catch (ServiceUnreachable&) {
135     INFOS("Caught exception: Naming Service Unreachable");
136   }
137   catch (...) {
138     INFOS("Caught unknown exception.");
139   }
140   return Engines::Container::_nil();
141 }
142
143 Engines::Container_var SALOME_LifeCycleCORBA::FindOrStartContainer(
144                                               const string aComputerContainer ,
145                                               const string theComputer ,
146                                               const string theContainer ) {
147   Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ;
148   Engines::Container_var aFactoryServer ;
149   SCRUTE( aComputerContainer ) ;
150   SCRUTE( theComputer ) ;
151   SCRUTE( theContainer ) ;
152   bool pyCont = false ;
153   int len = theContainer.length() ;
154   if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) {
155     pyCont = true ;
156   }
157   if ( !CORBA::is_nil( aContainer ) ) {
158     return aContainer ;
159   }
160   else {
161     string FactoryServer = theComputer ;
162     if ( pyCont ) {
163       FactoryServer += "/FactoryServerPy" ;
164     }
165     else {
166       FactoryServer += "/FactoryServer" ;
167     }
168     aFactoryServer = FindContainer( FactoryServer.c_str() ) ;
169     if ( CORBA::is_nil( aFactoryServer ) ) {
170 // rsh -n machine_name ${KERNEL_ROOT_DIR}/bin/salome SALOME_Container -ORBInitRef NameService=corbaname::localhost:1515 &
171       string rsh( "" ) ;
172       if ( theComputer!= GetHostname() ) {
173         rsh += "rsh -n " ;
174         rsh += theComputer ;
175         rsh += " " ;
176       }
177       string path = ComputerPath( theComputer.c_str() ) ;
178       SCRUTE( path ) ;
179       rsh += path;
180 //       rsh += "runSession " ;
181       if ( pyCont ) {
182         rsh += "SALOME_ContainerPy.py " ;
183         rsh += "FactoryServerPy -" ;
184       }
185       else {
186         rsh += "SALOME_Container " ;
187         rsh += "FactoryServer -" ;
188       }
189       string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
190       ifstream omniORBfile( omniORBcfg.c_str() ) ;
191       char ORBInitRef[12] ;
192       char nameservice[132] ;
193       omniORBfile >> ORBInitRef ;
194       rsh += ORBInitRef ;
195       rsh += " " ;
196       omniORBfile >> nameservice ;
197       omniORBfile.close() ;
198       char * bsn = strchr( nameservice , '\n' ) ;
199       if ( bsn ) {
200         bsn[ 0 ] = '\0' ;
201       }
202       rsh += nameservice ;
203       if ( pyCont ) {
204         rsh += " > /tmp/FactoryServerPy_" ;
205       }
206       else {
207         rsh += " > /tmp/FactoryServer_" ;
208       }
209       rsh += theComputer ;
210       rsh += ".log 2>&1 &" ;
211       SCRUTE( rsh );
212       int status = system( rsh.c_str() ) ;
213       if (status == -1) {
214         INFOS("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status -1)") ;
215       }
216       else if (status == 217) {
217         INFOS("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status 217)") ;
218       }
219       else {
220         int count = 21 ;
221         while ( CORBA::is_nil( aFactoryServer ) && count ) {
222           sleep( 1 ) ;
223           count-- ;
224           if ( count != 10 )
225             MESSAGE( count << ". Waiting for FactoryServer on " << theComputer)
226           aFactoryServer = FindContainer( FactoryServer.c_str() ) ;
227         }
228         if ( CORBA::is_nil( aFactoryServer ) ) {
229           INFOS("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ;
230         }
231         else if ( strcmp( theComputer.c_str() , GetHostname().c_str() ) ) {
232           _FactoryServer = aFactoryServer ;
233         }
234       }
235     }
236     if ( !CORBA::is_nil( aFactoryServer ) ) {
237       if ( strcmp( theContainer.c_str() , "FactoryServer" ) ||
238            strcmp( theContainer.c_str() , "FactoryServerPy" ) ) {
239         MESSAGE("Container not found ! trying to start " << aComputerContainer);
240         Engines::Container_var myContainer = aFactoryServer->start_impl( theContainer.c_str() ) ;
241         if ( !CORBA::is_nil( myContainer ) ) {
242           MESSAGE("Container " << aComputerContainer << " started");
243           return myContainer ;
244         }
245         else {
246           MESSAGE("Container " << aComputerContainer << " NOT started");
247         }
248       }
249       else {
250         MESSAGE("Container " << aComputerContainer << " started");
251         return aFactoryServer ;
252       }
253     }
254   }
255   return Engines::Container::_nil();
256 }
257
258 Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component
259                                    (const char *containerName,
260                                     const char *componentName,
261                                     const char *implementation)
262 {
263   BEGIN_OF("FindOrLoad_Component(1)");
264   ASSERT(_NS != NULL);
265   string theComputer ;
266   string theContainer ;
267   string theComputerContainer = ContainerName( containerName ,
268                                                &theComputer ,
269                                                &theContainer ) ;
270   Engines::Container_var cont = FindOrStartContainer( theComputerContainer ,
271                                                       theComputer ,
272                                                       theContainer ) ;
273 //  ASSERT(!CORBA::is_nil(cont));
274
275   string path( theComputerContainer );
276   path = path + "/";
277   path = path + componentName;
278   SCRUTE(path);
279   try
280     {
281       CORBA::Object_var obj = _NS->Resolve(path.c_str());
282       if (CORBA::is_nil(obj))
283         {
284           MESSAGE("Component not found ! trying to load " << path);
285           Engines::Component_var compo 
286             = cont->load_impl(componentName, implementation);
287 //        ASSERT(!CORBA::is_nil(compo));
288           MESSAGE("Component launched !" << path);
289           return compo;
290         }
291       else
292         {
293           MESSAGE("Component found !" << path);
294           Engines::Component_var compo = Engines::Component::_narrow(obj);
295 //        ASSERT(!CORBA::is_nil(compo));
296           try
297             {
298               compo->ping(); 
299             }
300           catch (CORBA::COMM_FAILURE&)
301             {
302               INFOS("Caught CORBA::SystemException CommFailure. Engine "
303                     << path << "does not respond" );
304             }
305           return compo;
306         }
307     }
308   catch (ServiceUnreachable&)
309     {
310       INFOS("Caught exception: Naming Service Unreachable");
311     }
312   catch (...)
313     {
314       INFOS("Caught unknown exception.");
315     }
316   return Engines::Component::_nil();
317 }
318
319 Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component
320                                   (const char *containerName,
321                                    const char *componentName)
322 {
323 //  BEGIN_OF("FindOrLoad_Component(2)");
324   ASSERT(_NS != NULL);
325   string theComputer ;
326   string theContainer ;
327   string theComputerContainer = ContainerName( containerName ,
328                                                &theComputer ,
329                                                &theContainer ) ;
330   Engines::Container_var cont = FindOrStartContainer( theComputerContainer ,
331                                                       theComputer ,
332                                                       theContainer ) ;
333
334   if ( CORBA::is_nil( cont ) ) {
335     MESSAGE("Container not found ! " << theComputerContainer );
336     return Engines::Component::_nil();
337   }
338
339 //  char * machine = cont->machineName() ;
340   const char * machine = theComputer.c_str() ;
341
342   string path( theComputerContainer );
343   path += "/";
344   path += componentName;
345   SCRUTE(path);
346
347   try {
348     CORBA::Object_var obj = _NS->Resolve(path.c_str());
349     if ( CORBA::is_nil( obj ) ) {
350       MESSAGE("Component not found ! trying to load " << path);
351           CORBA::Object_var obj2 = _NS->Resolve("/Kernel/ModulCatalog");
352           SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
353             SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj2);
354
355           SALOME_ModuleCatalog::Acomponent_ptr compoInfo = 
356             Catalog->GetComponent(componentName);
357           if (CORBA::is_nil (compoInfo)) 
358             {
359               INFOS("Catalog Error : Component not found in the catalog")
360               return Engines::Component::_nil();
361 //              exit (-1);
362             }
363           
364           string  path;
365           try
366             {
367               path = compoInfo->GetPathPrefix( machine ) ;
368               path += "/" ;
369             }
370           catch (SALOME_ModuleCatalog::NotFound&)
371             {
372               MESSAGE("GetPathPrefix(" << machine << ") not found!"
373                       << "trying localhost");
374               try {
375                 path = compoInfo->GetPathPrefix("localhost") ;
376                 path += "/" ;
377               }
378               catch (SALOME_ModuleCatalog::NotFound&) {
379                 MESSAGE("GetPathPrefix(localhost) not found!") ;
380                 path = "" ;
381               }
382             }
383
384           SCRUTE(path); 
385           string implementation(path);
386           implementation += "lib";
387           implementation += componentName;
388           implementation += "Engine.so";
389           
390           Engines::Component_var compo 
391             = cont->load_impl(componentName, implementation.c_str());
392
393 //        ASSERT(!CORBA::is_nil(compo));
394 //        MESSAGE("Component launched !" << path);
395           return compo;
396     }
397     else
398         {
399           MESSAGE("Component found !" << path);
400           Engines::Component_var compo = Engines::Component::_narrow(obj);
401 //        ASSERT(!CORBA::is_nil(compo));
402           try
403             {
404               string instanceName = compo->instanceName(); 
405             }
406           catch (CORBA::COMM_FAILURE&)
407             {
408               INFOS("Caught CORBA::SystemException CommFailure. Engine "
409                     << path << "does not respond" );
410             }
411           return compo;
412         }
413     }
414   catch (ServiceUnreachable&)
415     {
416       INFOS("Caught exception: Naming Service Unreachable");
417     }
418   catch (...)
419     {
420       INFOS("Caught unknown exception.");
421     }
422   return Engines::Component::_nil();
423 }