1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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
23 // File : Session_ServerCheck.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 #include "Session_ServerCheck.hxx"
28 #include <SALOMEconfig.h>
29 #include CORBA_CLIENT_HEADER(SALOME_Session)
30 #include CORBA_CLIENT_HEADER(SALOME_Registry)
31 #include CORBA_CLIENT_HEADER(SALOMEDS)
32 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
33 #include CORBA_CLIENT_HEADER(SALOME_Component)
35 #include "Utils_ORB_INIT.hxx"
36 #include "Utils_SINGLETON.hxx"
37 #include "SALOME_NamingService.hxx"
38 #include "Basics_Utils.hxx"
39 #include "utilities.h"
41 #include <QApplication>
42 #include <QWaitCondition>
43 #include <QMutexLocker>
44 #include <QStringList>
51 \brief Default number of attemtps to check SALOME server.
53 This value can be changed by setting the CSF_RepeatServerRequest
54 environment variable. For example, to set number of check attempts
55 for each server to 1000:
57 setenv CSF_RepeatServerRequest 1000
60 const int __DEFAULT__ATTEMPTS__ = 300;
63 \brief Default delay between attempts (in microseconds).
65 This value can be changed by setting the CSF_DelayServerRequest
66 environment variable. For example, to set delay between attemtps
67 to check SALOME servers to 100000 (0.1 second):
69 setenv CSF_DelayServerRequest 100000
72 const int __DEFAULT__DELAY__ = 50000;
75 \classSession_ServerCheck::Locker
76 \brief Automatic locker/unlocker.
80 class Session_ServerCheck::Locker
84 \brief Constructor. Tries to aquire lock.
86 Locker( Session_ServerCheck* sc )
89 myChecker->myMutex->lock();
90 myChecker->myMutex->unlock();
93 \brief Destructor. Wakes the calling thread and goes sleeping.
97 myChecker->myWC->wakeAll();
98 myChecker->usleep( myChecker->myDelay );
101 Session_ServerCheck* myChecker;
105 \class Session_ServerCheck
106 \brief The class Session_ServerCheck is used to check SALOME
107 servers availability.
109 It runs in the secondrary thread. The number of attemts to check
110 each SALOME server and the time delay between checks can be specified
111 via setting the CSF_RepeatServerRequest and CSF_DelayServerRequest
112 environment variables.
114 Total number of the check attempts can be retrieved via totalSteps()
115 method and current check step can be retrieved via currentStep() method.
117 The method currentMessage() can be used to get the information message
118 about what SALOME server is currently checked. If any error occured (some
119 server could not be found) the thread loop is stopped and error status
120 is set. Error message can be retrieved with the error() method.
125 \param mutex a mutex used to serialize progress operations (splash)
126 \param wc a wait condition used in combination with \a mutex
128 Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc )
132 myCheckCppContainer( false ),
133 myCheckPyContainer( false ),
134 myCheckSVContainer( false ),
135 myAttempts( __DEFAULT__ATTEMPTS__ ),
136 myDelay ( __DEFAULT__DELAY__ ),
140 // try to get nb of attempts from environment variable
141 if ( ( cenv = getenv( "CSF_RepeatServerRequest" ) ) && atoi( cenv ) > 0 )
142 myAttempts = atoi( cenv );
143 // try to get delay between attempts from environment variable
144 if ( ( cenv = getenv( "CSF_DelayServerRequest" ) ) && atoi( cenv ) > 0 )
145 myDelay = atoi( cenv );
147 // parse command line check if it is necessary to wait SALOME containers
148 QStringList args = QApplication::arguments();
149 for ( int i = 1; i < args.count(); i++ ) {
150 myCheckCppContainer = myCheckCppContainer || args[i] == "CPP";
151 myCheckPyContainer = myCheckPyContainer || args[i] == "PY";
152 myCheckSVContainer = myCheckSVContainer || args[i] == "SUPERV";
162 Session_ServerCheck::~Session_ServerCheck()
165 while( isRunning() );
169 \brief Get current information message.
170 \return current message
172 QString Session_ServerCheck::currentMessage()
174 static QStringList messages;
175 if ( messages.isEmpty() ) {
176 messages << tr( "Waiting for naming service..." );
177 messages << tr( "Waiting for registry server..." );
178 messages << tr( "Waiting for study server..." );
179 messages << tr( "Waiting for module catalogue server..." );
180 messages << tr( "Waiting for session server..." );
181 messages << tr( "Waiting for C++ container..." );
182 messages << tr( "Waiting for Python container..." );
183 messages << tr( "Waiting for Supervision container..." );
185 QMutexLocker locker( &myDataMutex );
187 int idx = myCurrentStep / myAttempts;
188 if ( idx >= 0 && idx < messages.count() )
189 msg = messages[ idx ];
194 \brief Get error message.
195 \return error message or null string of there was no any error
197 QString Session_ServerCheck::error()
199 QMutexLocker locker( &myDataMutex );
204 \brief Get current step.
207 int Session_ServerCheck::currentStep()
209 QMutexLocker locker( &myDataMutex );
210 return myCurrentStep;
214 \brief Get total number of check steps.
215 \return total number of steps
217 int Session_ServerCheck::totalSteps()
219 QMutexLocker locker( &myDataMutex );
220 int cnt = 5; // base servers
221 if ( myCheckCppContainer ) cnt++; // + C++ container
222 if ( myCheckPyContainer ) cnt++; // + Python container
223 if ( myCheckSVContainer ) cnt++; // + supervision container
224 return cnt * myAttempts;
228 \brief Modify current step.
229 \param step new current step value
231 void Session_ServerCheck::setStep( const int step )
233 QMutexLocker locker( &myDataMutex );
234 myCurrentStep = step;
238 \brief Set error message.
239 \param msg error message
241 void Session_ServerCheck::setError( const QString& msg )
243 QMutexLocker locker( &myDataMutex );
248 \brief Thread loop function. Performs SALOME servers check.
250 void Session_ServerCheck::run()
252 // start check servers
255 int argc = QApplication::instance()->argc();
256 char** argv = QApplication::instance()->argv();
258 // 1. Check naming service
259 for ( int i = 0; i < myAttempts; i++ ) {
260 Locker locker( this );
262 setStep( current * myAttempts + i );
265 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
266 CORBA::Object_var obj = orb->resolve_initial_references( "NameService" );
267 CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow( obj );
268 if ( !CORBA::is_nil( _root_context ) ) {
269 setStep( ++current * myAttempts );
273 catch( CORBA::COMM_FAILURE& ) {
274 MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" );
277 MESSAGE( "Unknown Exception: unable to contact the naming service" );
280 if ( i == myAttempts-1 ) {
281 setError( tr( "Unable to contact the naming service.\n" ) );
286 // 2. Check registry server
287 for ( int i = 0; i < myAttempts ; i++ ) {
288 Locker locker( this );
290 setStep( current * myAttempts + i );
293 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
294 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
295 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
297 CORBA::Object_var obj = NS.Resolve( "/Registry" );
298 Registry::Components_var registry = Registry::Components::_narrow( obj );
299 if ( !CORBA::is_nil( registry ) ) {
300 MESSAGE( "/Registry is found" );
302 MESSAGE( "Registry was activated" );
303 setStep( ++current * myAttempts );
307 catch ( ServiceUnreachable& ) {
308 MESSAGE( "Caught exception: Naming Service unreachable." );
309 error = "Naming service unreachable";
311 catch ( CORBA::COMM_FAILURE& ) {
312 MESSAGE( "Caught CORBA::SystemException CommFailure." );
313 error = "Caught CORBA::SystemException CommFailure.";
315 catch ( CORBA::SystemException& ) {
316 MESSAGE( "Caught CORBA::SystemException." );
317 error = "Caught CORBA::SystemException.";
319 catch ( CORBA::Exception& ) {
320 MESSAGE( "Caught CORBA::Exception." );
321 error = "Caught CORBA::Exception.";
324 MESSAGE( "Caught unknown exception." );
325 error = "Caught unknown exception.";
328 if ( i == myAttempts-1 ) {
329 setError( tr( "Registry server is not found.\n%1" ).arg ( error ) );
334 // 3. Check data server
335 for ( int i = 0; i < myAttempts ; i++ ) {
336 Locker locker( this );
338 setStep( current * myAttempts + i );
341 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
342 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
343 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
345 CORBA::Object_var obj = NS.Resolve( "/myStudyManager" );
346 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj );
347 if ( !CORBA::is_nil( studyManager ) ) {
348 MESSAGE( "/myStudyManager is found" );
349 studyManager->ping();
350 MESSAGE( "StudyManager was activated" );
351 setStep( ++current * myAttempts );
355 catch ( ServiceUnreachable& ) {
356 MESSAGE( "Caught exception: Naming Service unreachable." );
357 error = "Naming service unreachable";
359 catch ( CORBA::COMM_FAILURE& ) {
360 MESSAGE( "Caught CORBA::SystemException CommFailure." );
361 error = "Caught CORBA::SystemException CommFailure.";
363 catch ( CORBA::SystemException& ) {
364 MESSAGE( "Caught CORBA::SystemException." );
365 error = "Caught CORBA::SystemException.";
367 catch ( CORBA::Exception& ) {
368 MESSAGE( "Caught CORBA::Exception." );
369 error = "Caught CORBA::Exception.";
372 MESSAGE( "Caught unknown exception." );
373 error = "Caught unknown exception.";
376 if ( i == myAttempts-1 ) {
377 setError( tr( "Study server is not found.\n%1" ).arg ( error ) );
382 // 4. Check module catalogue server
383 for ( int i = 0; i < myAttempts ; i++ ) {
384 Locker locker( this );
386 setStep( current * myAttempts + i );
389 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
390 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
391 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
393 CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" );
394 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
395 if ( !CORBA::is_nil( catalog ) ){
396 MESSAGE( "/Kernel/ModulCatalog is found" );
398 MESSAGE( "ModuleCatalog was activated" );
399 setStep( ++current * myAttempts );
403 catch ( ServiceUnreachable& ) {
404 MESSAGE( "Caught exception: Naming Service unreachable." );
405 error = "Naming service unreachable";
407 catch ( CORBA::COMM_FAILURE& ) {
408 MESSAGE( "Caught CORBA::SystemException CommFailure." );
409 error = "Caught CORBA::SystemException CommFailure.";
411 catch ( CORBA::SystemException& ) {
412 MESSAGE( "Caught CORBA::SystemException." );
413 error = "Caught CORBA::SystemException.";
415 catch ( CORBA::Exception& ) {
416 MESSAGE( "Caught CORBA::Exception." );
417 error = "Caught CORBA::Exception.";
420 MESSAGE( "Caught unknown exception." );
421 error = "Caught unknown exception.";
424 if ( i == myAttempts-1 ) {
425 setError( tr( "Module catalogue server is not found.\n%1" ).arg ( error ) );
430 // 5. Check data server
431 for ( int i = 0; i < myAttempts ; i++ ) {
432 Locker locker( this );
434 setStep( current * myAttempts + i );
437 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
438 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
439 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
441 CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" );
442 SALOME::Session_var session = SALOME::Session::_narrow( obj );
443 if ( !CORBA::is_nil( session ) ) {
444 MESSAGE( "/Kernel/Session is found" );
446 MESSAGE( "SALOME_Session was activated" );
447 setStep( ++current * myAttempts );
451 catch ( ServiceUnreachable& ) {
452 MESSAGE( "Caught exception: Naming Service unreachable." );
453 error = "Naming service unreachable";
455 catch ( CORBA::COMM_FAILURE& ) {
456 MESSAGE( "Caught CORBA::SystemException CommFailure." );
457 error = "Caught CORBA::SystemException CommFailure.";
459 catch ( CORBA::SystemException& ) {
460 MESSAGE( "Caught CORBA::SystemException." );
461 error = "Caught CORBA::SystemException.";
463 catch ( CORBA::Exception& ) {
464 MESSAGE( "Caught CORBA::Exception." );
465 error = "Caught CORBA::Exception.";
468 MESSAGE( "Caught unknown exception." );
469 error = "Caught unknown exception.";
472 if ( i == myAttempts-1 ) {
473 setError( tr( "Session server is not found.\n%1" ).arg ( error ) );
478 // 6. Check C++ container
479 if ( myCheckCppContainer ) {
480 for ( int i = 0; i < myAttempts ; i++ ) {
481 Locker locker( this );
483 setStep( current * myAttempts + i );
486 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
487 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
488 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
490 QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( Kernel_Utils::GetHostname().c_str() );
491 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
492 Engines::Container_var FScontainer = Engines::Container::_narrow( obj );
493 if ( !CORBA::is_nil( FScontainer ) ) {
494 MESSAGE( containerName.toLatin1().constData() << " is found" );
496 MESSAGE( "FactoryServer container was activated" );
497 setStep( ++current * myAttempts );
501 catch ( ServiceUnreachable& ) {
502 MESSAGE( "Caught exception: Naming Service unreachable." );
503 error = "Naming service unreachable";
505 catch ( CORBA::COMM_FAILURE& ) {
506 MESSAGE( "Caught CORBA::SystemException CommFailure." );
507 error = "Caught CORBA::SystemException CommFailure.";
509 catch ( CORBA::SystemException& ) {
510 MESSAGE( "Caught CORBA::SystemException." );
511 error = "Caught CORBA::SystemException.";
513 catch ( CORBA::Exception& ) {
514 MESSAGE( "Caught CORBA::Exception." );
515 error = "Caught CORBA::Exception.";
518 MESSAGE( "Caught unknown exception." );
519 error = "Caught unknown exception.";
522 if ( i == myAttempts-1 ) {
523 setError( tr( "C++ container is not found.\n%1" ).arg ( error ) );
529 // 7. Check Python container
530 if ( myCheckPyContainer ) {
531 for ( int i = 0; i < myAttempts ; i++ ) {
532 Locker locker( this );
534 setStep( current * myAttempts + i );
537 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
538 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
539 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
541 QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( Kernel_Utils::GetHostname().c_str() );
542 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
543 Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj );
544 if ( !CORBA::is_nil( FSPcontainer ) ) {
545 MESSAGE( containerName.toLatin1().constData() << " is found" );
546 FSPcontainer->ping();
547 MESSAGE("FactoryServerPy container was activated");
548 setStep( ++current * myAttempts );
552 catch ( ServiceUnreachable& ) {
553 MESSAGE( "Caught exception: Naming Service unreachable." );
554 error = "Naming service unreachable";
556 catch ( CORBA::COMM_FAILURE& ) {
557 MESSAGE( "Caught CORBA::SystemException CommFailure." );
558 error = "Caught CORBA::SystemException CommFailure.";
560 catch ( CORBA::SystemException& ) {
561 MESSAGE( "Caught CORBA::SystemException." );
562 error = "Caught CORBA::SystemException.";
564 catch ( CORBA::Exception& ) {
565 MESSAGE( "Caught CORBA::Exception." );
566 error = "Caught CORBA::Exception.";
569 MESSAGE( "Caught unknown exception." );
570 error = "Caught unknown exception.";
573 if ( i == myAttempts-1 ) {
574 setError( tr( "Python container is not found.\n%1" ).arg ( error ) );
580 // 8. Check supervision container
581 if ( myCheckSVContainer ) {
582 for ( int i = 0; i < myAttempts ; i++ ) {
583 Locker locker( this );
585 setStep( current * myAttempts + i );
588 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
589 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
590 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
592 QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( Kernel_Utils::GetHostname().c_str() );
593 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
594 Engines::Container_var SVcontainer = Engines::Container::_narrow( obj );
595 if ( !CORBA::is_nil( SVcontainer ) ) {
596 MESSAGE( containerName.toLatin1().constData() << " is found" );
598 MESSAGE("SuperVisionContainer container was activated");
599 setStep( ++current * myAttempts );
603 catch ( ServiceUnreachable& ) {
604 MESSAGE( "Caught exception: Naming Service unreachable." );
605 error = "Naming service unreachable";
607 catch ( CORBA::COMM_FAILURE& ) {
608 MESSAGE( "Caught CORBA::SystemException CommFailure." );
609 error = "Caught CORBA::SystemException CommFailure.";
611 catch ( CORBA::SystemException& ) {
612 MESSAGE( "Caught CORBA::SystemException." );
613 error = "Caught CORBA::SystemException.";
615 catch ( CORBA::Exception& ) {
616 MESSAGE( "Caught CORBA::Exception." );
617 error = "Caught CORBA::Exception.";
620 MESSAGE( "Caught unknown exception." );
621 error = "Caught unknown exception.";
624 if ( i == myAttempts-1 ) {
625 setError( tr( "Supervision container is not found.\n%1" ).arg ( error ) );