]> SALOME platform Git repositories - modules/gui.git/blob - src/Session/Session_ServerCheck.cxx
Salome HOME
4003b22accdad1f9a87c28eefb0861062c7f8635
[modules/gui.git] / src / Session / Session_ServerCheck.cxx
1 //  Copyright (C) 2007-2008  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 // File   : Session_ServerCheck.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
24 //
25 #include "Session_ServerCheck.hxx"
26
27 #include <SALOMEconfig.h>
28 #include CORBA_CLIENT_HEADER(SALOME_Session)
29 #include CORBA_CLIENT_HEADER(SALOME_Registry)
30 #include CORBA_CLIENT_HEADER(SALOMEDS)
31 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
32 #include CORBA_CLIENT_HEADER(SALOME_Component)
33
34 #include "Utils_ORB_INIT.hxx"
35 #include "Utils_SINGLETON.hxx"
36 #include "SALOME_NamingService.hxx"
37 #include "Basics_Utils.hxx"
38 #include "utilities.h"
39
40 #include <QApplication> 
41 #include <QWaitCondition>
42 #include <QMutexLocker>
43 #include <QStringList>
44
45 //
46 // Default settings
47 //
48
49 /*!
50   \brief Default number of attemtps to check SALOME server.
51
52   This value can be changed by setting the CSF_RepeatServerRequest
53   environment variable. For example, to set number of check attempts
54   for each server to 1000:
55   \code
56   setenv CSF_RepeatServerRequest 1000
57   \endcode
58 */
59 const int __DEFAULT__ATTEMPTS__ = 300;
60
61 /*!
62   \brief Default delay between attempts (in microseconds).
63
64   This value can be changed by setting the CSF_DelayServerRequest
65   environment variable. For example, to set delay between attemtps
66   to check SALOME servers to 100000 (0.1 second):
67   \code
68   setenv CSF_DelayServerRequest 100000
69   \endcode
70 */
71 const int __DEFAULT__DELAY__ = 50000;
72
73 /*!
74   \classSession_ServerCheck::Locker
75   \brief Automatic locker/unlocker.
76   \internal
77 */
78
79 class Session_ServerCheck::Locker
80 {
81 public:
82   /*!
83     \brief Constructor. Tries to aquire lock.
84   */
85   Locker( Session_ServerCheck* sc ) 
86     : myChecker( sc )
87   {
88     myChecker->myMutex->lock();
89     myChecker->myMutex->unlock();
90   }
91   /*!
92     \brief Destructor. Wakes the calling thread and goes sleeping.
93   */
94   ~Locker()
95   {
96     myChecker->myWC->wakeAll();
97     myChecker->usleep( myChecker->myDelay );
98   }
99 private:
100   Session_ServerCheck* myChecker;
101 };
102
103 /*!
104   \class Session_ServerCheck
105   \brief The class Session_ServerCheck is used to check SALOME
106   servers availability.
107   
108   It runs in the secondrary thread. The number of attemts to check
109   each SALOME server and the time delay between checks can be specified
110   via setting the CSF_RepeatServerRequest and CSF_DelayServerRequest
111   environment variables.
112
113   Total number of the check attempts can be retrieved via totalSteps()
114   method and current check step can be retrieved via currentStep() method.
115
116   The method currentMessage() can be used to get the information message
117   about what SALOME server is currently checked. If any error occured (some
118   server could not be found) the thread loop is stopped and error status
119   is set. Error message can be retrieved with the error() method.
120 */
121
122 /*!
123   \brief Constructor.
124   \param mutex a mutex used to serialize progress operations (splash)
125   \param wc a wait condition used in combination with \a mutex
126 */
127 Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc )
128 : QThread(),
129   myMutex( mutex ),
130   myWC( wc ),
131   myCheckCppContainer( false ),
132   myCheckPyContainer( false ),
133   myCheckSVContainer( false ),
134   myAttempts( __DEFAULT__ATTEMPTS__ ),
135   myDelay   ( __DEFAULT__DELAY__ ),
136   myCurrentStep( 0 )
137 {
138   char* cenv;
139   // try to get nb of attempts from environment variable
140   if ( ( cenv = getenv( "CSF_RepeatServerRequest" ) ) && atoi( cenv ) > 0 )
141     myAttempts = atoi( cenv );
142   // try to get delay between attempts from environment variable
143   if ( ( cenv = getenv( "CSF_DelayServerRequest" ) ) && atoi( cenv ) > 0 )
144     myDelay = atoi( cenv );
145
146   // parse command line check if it is necessary to wait SALOME containers
147   QStringList args = QApplication::arguments();
148   for ( int i = 1; i < args.count(); i++ ) {
149     myCheckCppContainer = myCheckCppContainer || args[i] == "CPP";
150     myCheckPyContainer  = myCheckPyContainer  || args[i] == "PY";
151     myCheckSVContainer  = myCheckSVContainer  || args[i] == "SUPERV";
152   }
153   
154   // start thread
155   start();
156 }
157
158 /*!
159   \brief Destructor
160 */
161 Session_ServerCheck::~Session_ServerCheck()
162 {
163   terminate();
164   while( isRunning() );
165 }
166
167 /*!
168   \brief Get current information message.
169   \return current message
170 */
171 QString Session_ServerCheck::currentMessage()
172 {
173   static QStringList messages;
174   if ( messages.isEmpty() ) {
175     messages << tr( "Waiting for naming service..." ); 
176     messages << tr( "Waiting for registry server..." );
177     messages << tr( "Waiting for study server..." );
178     messages << tr( "Waiting for module catalogue server..." );
179     messages << tr( "Waiting for session server..." );
180     messages << tr( "Waiting for C++ container..." );
181     messages << tr( "Waiting for Python container..." );
182     messages << tr( "Waiting for Supervision container..." );
183   }
184   QMutexLocker locker( &myDataMutex );
185   QString msg;
186   int idx = myCurrentStep / myAttempts;
187   if ( idx >= 0 && idx < messages.count() )
188     msg = messages[ idx ];
189   return msg;
190 }
191
192 /*!
193   \brief Get error message.
194   \return error message or null string of there was no any error
195 */
196 QString Session_ServerCheck::error()
197 {
198   QMutexLocker locker( &myDataMutex );
199   return myError;
200 }
201
202 /*!
203   \brief Get current step.
204   \return current step
205 */
206 int Session_ServerCheck::currentStep()
207 {
208   QMutexLocker locker( &myDataMutex );
209   return myCurrentStep;
210 }
211
212 /*!
213   \brief Get total number of check steps.
214   \return total number of steps
215 */
216 int Session_ServerCheck::totalSteps()
217 {
218   QMutexLocker locker( &myDataMutex );
219   int cnt = 5;                       // base servers
220   if ( myCheckCppContainer ) cnt++;  // + C++ container
221   if ( myCheckPyContainer )  cnt++;  // + Python container
222   if ( myCheckSVContainer )  cnt++;  // + supervision container
223   return cnt * myAttempts;
224 }
225
226 /*!
227   \brief Modify current step.
228   \param step new current step value
229 */
230 void Session_ServerCheck::setStep( const int step )
231 {
232   QMutexLocker locker( &myDataMutex );
233   myCurrentStep = step;
234 }
235
236 /*!
237   \brief Set error message.
238   \param msg error message
239 */
240 void Session_ServerCheck::setError( const QString& msg )
241 {
242   QMutexLocker locker( &myDataMutex );
243   myError = msg;
244 }
245
246 /*!
247   \brief Thread loop function. Performs SALOME servers check.
248 */
249 void Session_ServerCheck::run()
250 {
251   // start check servers
252   int current = 0;
253   QString error;
254   int    argc = QApplication::instance()->argc();
255   char** argv = QApplication::instance()->argv();
256
257   // 1. Check naming service
258   for ( int i = 0; i < myAttempts; i++ ) {
259     Locker locker( this );
260
261     setStep( current * myAttempts + i );
262
263     try {
264       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
265       CORBA::Object_var obj = orb->resolve_initial_references( "NameService" );
266       CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow( obj );
267       if ( !CORBA::is_nil( _root_context ) ) {
268         setStep( ++current * myAttempts );
269         break;
270       }
271     }
272     catch( CORBA::COMM_FAILURE& ) {
273       MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" );
274     }
275     catch( ... ) {
276       MESSAGE( "Unknown Exception: unable to contact the naming service" );
277     }
278
279     if ( i == myAttempts-1 ) {
280       setError( tr( "Unable to contact the naming service.\n" ) );
281       return;
282     }
283   }
284
285   // 2. Check registry server
286   for ( int i = 0; i < myAttempts ; i++ ) {
287     Locker locker( this );
288
289     setStep( current * myAttempts + i );
290
291     try {
292       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
293       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
294       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
295       NS.init_orb( orb );
296       CORBA::Object_var obj = NS.Resolve( "/Registry" );
297       Registry::Components_var registry = Registry::Components::_narrow( obj );
298       if ( !CORBA::is_nil( registry ) ) {
299         MESSAGE( "/Registry is found" );
300         registry->ping();
301         MESSAGE( "Registry was activated" );
302         setStep( ++current * myAttempts );
303         break;
304       }
305     }
306     catch ( ServiceUnreachable& ) {
307       MESSAGE( "Caught exception: Naming Service unreachable." );
308       error = "Naming service unreachable";
309     }
310     catch ( CORBA::COMM_FAILURE& ) {
311       MESSAGE( "Caught CORBA::SystemException CommFailure." );
312       error = "Caught CORBA::SystemException CommFailure.";
313     }
314     catch ( CORBA::SystemException& ) {
315       MESSAGE( "Caught CORBA::SystemException." );
316       error = "Caught CORBA::SystemException.";
317     }
318     catch ( CORBA::Exception& ) {
319       MESSAGE( "Caught CORBA::Exception." );
320       error = "Caught CORBA::Exception.";
321     }
322     catch (...) {
323       MESSAGE( "Caught unknown exception." );
324       error = "Caught unknown exception.";
325     }
326
327     if ( i == myAttempts-1 ) {
328       setError( tr( "Registry server is not found.\n%1" ).arg ( error ) );
329       return;
330     }
331   }
332
333   // 3. Check data server
334   for ( int i = 0; i < myAttempts ; i++ ) {
335     Locker locker( this );
336
337     setStep( current * myAttempts + i );
338
339     try {
340       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
341       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
342       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
343       NS.init_orb( orb );
344       CORBA::Object_var obj = NS.Resolve( "/myStudyManager" );
345       SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj );
346       if ( !CORBA::is_nil( studyManager ) ) {
347         MESSAGE( "/myStudyManager is found" );
348         studyManager->ping();
349         MESSAGE( "StudyManager was activated" );
350         setStep( ++current * myAttempts );
351         break;
352       }
353     }
354     catch ( ServiceUnreachable& ) {
355       MESSAGE( "Caught exception: Naming Service unreachable." );
356       error = "Naming service unreachable";
357     }
358     catch ( CORBA::COMM_FAILURE& ) {
359       MESSAGE( "Caught CORBA::SystemException CommFailure." );
360       error = "Caught CORBA::SystemException CommFailure.";
361     }
362     catch ( CORBA::SystemException& ) {
363       MESSAGE( "Caught CORBA::SystemException." );
364       error = "Caught CORBA::SystemException.";
365     }
366     catch ( CORBA::Exception& ) {
367       MESSAGE( "Caught CORBA::Exception." );
368       error = "Caught CORBA::Exception.";
369     }
370     catch (...) {
371       MESSAGE( "Caught unknown exception." );
372       error = "Caught unknown exception.";
373     }
374
375     if ( i == myAttempts-1 ) {
376       setError( tr( "Study server is not found.\n%1" ).arg ( error ) );
377       return;
378     }
379   }
380   
381   // 4. Check module catalogue server
382   for ( int i = 0; i < myAttempts ; i++ ) {
383     Locker locker( this );
384
385     setStep( current * myAttempts + i );
386
387     try {
388       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
389       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
390       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
391       NS.init_orb( orb );
392       CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" );
393       SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
394       if ( !CORBA::is_nil( catalog ) ){
395         MESSAGE( "/Kernel/ModulCatalog is found" );
396         catalog->ping();
397         MESSAGE( "ModuleCatalog was activated" );
398         setStep( ++current * myAttempts );
399         break;
400       }
401     }
402     catch ( ServiceUnreachable& ) {
403       MESSAGE( "Caught exception: Naming Service unreachable." );
404       error = "Naming service unreachable";
405     }
406     catch ( CORBA::COMM_FAILURE& ) {
407       MESSAGE( "Caught CORBA::SystemException CommFailure." );
408       error = "Caught CORBA::SystemException CommFailure.";
409     }
410     catch ( CORBA::SystemException& ) {
411       MESSAGE( "Caught CORBA::SystemException." );
412       error = "Caught CORBA::SystemException.";
413     }
414     catch ( CORBA::Exception& ) {
415       MESSAGE( "Caught CORBA::Exception." );
416       error = "Caught CORBA::Exception.";
417     }
418     catch (...) {
419       MESSAGE( "Caught unknown exception." );
420       error = "Caught unknown exception.";
421     }
422
423     if ( i == myAttempts-1 ) {
424       setError( tr( "Module catalogue server is not found.\n%1" ).arg ( error ) );
425       return;
426     }
427   }
428
429   // 5. Check data server
430   for ( int i = 0; i < myAttempts ; i++ ) {
431     Locker locker( this );
432
433     setStep( current * myAttempts + i );
434
435     try {
436       CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
437       SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
438       ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
439       NS.init_orb( orb );
440       CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" );
441       SALOME::Session_var session = SALOME::Session::_narrow( obj );
442       if ( !CORBA::is_nil( session ) ) {
443         MESSAGE( "/Kernel/Session is found" );
444         session->ping();
445         MESSAGE( "SALOME_Session was activated" );
446         setStep( ++current * myAttempts );
447         break;
448       }
449     }
450     catch ( ServiceUnreachable& ) {
451       MESSAGE( "Caught exception: Naming Service unreachable." );
452       error = "Naming service unreachable";
453     }
454     catch ( CORBA::COMM_FAILURE& ) {
455       MESSAGE( "Caught CORBA::SystemException CommFailure." );
456       error = "Caught CORBA::SystemException CommFailure.";
457     }
458     catch ( CORBA::SystemException& ) {
459       MESSAGE( "Caught CORBA::SystemException." );
460       error = "Caught CORBA::SystemException.";
461     }
462     catch ( CORBA::Exception& ) {
463       MESSAGE( "Caught CORBA::Exception." );
464       error = "Caught CORBA::Exception.";
465     }
466     catch (...) {
467       MESSAGE( "Caught unknown exception." );
468       error = "Caught unknown exception.";
469     }
470
471     if ( i == myAttempts-1 ) {
472       setError( tr( "Session server is not found.\n%1" ).arg ( error ) );
473       return;
474     }
475   }
476
477   // 6. Check C++ container
478   if ( myCheckCppContainer ) {
479     for ( int i = 0; i < myAttempts ; i++ ) {
480       Locker locker( this );
481       
482       setStep( current * myAttempts + i );
483
484       try {
485         CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
486         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
487         ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
488         NS.init_orb( orb );
489         QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( Kernel_Utils::GetHostname().c_str() );
490         CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
491         Engines::Container_var FScontainer = Engines::Container::_narrow( obj );
492         if ( !CORBA::is_nil( FScontainer ) ) {
493           MESSAGE( containerName.toLatin1().constData() << " is found" );
494           FScontainer->ping();
495           MESSAGE( "FactoryServer container was activated" );
496           setStep( ++current * myAttempts );
497           break;
498         }
499       }
500       catch ( ServiceUnreachable& ) {
501         MESSAGE( "Caught exception: Naming Service unreachable." );
502         error = "Naming service unreachable";
503       }
504       catch ( CORBA::COMM_FAILURE& ) {
505         MESSAGE( "Caught CORBA::SystemException CommFailure." );
506         error = "Caught CORBA::SystemException CommFailure.";
507       }
508       catch ( CORBA::SystemException& ) {
509         MESSAGE( "Caught CORBA::SystemException." );
510         error = "Caught CORBA::SystemException.";
511       }
512       catch ( CORBA::Exception& ) {
513         MESSAGE( "Caught CORBA::Exception." );
514         error = "Caught CORBA::Exception.";
515       }
516       catch (...) {
517         MESSAGE( "Caught unknown exception." );
518         error = "Caught unknown exception.";
519       }
520       
521       if ( i == myAttempts-1 ) {
522         setError( tr( "C++ container is not found.\n%1" ).arg ( error ) );
523         return;
524       }
525     }
526   }
527
528   // 7. Check Python container
529   if ( myCheckPyContainer ) {
530     for ( int i = 0; i < myAttempts ; i++ ) {
531       Locker locker( this );
532       
533       setStep( current * myAttempts + i );
534
535       try {
536         CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
537         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
538         ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
539         NS.init_orb( orb );
540         QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( Kernel_Utils::GetHostname().c_str() );
541         CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
542         Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj );
543         if ( !CORBA::is_nil( FSPcontainer ) ) {
544           MESSAGE( containerName.toLatin1().constData() << " is found" );
545           FSPcontainer->ping();
546           MESSAGE("FactoryServerPy container was activated");
547           setStep( ++current * myAttempts );
548           break;
549         }
550       }
551       catch ( ServiceUnreachable& ) {
552         MESSAGE( "Caught exception: Naming Service unreachable." );
553         error = "Naming service unreachable";
554       }
555       catch ( CORBA::COMM_FAILURE& ) {
556         MESSAGE( "Caught CORBA::SystemException CommFailure." );
557         error = "Caught CORBA::SystemException CommFailure.";
558       }
559       catch ( CORBA::SystemException& ) {
560         MESSAGE( "Caught CORBA::SystemException." );
561         error = "Caught CORBA::SystemException.";
562       }
563       catch ( CORBA::Exception& ) {
564         MESSAGE( "Caught CORBA::Exception." );
565         error = "Caught CORBA::Exception.";
566       }
567       catch (...) {
568         MESSAGE( "Caught unknown exception." );
569         error = "Caught unknown exception.";
570       }
571
572       if ( i == myAttempts-1 ) {
573         setError( tr( "Python container is not found.\n%1" ).arg ( error ) );
574         return;
575       }
576     }
577   }
578
579   // 8. Check supervision container
580   if ( myCheckSVContainer ) {
581     for ( int i = 0; i < myAttempts ; i++ ) {
582       Locker locker( this );
583       
584       setStep( current * myAttempts + i );
585
586       try {
587         CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
588         SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
589         ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
590         NS.init_orb( orb );
591         QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( Kernel_Utils::GetHostname().c_str() );
592         CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
593         Engines::Container_var SVcontainer = Engines::Container::_narrow( obj );
594         if ( !CORBA::is_nil( SVcontainer ) ) {
595           MESSAGE( containerName.toLatin1().constData() << " is found" );
596           SVcontainer->ping();
597           MESSAGE("SuperVisionContainer container was activated");
598           setStep( ++current * myAttempts );
599           break;
600         }
601       }
602       catch ( ServiceUnreachable& ) {
603         MESSAGE( "Caught exception: Naming Service unreachable." );
604         error = "Naming service unreachable";
605       }
606       catch ( CORBA::COMM_FAILURE& ) {
607         MESSAGE( "Caught CORBA::SystemException CommFailure." );
608         error = "Caught CORBA::SystemException CommFailure.";
609       }
610       catch ( CORBA::SystemException& ) {
611         MESSAGE( "Caught CORBA::SystemException." );
612         error = "Caught CORBA::SystemException.";
613       }
614       catch ( CORBA::Exception& ) {
615         MESSAGE( "Caught CORBA::Exception." );
616         error = "Caught CORBA::Exception.";
617       }
618       catch (...) {
619         MESSAGE( "Caught unknown exception." );
620         error = "Caught unknown exception.";
621       }
622     
623       if ( i == myAttempts-1 ) {
624         setError( tr( "Supervision container is not found.\n%1" ).arg ( error ) );
625         return;
626       }
627     }
628   }
629 }