1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : Session_ServerCheck.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "Session_ServerCheck.hxx"
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)
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"
40 #include <QApplication>
41 #include <QWaitCondition>
42 #include <QMutexLocker>
43 #include <QStringList>
50 \brief Default number of attemtps to check SALOME server.
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:
56 setenv CSF_RepeatServerRequest 1000
59 const int __DEFAULT__ATTEMPTS__ = 300;
62 \brief Default delay between attempts (in microseconds).
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):
68 setenv CSF_DelayServerRequest 100000
71 const int __DEFAULT__DELAY__ = 50000;
74 \classSession_ServerCheck::Locker
75 \brief Automatic locker/unlocker.
79 class Session_ServerCheck::Locker
83 \brief Constructor. Tries to aquire lock.
85 Locker( Session_ServerCheck* sc )
88 myChecker->myMutex->lock();
89 myChecker->myMutex->unlock();
92 \brief Destructor. Wakes the calling thread and goes sleeping.
96 myChecker->myWC->wakeAll();
97 myChecker->usleep( myChecker->myDelay );
100 Session_ServerCheck* myChecker;
104 \class Session_ServerCheck
105 \brief The class Session_ServerCheck is used to check SALOME
106 servers availability.
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.
113 Total number of the check attempts can be retrieved via totalSteps()
114 method and current check step can be retrieved via currentStep() method.
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.
124 \param mutex a mutex used to serialize progress operations (splash)
125 \param wc a wait condition used in combination with \a mutex
127 Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc )
131 myCheckCppContainer( false ),
132 myCheckPyContainer( false ),
133 myCheckSVContainer( false ),
134 myAttempts( __DEFAULT__ATTEMPTS__ ),
135 myDelay ( __DEFAULT__DELAY__ ),
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 );
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";
161 Session_ServerCheck::~Session_ServerCheck()
164 while( isRunning() );
168 \brief Get current information message.
169 \return current message
171 QString Session_ServerCheck::currentMessage()
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..." );
184 QMutexLocker locker( &myDataMutex );
186 int idx = myCurrentStep / myAttempts;
187 if ( idx >= 0 && idx < messages.count() )
188 msg = messages[ idx ];
193 \brief Get error message.
194 \return error message or null string of there was no any error
196 QString Session_ServerCheck::error()
198 QMutexLocker locker( &myDataMutex );
203 \brief Get current step.
206 int Session_ServerCheck::currentStep()
208 QMutexLocker locker( &myDataMutex );
209 return myCurrentStep;
213 \brief Get total number of check steps.
214 \return total number of steps
216 int Session_ServerCheck::totalSteps()
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;
227 \brief Modify current step.
228 \param step new current step value
230 void Session_ServerCheck::setStep( const int step )
232 QMutexLocker locker( &myDataMutex );
233 myCurrentStep = step;
237 \brief Set error message.
238 \param msg error message
240 void Session_ServerCheck::setError( const QString& msg )
242 QMutexLocker locker( &myDataMutex );
247 \brief Thread loop function. Performs SALOME servers check.
249 void Session_ServerCheck::run()
251 // start check servers
254 int argc = QApplication::instance()->argc();
255 char** argv = QApplication::instance()->argv();
257 // 1. Check naming service
258 for ( int i = 0; i < myAttempts; i++ ) {
259 Locker locker( this );
261 setStep( current * myAttempts + i );
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 );
272 catch( CORBA::COMM_FAILURE& ) {
273 MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" );
276 MESSAGE( "Unknown Exception: unable to contact the naming service" );
279 if ( i == myAttempts-1 ) {
280 setError( tr( "Unable to contact the naming service.\n" ) );
285 // 2. Check registry server
286 for ( int i = 0; i < myAttempts ; i++ ) {
287 Locker locker( this );
289 setStep( current * myAttempts + i );
292 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
293 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
294 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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" );
301 MESSAGE( "Registry was activated" );
302 setStep( ++current * myAttempts );
306 catch ( ServiceUnreachable& ) {
307 MESSAGE( "Caught exception: Naming Service unreachable." );
308 error = "Naming service unreachable";
310 catch ( CORBA::COMM_FAILURE& ) {
311 MESSAGE( "Caught CORBA::SystemException CommFailure." );
312 error = "Caught CORBA::SystemException CommFailure.";
314 catch ( CORBA::SystemException& ) {
315 MESSAGE( "Caught CORBA::SystemException." );
316 error = "Caught CORBA::SystemException.";
318 catch ( CORBA::Exception& ) {
319 MESSAGE( "Caught CORBA::Exception." );
320 error = "Caught CORBA::Exception.";
323 MESSAGE( "Caught unknown exception." );
324 error = "Caught unknown exception.";
327 if ( i == myAttempts-1 ) {
328 setError( tr( "Registry server is not found.\n%1" ).arg ( error ) );
333 // 3. Check data server
334 for ( int i = 0; i < myAttempts ; i++ ) {
335 Locker locker( this );
337 setStep( current * myAttempts + i );
340 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
341 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
342 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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 );
354 catch ( ServiceUnreachable& ) {
355 MESSAGE( "Caught exception: Naming Service unreachable." );
356 error = "Naming service unreachable";
358 catch ( CORBA::COMM_FAILURE& ) {
359 MESSAGE( "Caught CORBA::SystemException CommFailure." );
360 error = "Caught CORBA::SystemException CommFailure.";
362 catch ( CORBA::SystemException& ) {
363 MESSAGE( "Caught CORBA::SystemException." );
364 error = "Caught CORBA::SystemException.";
366 catch ( CORBA::Exception& ) {
367 MESSAGE( "Caught CORBA::Exception." );
368 error = "Caught CORBA::Exception.";
371 MESSAGE( "Caught unknown exception." );
372 error = "Caught unknown exception.";
375 if ( i == myAttempts-1 ) {
376 setError( tr( "Study server is not found.\n%1" ).arg ( error ) );
381 // 4. Check module catalogue server
382 for ( int i = 0; i < myAttempts ; i++ ) {
383 Locker locker( this );
385 setStep( current * myAttempts + i );
388 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
389 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
390 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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" );
397 MESSAGE( "ModuleCatalog was activated" );
398 setStep( ++current * myAttempts );
402 catch ( ServiceUnreachable& ) {
403 MESSAGE( "Caught exception: Naming Service unreachable." );
404 error = "Naming service unreachable";
406 catch ( CORBA::COMM_FAILURE& ) {
407 MESSAGE( "Caught CORBA::SystemException CommFailure." );
408 error = "Caught CORBA::SystemException CommFailure.";
410 catch ( CORBA::SystemException& ) {
411 MESSAGE( "Caught CORBA::SystemException." );
412 error = "Caught CORBA::SystemException.";
414 catch ( CORBA::Exception& ) {
415 MESSAGE( "Caught CORBA::Exception." );
416 error = "Caught CORBA::Exception.";
419 MESSAGE( "Caught unknown exception." );
420 error = "Caught unknown exception.";
423 if ( i == myAttempts-1 ) {
424 setError( tr( "Module catalogue server is not found.\n%1" ).arg ( error ) );
429 // 5. Check data server
430 for ( int i = 0; i < myAttempts ; i++ ) {
431 Locker locker( this );
433 setStep( current * myAttempts + i );
436 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
437 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
438 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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" );
445 MESSAGE( "SALOME_Session was activated" );
446 setStep( ++current * myAttempts );
450 catch ( ServiceUnreachable& ) {
451 MESSAGE( "Caught exception: Naming Service unreachable." );
452 error = "Naming service unreachable";
454 catch ( CORBA::COMM_FAILURE& ) {
455 MESSAGE( "Caught CORBA::SystemException CommFailure." );
456 error = "Caught CORBA::SystemException CommFailure.";
458 catch ( CORBA::SystemException& ) {
459 MESSAGE( "Caught CORBA::SystemException." );
460 error = "Caught CORBA::SystemException.";
462 catch ( CORBA::Exception& ) {
463 MESSAGE( "Caught CORBA::Exception." );
464 error = "Caught CORBA::Exception.";
467 MESSAGE( "Caught unknown exception." );
468 error = "Caught unknown exception.";
471 if ( i == myAttempts-1 ) {
472 setError( tr( "Session server is not found.\n%1" ).arg ( error ) );
477 // 6. Check C++ container
478 if ( myCheckCppContainer ) {
479 for ( int i = 0; i < myAttempts ; i++ ) {
480 Locker locker( this );
482 setStep( current * myAttempts + i );
485 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
486 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
487 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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" );
495 MESSAGE( "FactoryServer container was activated" );
496 setStep( ++current * myAttempts );
500 catch ( ServiceUnreachable& ) {
501 MESSAGE( "Caught exception: Naming Service unreachable." );
502 error = "Naming service unreachable";
504 catch ( CORBA::COMM_FAILURE& ) {
505 MESSAGE( "Caught CORBA::SystemException CommFailure." );
506 error = "Caught CORBA::SystemException CommFailure.";
508 catch ( CORBA::SystemException& ) {
509 MESSAGE( "Caught CORBA::SystemException." );
510 error = "Caught CORBA::SystemException.";
512 catch ( CORBA::Exception& ) {
513 MESSAGE( "Caught CORBA::Exception." );
514 error = "Caught CORBA::Exception.";
517 MESSAGE( "Caught unknown exception." );
518 error = "Caught unknown exception.";
521 if ( i == myAttempts-1 ) {
522 setError( tr( "C++ container is not found.\n%1" ).arg ( error ) );
528 // 7. Check Python container
529 if ( myCheckPyContainer ) {
530 for ( int i = 0; i < myAttempts ; i++ ) {
531 Locker locker( this );
533 setStep( current * myAttempts + i );
536 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
537 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
538 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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 );
551 catch ( ServiceUnreachable& ) {
552 MESSAGE( "Caught exception: Naming Service unreachable." );
553 error = "Naming service unreachable";
555 catch ( CORBA::COMM_FAILURE& ) {
556 MESSAGE( "Caught CORBA::SystemException CommFailure." );
557 error = "Caught CORBA::SystemException CommFailure.";
559 catch ( CORBA::SystemException& ) {
560 MESSAGE( "Caught CORBA::SystemException." );
561 error = "Caught CORBA::SystemException.";
563 catch ( CORBA::Exception& ) {
564 MESSAGE( "Caught CORBA::Exception." );
565 error = "Caught CORBA::Exception.";
568 MESSAGE( "Caught unknown exception." );
569 error = "Caught unknown exception.";
572 if ( i == myAttempts-1 ) {
573 setError( tr( "Python container is not found.\n%1" ).arg ( error ) );
579 // 8. Check supervision container
580 if ( myCheckSVContainer ) {
581 for ( int i = 0; i < myAttempts ; i++ ) {
582 Locker locker( this );
584 setStep( current * myAttempts + i );
587 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
588 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
589 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
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" );
597 MESSAGE("SuperVisionContainer container was activated");
598 setStep( ++current * myAttempts );
602 catch ( ServiceUnreachable& ) {
603 MESSAGE( "Caught exception: Naming Service unreachable." );
604 error = "Naming service unreachable";
606 catch ( CORBA::COMM_FAILURE& ) {
607 MESSAGE( "Caught CORBA::SystemException CommFailure." );
608 error = "Caught CORBA::SystemException CommFailure.";
610 catch ( CORBA::SystemException& ) {
611 MESSAGE( "Caught CORBA::SystemException." );
612 error = "Caught CORBA::SystemException.";
614 catch ( CORBA::Exception& ) {
615 MESSAGE( "Caught CORBA::Exception." );
616 error = "Caught CORBA::Exception.";
619 MESSAGE( "Caught unknown exception." );
620 error = "Caught unknown exception.";
623 if ( i == myAttempts-1 ) {
624 setError( tr( "Supervision container is not found.\n%1" ).arg ( error ) );