Salome HOME
This commit was generated by cvs2git to track changes on a CVS vendor
[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 using namespace std;
30 #include <iostream>
31 #include <fstream>
32 #include <sstream>
33 #include <iomanip>
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   SCRUTE( path ) ;
106   return CORBA::string_dup( path ) ;
107 }
108
109 Engines::Container_var SALOME_LifeCycleCORBA::FindContainer(const char *containerName ) {
110   ASSERT(_NS != NULL);
111   string cont ;
112   if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ...
113     string theComputer ;
114     string theContainer ;
115     cont = ContainerName( containerName , &theComputer , &theContainer ) ;
116   }
117   else {
118     cont = containerName ;
119   }
120   try {
121
122     SCRUTE( cont );
123
124     CORBA::Object_var obj = _NS->Resolve( cont.c_str() );
125     if( !CORBA::is_nil( obj ) ) {
126       return Engines::Container::_narrow( obj ) ;
127     }
128   }
129   catch (ServiceUnreachable&) {
130     INFOS("Caught exception: Naming Service Unreachable");
131   }
132   catch (...) {
133     INFOS("Caught unknown exception.");
134   }
135   return Engines::Container::_nil();
136 }
137
138 Engines::Container_var SALOME_LifeCycleCORBA::FindOrStartContainer(
139                                               const string aComputerContainer ,
140                                               const string theComputer ,
141                                               const string theContainer ) {
142   Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ;
143   Engines::Container_var aFactoryServer ;
144   SCRUTE( aComputerContainer ) ;
145   SCRUTE( theComputer ) ;
146   SCRUTE( theContainer ) ;
147   bool pyCont = false ;
148   int len = theContainer.length() ;
149   if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) {
150     pyCont = true ;
151   }
152   if ( !CORBA::is_nil( aContainer ) ) {
153     return aContainer ;
154   }
155   else {
156     string FactoryServer = theComputer ;
157     if ( pyCont ) {
158       FactoryServer += "/FactoryServerPy" ;
159     }
160     else {
161       FactoryServer += "/FactoryServer" ;
162     }
163     aFactoryServer = FindContainer( FactoryServer.c_str() ) ;
164     if ( CORBA::is_nil( aFactoryServer ) ) {
165 // rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 &
166       string rsh( "" ) ;
167       if ( theComputer!= GetHostname() ) {
168         rsh += "rsh -n " ;
169         rsh += theComputer ;
170         rsh += " " ;
171       }
172       string path = ComputerPath( theComputer.c_str() ) ;
173       SCRUTE( path ) ;
174       if ( path[0] != '\0' ) {
175         rsh += path ;
176         rsh += "/../bin/" ;
177       }
178       rsh += "runSession " ;
179       if ( pyCont ) {
180         rsh += "SALOME_ContainerPy.py " ;
181         rsh += "FactoryServerPy -" ;
182       }
183       else {
184         rsh += "SALOME_Container " ;
185         rsh += "FactoryServer -" ;
186       }
187       string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ;
188       ifstream omniORBfile( omniORBcfg.c_str() ) ;
189       char ORBInitRef[12] ;
190       char nameservice[132] ;
191       omniORBfile >> ORBInitRef ;
192       rsh += ORBInitRef ;
193       rsh += " " ;
194       omniORBfile >> nameservice ;
195       omniORBfile.close() ;
196       char * bsn = strchr( nameservice , '\n' ) ;
197       if ( bsn ) {
198         bsn[ 0 ] = '\0' ;
199       }
200       rsh += nameservice ;
201       if ( pyCont ) {
202         rsh += " > /tmp/FactoryServerPy_" ;
203       }
204       else {
205         rsh += " > /tmp/FactoryServer_" ;
206       }
207       rsh += theComputer ;
208       rsh += ".log 2>&1 &" ;
209       SCRUTE( rsh );
210       int status = system( rsh.c_str() ) ;
211       if (status == -1) {
212         INFOS("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status -1)") ;
213       }
214       else if (status == 217) {
215         INFOS("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status 217)") ;
216       }
217       else {
218         int count = 21 ;
219         while ( CORBA::is_nil( aFactoryServer ) && count ) {
220           sleep( 1 ) ;
221           count-- ;
222           if ( count != 10 )
223             MESSAGE( count << ". Waiting for FactoryServer on " << theComputer)
224           aFactoryServer = FindContainer( FactoryServer.c_str() ) ;
225         }
226         if ( CORBA::is_nil( aFactoryServer ) ) {
227           INFOS("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ;
228         }
229         else if ( strcmp( theComputer.c_str() , GetHostname().c_str() ) ) {
230           _FactoryServer = aFactoryServer ;
231         }
232       }
233     }
234     if ( !CORBA::is_nil( aFactoryServer ) ) {
235       if ( strcmp( theContainer.c_str() , "FactoryServer" ) ||
236            strcmp( theContainer.c_str() , "FactoryServerPy" ) ) {
237         MESSAGE("Container not found ! trying to start " << aComputerContainer);
238         Engines::Container_var myContainer = aFactoryServer->start_impl( theContainer.c_str() ) ;
239         if ( !CORBA::is_nil( myContainer ) ) {
240           MESSAGE("Container " << aComputerContainer << " started");
241           return myContainer ;
242         }
243         else {
244           MESSAGE("Container " << aComputerContainer << " NOT started");
245         }
246       }
247       else {
248         MESSAGE("Container " << aComputerContainer << " started");
249         return aFactoryServer ;
250       }
251     }
252   }
253   return Engines::Container::_nil();
254 }
255
256 Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component
257                                    (const char *containerName,
258                                     const char *componentName,
259                                     const char *implementation)
260 {
261   BEGIN_OF("FindOrLoad_Component(1)");
262   ASSERT(_NS != NULL);
263   string theComputer ;
264   string theContainer ;
265   string theComputerContainer = ContainerName( containerName ,
266                                                &theComputer ,
267                                                &theContainer ) ;
268   Engines::Container_var cont = FindOrStartContainer( theComputerContainer ,
269                                                       theComputer ,
270                                                       theContainer ) ;
271 //  ASSERT(!CORBA::is_nil(cont));
272
273   string path( theComputerContainer );
274   path = path + "/";
275   path = path + componentName;
276   SCRUTE(path);
277   try
278     {
279       CORBA::Object_var obj = _NS->Resolve(path.c_str());
280       if (CORBA::is_nil(obj))
281         {
282           MESSAGE("Component not found ! trying to load " << path);
283           Engines::Component_var compo 
284             = cont->load_impl(componentName, implementation);
285 //        ASSERT(!CORBA::is_nil(compo));
286           MESSAGE("Component launched !" << path);
287           return compo;
288         }
289       else
290         {
291           MESSAGE("Component found !" << path);
292           Engines::Component_var compo = Engines::Component::_narrow(obj);
293 //        ASSERT(!CORBA::is_nil(compo));
294           try
295             {
296               compo->ping(); 
297             }
298           catch (CORBA::COMM_FAILURE&)
299             {
300               INFOS("Caught CORBA::SystemException CommFailure. Engine "
301                     << path << "does not respond" );
302             }
303           return compo;
304         }
305     }
306   catch (ServiceUnreachable&)
307     {
308       INFOS("Caught exception: Naming Service Unreachable");
309     }
310   catch (...)
311     {
312       INFOS("Caught unknown exception.");
313     }
314   return Engines::Component::_nil();
315 }
316
317 Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component
318                                   (const char *containerName,
319                                    const char *componentName)
320 {
321 //  BEGIN_OF("FindOrLoad_Component(2)");
322   ASSERT(_NS != NULL);
323   string theComputer ;
324   string theContainer ;
325   string theComputerContainer = ContainerName( containerName ,
326                                                &theComputer ,
327                                                &theContainer ) ;
328   Engines::Container_var cont = FindOrStartContainer( theComputerContainer ,
329                                                       theComputer ,
330                                                       theContainer ) ;
331
332   if ( CORBA::is_nil( cont ) ) {
333     MESSAGE("Container not found ! " << theComputerContainer );
334     return Engines::Component::_nil();
335   }
336
337 //  char * machine = cont->machineName() ;
338   const char * machine = theComputer.c_str() ;
339
340   string path( theComputerContainer );
341   path += "/";
342   path += componentName;
343   SCRUTE(path);
344
345   try {
346     CORBA::Object_var obj = _NS->Resolve(path.c_str());
347     if ( CORBA::is_nil( obj ) ) {
348       MESSAGE("Component not found ! trying to load " << path);
349           CORBA::Object_var obj2 = _NS->Resolve("/Kernel/ModulCatalog");
350           SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
351             SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj2);
352
353           SALOME_ModuleCatalog::Acomponent_ptr compoInfo = 
354             Catalog->GetComponent(componentName);
355           if (CORBA::is_nil (compoInfo)) 
356             {
357               INFOS("Catalog Error : Component not found in the catalog")
358               return Engines::Component::_nil();
359 //              exit (-1);
360             }
361           
362           string  path;
363           try
364             {
365               path = compoInfo->GetPathPrefix( machine ) ;
366               path += "/" ;
367             }
368           catch (SALOME_ModuleCatalog::NotFound&)
369             {
370               MESSAGE("GetPathPrefix(" << machine << ") not found!"
371                       << "trying localhost");
372               try {
373                 path = compoInfo->GetPathPrefix("localhost") ;
374                 path += "/" ;
375               }
376               catch (SALOME_ModuleCatalog::NotFound&) {
377                 MESSAGE("GetPathPrefix(localhost) not found!") ;
378                 path = "" ;
379               }
380             }
381
382           SCRUTE(path); 
383           string implementation(path);
384           implementation += "lib";
385           implementation += componentName;
386           implementation += "Engine.so";
387           
388           Engines::Component_var compo 
389             = cont->load_impl(componentName, implementation.c_str());
390
391 //        ASSERT(!CORBA::is_nil(compo));
392 //        MESSAGE("Component launched !" << path);
393           return compo;
394     }
395     else
396         {
397           MESSAGE("Component found !" << path);
398           Engines::Component_var compo = Engines::Component::_narrow(obj);
399 //        ASSERT(!CORBA::is_nil(compo));
400           try
401             {
402               string instanceName = compo->instanceName(); 
403             }
404           catch (CORBA::COMM_FAILURE&)
405             {
406               INFOS("Caught CORBA::SystemException CommFailure. Engine "
407                     << path << "does not respond" );
408             }
409           return compo;
410         }
411     }
412   catch (ServiceUnreachable&)
413     {
414       INFOS("Caught exception: Naming Service Unreachable");
415     }
416   catch (...)
417     {
418       INFOS("Caught unknown exception.");
419     }
420   return Engines::Component::_nil();
421 }