Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/gui.git] / src / Session / Session_ServerCheck.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 // File:      Session_ServerCheck.cxx
20 // Author:    Vadim SANDLER
21
22 #include "Session_ServerCheck.hxx"
23 #include <QtxSplash.h>
24
25 #include <SALOMEconfig.h>
26 #include CORBA_CLIENT_HEADER(SALOME_Session)
27 #include CORBA_CLIENT_HEADER(SALOME_Registry)
28 #include CORBA_CLIENT_HEADER(SALOMEDS)
29 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
30 #include CORBA_CLIENT_HEADER(SALOME_Component)
31
32 #include "Utils_ORB_INIT.hxx"
33 #include "Utils_SINGLETON.hxx"
34 #include "SALOME_NamingService.hxx"
35 #include "utilities.h"
36 #include "OpUtil.hxx"
37
38 // Default settings
39 const int __DEFAULT__ATTEMPTS__ = 300;      // number of checks attemtps
40                                             // can be overrided by CSF_RepeatServerRequest
41                                             // environment variable
42 const int __DEFAULT__DELAY__    = 100000;   // delay between attempts (microseconds)
43                                             // can be overrided by CSF_DelayServerRequest
44                                             // environment variable
45
46 /*!
47   Constructor
48 */
49 Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc )
50   : QThread(),
51     myMutex( mutex ),
52     myWC( wc ),
53     myCheckCppContainer( false ),
54     myCheckPyContainer( false ),
55     myCheckSVContainer( false ),
56     myAttempts( __DEFAULT__ATTEMPTS__ ),
57     myDelay   ( __DEFAULT__DELAY__ )
58 {
59   char* cenv;
60   // try to get nb of attempts from environment variable
61   if ( ( cenv = getenv( "CSF_RepeatServerRequest" ) ) && atoi( cenv ) > 0 )
62     myAttempts = atoi( cenv );
63   // try to get delay between attempts from environment variable
64   if ( ( cenv = getenv( "CSF_DelayServerRequest" ) ) && atoi( cenv ) > 0 )
65     myDelay = atoi( cenv );
66
67   // check if it is necessary to wait containers
68   for ( int i = 1; i < qApp->argc(); i++ ) {
69     if ( !strcmp( qApp->argv()[i], "CPP" ) )
70       myCheckCppContainer = true;
71     if ( !strcmp( qApp->argv()[i], "PY" ) )
72       myCheckPyContainer = true;
73     if ( !strcmp( qApp->argv()[i], "SUPERV" ) )
74       myCheckSVContainer = true;
75   }
76   
77   // start thread
78   start();
79 }
80
81 /*!
82   Destructor
83 */
84 Session_ServerCheck::~Session_ServerCheck()
85 {
86 }
87
88 /*!
89   Thread loop. Checnk SALOME servers and shows status message
90   in the splash screen.
91 */
92 void Session_ServerCheck::run()
93 {
94   // automatic locker
95   class Locker
96   {
97   public:
98     QMutex*         _m;
99     QWaitCondition* _wc;
100     Locker( QMutex* m, QWaitCondition* wc ) : _m( m ), _wc( wc )
101     {
102       _m->lock();
103       _m->unlock(); 
104     }
105     ~Locker()
106     {
107       _wc->wakeAll();
108     }
109   };
110
111   // lock mutex (ensure splash is shown)
112   Locker locker( myMutex, myWC );
113
114   // set initial splash status
115   QtxSplash* splash = QtxSplash::splash();
116
117   int cnt = 5;                       // base servers
118   if ( myCheckCppContainer ) cnt++;  // + C++ container
119   if ( myCheckPyContainer )  cnt++;  // + Python container
120   if ( myCheckSVContainer )  cnt++;  // + supervision container
121
122   splash->setProgress( 0, cnt * myAttempts );
123   QString initialInfo = splash->message();
124   QString info = initialInfo.isEmpty() ? "%1" : QString( "%1\n%2" ).arg( initialInfo );
125
126   // start check servers
127   int i;
128   int current = 0;
129   bool bOk;
130   QString error;
131   int    argc = qApp->argc();
132   char** argv = qApp->argv();
133
134   // 1. Check naming service
135   bOk = false;
136   for ( i = 0; i < myAttempts ; i++ ) {
137     QtxSplash::setStatus( info.arg( "Waiting for naming service..." ), current * myAttempts + i );
138     QThread::usleep( i == 0 ? 500000 : myDelay );
139     try {
140       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
141       CORBA::Object_var obj = orb->resolve_initial_references( "NameService" );
142       CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow( obj );
143       if ( !CORBA::is_nil( _root_context ) ) {
144         bOk = true;
145         break;
146       }
147     }
148     catch( CORBA::COMM_FAILURE& ) {
149       MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" );
150     }
151     catch( ... ) {
152       MESSAGE( "Unknown Exception: unable to contact the naming service" );
153     }
154   }
155   if ( !bOk ) {
156     QtxSplash::error( "Unable to contact the naming service.\n%1" );
157     return;
158   }
159   QtxSplash::setStatus( info.arg( "Waiting for naming service...OK" ), ++current * myAttempts );
160   QThread::usleep( 300000 );
161   
162   // 2. Check registry server
163   bOk = false;
164   for ( i = 0; i < myAttempts ; i++ ) {
165     QtxSplash::setStatus( info.arg( "Waiting for registry server..." ), current * myAttempts + i );
166     QThread::usleep( i == 0 ? 500000 : myDelay );
167     try {
168       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
169       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
170       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
171       NS.init_orb( orb );
172       CORBA::Object_var obj = NS.Resolve( "/Registry" );
173       Registry::Components_var registry = Registry::Components::_narrow( obj );
174       if ( !CORBA::is_nil( registry ) ) {
175         MESSAGE( "/Registry is found" );
176         registry->ping();
177         MESSAGE( "Registry was activated" );
178         bOk = true;
179         break;
180       }
181     }
182     catch ( ServiceUnreachable& ) {
183       MESSAGE( "Caught exception: Naming Service unreachable." );
184       error = "Naming service unreachable";
185     }
186     catch ( CORBA::COMM_FAILURE& ) {
187       MESSAGE( "Caught CORBA::SystemException CommFailure." );
188       error = "Caught CORBA::SystemException CommFailure.";
189     }
190     catch ( CORBA::SystemException& ) {
191       MESSAGE( "Caught CORBA::SystemException." );
192       error = "Caught CORBA::SystemException.";
193     }
194     catch ( CORBA::Exception& ) {
195       MESSAGE( "Caught CORBA::Exception." );
196       error = "Caught CORBA::Exception.";
197     }
198     catch (...) {
199       MESSAGE( "Caught unknown exception." );
200       error = "Caught unknown exception.";
201     }
202   }
203   if ( !bOk ) {
204     QtxSplash::error( QString( "Registry server is not found.\n%1" ).arg ( error ) );
205     return;
206   }
207   QtxSplash::setStatus( info.arg( "Waiting for registry server...OK" ), ++current * myAttempts );
208   QThread::usleep( 300000 );
209
210   // 3. Check data server
211   bOk = false;
212   for ( i = 0; i < myAttempts ; i++ ) {
213     QtxSplash::setStatus( info.arg( "Waiting for study server..." ), current * myAttempts + i );
214     QThread::usleep( i == 0 ? 500000 : myDelay );
215     try {
216       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
217       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
218       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
219       NS.init_orb( orb );
220       CORBA::Object_var obj = NS.Resolve( "/myStudyManager" );
221       SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj );
222       if ( !CORBA::is_nil( studyManager ) ) {
223         MESSAGE( "/myStudyManager is found" );
224         studyManager->ping();
225         MESSAGE( "StudyManager was activated" );
226         bOk = true;
227         break;
228       }
229     }
230     catch ( ServiceUnreachable& ) {
231       MESSAGE( "Caught exception: Naming Service unreachable." );
232       error = "Naming service unreachable";
233     }
234     catch ( CORBA::COMM_FAILURE& ) {
235       MESSAGE( "Caught CORBA::SystemException CommFailure." );
236       error = "Caught CORBA::SystemException CommFailure.";
237     }
238     catch ( CORBA::SystemException& ) {
239       MESSAGE( "Caught CORBA::SystemException." );
240       error = "Caught CORBA::SystemException.";
241     }
242     catch ( CORBA::Exception& ) {
243       MESSAGE( "Caught CORBA::Exception." );
244       error = "Caught CORBA::Exception.";
245     }
246     catch (...) {
247       MESSAGE( "Caught unknown exception." );
248       error = "Caught unknown exception.";
249     }
250   }
251   if ( !bOk ) {
252     QtxSplash::error( QString( "Study server is not found.\n%1" ).arg ( error ) );
253     return;
254   }
255   QtxSplash::setStatus( info.arg( "Waiting for study server...OK" ), ++current * myAttempts );
256   QThread::usleep( 300000 );
257
258   // 4. Check module catalogue server
259   bOk = false;
260   for ( i = 0; i < myAttempts ; i++ ) {
261     QtxSplash::setStatus( info.arg( "Waiting for module catalogue server..." ), current * myAttempts + i );
262     QThread::usleep( i == 0 ? 500000 : myDelay );
263     try {
264       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
265       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
266       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
267       NS.init_orb( orb );
268       CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" );
269       SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
270       if ( !CORBA::is_nil( catalog ) ){
271         MESSAGE( "/Kernel/ModulCatalog is found" );
272         catalog->ping();
273         MESSAGE( "ModuleCatalog was activated" );
274         bOk = true;
275         break;
276       }
277     }
278     catch ( ServiceUnreachable& ) {
279       MESSAGE( "Caught exception: Naming Service unreachable." );
280       error = "Naming service unreachable";
281     }
282     catch ( CORBA::COMM_FAILURE& ) {
283       MESSAGE( "Caught CORBA::SystemException CommFailure." );
284       error = "Caught CORBA::SystemException CommFailure.";
285     }
286     catch ( CORBA::SystemException& ) {
287       MESSAGE( "Caught CORBA::SystemException." );
288       error = "Caught CORBA::SystemException.";
289     }
290     catch ( CORBA::Exception& ) {
291       MESSAGE( "Caught CORBA::Exception." );
292       error = "Caught CORBA::Exception.";
293     }
294     catch (...) {
295       MESSAGE( "Caught unknown exception." );
296       error = "Caught unknown exception.";
297     }
298   }
299   if ( !bOk ) {
300     QtxSplash::error( QString( "Module catalogue server is not found.\n%1" ).arg ( error ) );
301     return;
302   }
303   QtxSplash::setStatus( info.arg( "Waiting for module catalogue server...OK" ), ++current * myAttempts );
304   QThread::usleep( 300000 );
305
306   // 5. Check data server
307   bOk = false;
308   for ( i = 0; i < myAttempts ; i++ ) {
309     QtxSplash::setStatus( info.arg( "Waiting for session server..." ), current * myAttempts + i );
310     QThread::usleep( i == 0 ? 500000 : myDelay );
311     try {
312       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
313       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
314       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
315       NS.init_orb( orb );
316       CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" );
317       SALOME::Session_var session = SALOME::Session::_narrow( obj );
318       if ( !CORBA::is_nil( session ) ) {
319         MESSAGE( "/Kernel/Session is found" );
320         session->ping();
321         MESSAGE( "SALOME_Session was activated" );
322         bOk = true;
323         break;
324       }
325     }
326     catch ( ServiceUnreachable& ) {
327       MESSAGE( "Caught exception: Naming Service unreachable." );
328       error = "Naming service unreachable";
329     }
330     catch ( CORBA::COMM_FAILURE& ) {
331       MESSAGE( "Caught CORBA::SystemException CommFailure." );
332       error = "Caught CORBA::SystemException CommFailure.";
333     }
334     catch ( CORBA::SystemException& ) {
335       MESSAGE( "Caught CORBA::SystemException." );
336       error = "Caught CORBA::SystemException.";
337     }
338     catch ( CORBA::Exception& ) {
339       MESSAGE( "Caught CORBA::Exception." );
340       error = "Caught CORBA::Exception.";
341     }
342     catch (...) {
343       MESSAGE( "Caught unknown exception." );
344       error = "Caught unknown exception.";
345     }
346   }
347   if ( !bOk ) {
348     QtxSplash::error( QString( "Session server is not found.\n%1" ).arg ( error ) );
349     return;
350   }
351   QtxSplash::setStatus( info.arg( "Waiting for session server...OK" ), ++current * myAttempts );
352   QThread::usleep( 300000 );
353
354   // 6. Check C++ container
355   if ( myCheckCppContainer ) {
356     bOk = false;
357     for ( i = 0; i < myAttempts ; i++ ) {
358       QtxSplash::setStatus( info.arg( "Waiting for C++ container..." ), current * myAttempts + i );
359       QThread::usleep( i == 0 ? 500000 : myDelay );
360       try {
361         CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
362         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
363         ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
364         NS.init_orb( orb );
365         QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( GetHostname() );
366         CORBA::Object_var obj = NS.Resolve( containerName.latin1() );
367         Engines::Container_var FScontainer = Engines::Container::_narrow( obj );
368         if ( !CORBA::is_nil( FScontainer ) ) {
369           MESSAGE( containerName.latin1() << " is found" );
370           FScontainer->ping();
371           MESSAGE( "FactoryServer container was activated" );
372           bOk = true;
373           break;
374         }
375       }
376       catch ( ServiceUnreachable& ) {
377         MESSAGE( "Caught exception: Naming Service unreachable." );
378         error = "Naming service unreachable";
379       }
380       catch ( CORBA::COMM_FAILURE& ) {
381         MESSAGE( "Caught CORBA::SystemException CommFailure." );
382         error = "Caught CORBA::SystemException CommFailure.";
383       }
384       catch ( CORBA::SystemException& ) {
385         MESSAGE( "Caught CORBA::SystemException." );
386         error = "Caught CORBA::SystemException.";
387       }
388       catch ( CORBA::Exception& ) {
389         MESSAGE( "Caught CORBA::Exception." );
390         error = "Caught CORBA::Exception.";
391       }
392       catch (...) {
393         MESSAGE( "Caught unknown exception." );
394         error = "Caught unknown exception.";
395       }
396     }
397     if ( !bOk ) {
398       QtxSplash::error( QString( "C++ container is not found.\n%1" ).arg ( error ) );
399       return;
400     }
401     QtxSplash::setStatus( info.arg( "Waiting for C++ container...OK" ), ++current * myAttempts );
402     QThread::usleep( 300000 );
403   }
404
405   // 7. Check Python container
406   if ( myCheckPyContainer ) {
407     bOk = false;
408     for ( i = 0; i < myAttempts ; i++ ) {
409       QtxSplash::setStatus( info.arg( "Waiting for Python container..." ), current * myAttempts + i );
410       QThread::usleep( i == 0 ? 500000 : myDelay );
411       try {
412         CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
413         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
414         ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
415         NS.init_orb( orb );
416         QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( GetHostname() );
417         CORBA::Object_var obj = NS.Resolve( containerName.latin1() );
418         Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj );
419         if ( !CORBA::is_nil( FSPcontainer ) ) {
420           MESSAGE( containerName.latin1() << " is found" );
421           FSPcontainer->ping();
422           MESSAGE("FactoryServerPy container was activated");
423           bOk = true;
424           break;
425         }
426       }
427       catch ( ServiceUnreachable& ) {
428         MESSAGE( "Caught exception: Naming Service unreachable." );
429         error = "Naming service unreachable";
430       }
431       catch ( CORBA::COMM_FAILURE& ) {
432         MESSAGE( "Caught CORBA::SystemException CommFailure." );
433         error = "Caught CORBA::SystemException CommFailure.";
434       }
435       catch ( CORBA::SystemException& ) {
436         MESSAGE( "Caught CORBA::SystemException." );
437         error = "Caught CORBA::SystemException.";
438       }
439       catch ( CORBA::Exception& ) {
440         MESSAGE( "Caught CORBA::Exception." );
441         error = "Caught CORBA::Exception.";
442       }
443       catch (...) {
444         MESSAGE( "Caught unknown exception." );
445         error = "Caught unknown exception.";
446       }
447     }
448     if ( !bOk ) {
449       QtxSplash::error( QString( "Python container is not found.\n%1" ).arg ( error ) );
450       return;
451     }
452     QtxSplash::setStatus( info.arg( "Waiting for Python container...OK" ), ++current * myAttempts );
453     QThread::usleep( 300000 );
454   }
455
456   // 8. Check supervision container
457   if ( myCheckSVContainer ) {
458     bOk = false;
459     for ( i = 0; i < myAttempts ; i++ ) {
460       QtxSplash::setStatus( info.arg( "Waiting for Supervision container..." ), current * myAttempts + i );
461       QThread::usleep( i == 0 ? 500000 : myDelay );
462       try {
463         CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
464         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
465         ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
466         NS.init_orb( orb );
467         QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( GetHostname() );
468         CORBA::Object_var obj = NS.Resolve( containerName.latin1() );
469         Engines::Container_var SVcontainer = Engines::Container::_narrow( obj );
470         if ( !CORBA::is_nil( SVcontainer ) ) {
471           MESSAGE( containerName.latin1() << " is found" );
472           SVcontainer->ping();
473           MESSAGE("SuperVisionContainer container was activated");
474           bOk = true;
475           break;
476         }
477       }
478       catch ( ServiceUnreachable& ) {
479         MESSAGE( "Caught exception: Naming Service unreachable." );
480         error = "Naming service unreachable";
481       }
482       catch ( CORBA::COMM_FAILURE& ) {
483         MESSAGE( "Caught CORBA::SystemException CommFailure." );
484         error = "Caught CORBA::SystemException CommFailure.";
485       }
486       catch ( CORBA::SystemException& ) {
487         MESSAGE( "Caught CORBA::SystemException." );
488         error = "Caught CORBA::SystemException.";
489       }
490       catch ( CORBA::Exception& ) {
491         MESSAGE( "Caught CORBA::Exception." );
492         error = "Caught CORBA::Exception.";
493       }
494       catch (...) {
495         MESSAGE( "Caught unknown exception." );
496         error = "Caught unknown exception.";
497       }
498     }
499     if ( !bOk ) {
500       QtxSplash::error( QString( "Supervision container is not found.\n%1" ).arg ( error ) );
501       return;
502     }
503     QtxSplash::setStatus( info.arg( "Waiting for Supervision container...OK" ), ++current * myAttempts );
504     QThread::usleep( 300000 );
505   }
506   // clear splash status
507   splash->setProgress( 0, 0 );
508   splash->setStatus( initialInfo );
509 }