1 // Copyright (C) 2007-2015 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;
74 // The exception being thrown out of a destructor,
75 // that is not allowed by default in C++11.
77 #if __cplusplus >= 201103L
78 # define TYPE_NOEXCEPT noexcept(false)
80 # define TYPE_NOEXCEPT
84 \classSession_ServerCheck::Locker
85 \brief Automatic locker/unlocker.
89 class Session_ServerCheck::Locker
93 \brief Constructor. Tries to aquire lock.
95 Locker( Session_ServerCheck* sc )
98 myChecker->myMutex->lock();
99 myChecker->myMutex->unlock();
102 \brief Destructor. Wakes the calling thread and goes sleeping.
104 ~Locker() TYPE_NOEXCEPT
106 myChecker->myWC->wakeAll();
107 myChecker->usleep( myChecker->myDelay );
110 Session_ServerCheck* myChecker;
114 \class Session_ServerCheck
115 \brief The class Session_ServerCheck is used to check SALOME
116 servers availability.
118 It runs in the secondrary thread. The number of attemts to check
119 each SALOME server and the time delay between checks can be specified
120 via setting the CSF_RepeatServerRequest and CSF_DelayServerRequest
121 environment variables.
123 Total number of the check attempts can be retrieved via totalSteps()
124 method and current check step can be retrieved via currentStep() method.
126 The method currentMessage() can be used to get the information message
127 about what SALOME server is currently checked. If any error occured (some
128 server could not be found) the thread loop is stopped and error status
129 is set. Error message can be retrieved with the error() method.
134 \param mutex a mutex used to serialize progress operations (splash)
135 \param wc a wait condition used in combination with \a mutex
137 Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc )
141 myCheckCppContainer( false ),
142 myCheckPyContainer( false ),
143 myCheckSVContainer( false ),
144 myAttempts( __DEFAULT__ATTEMPTS__ ),
145 myDelay ( __DEFAULT__DELAY__ ),
149 // try to get nb of attempts from environment variable
150 if ( ( cenv = getenv( "CSF_RepeatServerRequest" ) ) && atoi( cenv ) > 0 )
151 myAttempts = atoi( cenv );
152 // try to get delay between attempts from environment variable
153 if ( ( cenv = getenv( "CSF_DelayServerRequest" ) ) && atoi( cenv ) > 0 )
154 myDelay = atoi( cenv );
156 // parse command line check if it is necessary to wait SALOME containers
157 QStringList args = QApplication::arguments();
158 for ( int i = 1; i < args.count(); i++ ) {
159 myCheckCppContainer = myCheckCppContainer || args[i] == "CPP";
160 myCheckPyContainer = myCheckPyContainer || args[i] == "PY";
161 myCheckSVContainer = myCheckSVContainer || args[i] == "SUPERV";
171 Session_ServerCheck::~Session_ServerCheck()
174 while( isRunning() );
178 \brief Get current information message.
179 \return current message
181 QString Session_ServerCheck::currentMessage()
183 static QStringList messages;
184 if ( messages.isEmpty() ) {
185 messages << tr( "Waiting for naming service..." );
186 messages << tr( "Waiting for registry server..." );
187 messages << tr( "Waiting for study server..." );
188 messages << tr( "Waiting for module catalogue server..." );
189 messages << tr( "Waiting for session server..." );
190 messages << tr( "Waiting for C++ container..." );
191 messages << tr( "Waiting for Python container..." );
192 messages << tr( "Waiting for Supervision container..." );
194 QMutexLocker locker( &myDataMutex );
196 int idx = myCurrentStep / myAttempts;
197 if ( idx >= 0 && idx < messages.count() )
198 msg = messages[ idx ];
203 \brief Get error message.
204 \return error message or null string of there was no any error
206 QString Session_ServerCheck::error()
208 QMutexLocker locker( &myDataMutex );
213 \brief Get current step.
216 int Session_ServerCheck::currentStep()
218 QMutexLocker locker( &myDataMutex );
219 return myCurrentStep;
223 \brief Get total number of check steps.
224 \return total number of steps
226 int Session_ServerCheck::totalSteps()
228 QMutexLocker locker( &myDataMutex );
229 int cnt = 5; // base servers
230 if ( myCheckCppContainer ) cnt++; // + C++ container
231 if ( myCheckPyContainer ) cnt++; // + Python container
232 if ( myCheckSVContainer ) cnt++; // + supervision container
233 return cnt * myAttempts;
237 \brief Modify current step.
238 \param step new current step value
240 void Session_ServerCheck::setStep( const int step )
242 QMutexLocker locker( &myDataMutex );
243 myCurrentStep = step;
247 \brief Set error message.
248 \param msg error message
250 void Session_ServerCheck::setError( const QString& msg )
252 QMutexLocker locker( &myDataMutex );
257 \brief Thread loop function. Performs SALOME servers check.
259 void Session_ServerCheck::run()
261 // start check servers
265 QStringList args = QApplication::arguments();
266 int argc = args.size();
267 std::vector<std::string> args1(argc);
268 char** argv = new char*[argc];
269 for ( int i = 0; i < argc; ++i ) {
270 args1[i] = args[i].toStdString();
271 argv[i] = const_cast<char*>( args1[i].c_str() );
276 // 1. Check naming service
277 for ( int i = 0; (i < myAttempts) && OK; i++ ) {
278 Locker locker( this );
280 setStep( current * myAttempts + i );
283 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
284 CORBA::ORB_var orb = init( argc, argv );
285 CORBA::Object_var obj = orb->resolve_initial_references( "NameService" );
286 CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow( obj );
287 if ( !CORBA::is_nil( _root_context ) ) {
288 setStep( ++current * myAttempts );
292 catch( CORBA::COMM_FAILURE& ) {
293 MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" );
296 MESSAGE( "Unknown Exception: unable to contact the naming service" );
299 if ( i == myAttempts-1 ) {
300 setError( tr( "Unable to contact the naming service.\n" ) );
306 // 2. Check registry server
307 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
308 Locker locker( this );
310 setStep( current * myAttempts + i );
313 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
314 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
315 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
317 CORBA::Object_var obj = NS.Resolve( "/Registry" );
318 Registry::Components_var registry = Registry::Components::_narrow( obj );
319 if ( !CORBA::is_nil( registry ) ) {
320 MESSAGE( "/Registry is found" );
322 MESSAGE( "Registry was activated" );
323 setStep( ++current * myAttempts );
327 catch ( ServiceUnreachable& ) {
328 MESSAGE( "Caught exception: Naming Service unreachable." );
329 error = "Naming service unreachable";
331 catch ( CORBA::COMM_FAILURE& ) {
332 MESSAGE( "Caught CORBA::SystemException CommFailure." );
333 error = "Caught CORBA::SystemException CommFailure.";
335 catch ( CORBA::SystemException& ) {
336 MESSAGE( "Caught CORBA::SystemException." );
337 error = "Caught CORBA::SystemException.";
339 catch ( CORBA::Exception& ) {
340 MESSAGE( "Caught CORBA::Exception." );
341 error = "Caught CORBA::Exception.";
344 MESSAGE( "Caught unknown exception." );
345 error = "Caught unknown exception.";
348 if ( i == myAttempts-1 ) {
349 setError( tr( "Registry server is not found.\n%1" ).arg ( error ) );
355 // 3. Check data server
356 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
357 Locker locker( this );
359 setStep( current * myAttempts + i );
362 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
363 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
364 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
366 CORBA::Object_var obj = NS.Resolve( "/myStudyManager" );
367 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj );
368 if ( !CORBA::is_nil( studyManager ) ) {
369 MESSAGE( "/myStudyManager is found" );
370 studyManager->ping();
371 MESSAGE( "StudyManager was activated" );
372 setStep( ++current * myAttempts );
376 catch ( ServiceUnreachable& ) {
377 MESSAGE( "Caught exception: Naming Service unreachable." );
378 error = "Naming service unreachable";
380 catch ( CORBA::COMM_FAILURE& ) {
381 MESSAGE( "Caught CORBA::SystemException CommFailure." );
382 error = "Caught CORBA::SystemException CommFailure.";
384 catch ( CORBA::SystemException& ) {
385 MESSAGE( "Caught CORBA::SystemException." );
386 error = "Caught CORBA::SystemException.";
388 catch ( CORBA::Exception& ) {
389 MESSAGE( "Caught CORBA::Exception." );
390 error = "Caught CORBA::Exception.";
393 MESSAGE( "Caught unknown exception." );
394 error = "Caught unknown exception.";
397 if ( i == myAttempts-1 ) {
398 setError( tr( "Study server is not found.\n%1" ).arg ( error ) );
404 // 4. Check module catalogue server
405 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
406 Locker locker( this );
408 setStep( current * myAttempts + i );
411 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
412 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
413 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
415 CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" );
416 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
417 if ( !CORBA::is_nil( catalog ) ){
418 MESSAGE( "/Kernel/ModulCatalog is found" );
420 MESSAGE( "ModuleCatalog was activated" );
421 setStep( ++current * myAttempts );
425 catch ( ServiceUnreachable& ) {
426 MESSAGE( "Caught exception: Naming Service unreachable." );
427 error = "Naming service unreachable";
429 catch ( CORBA::COMM_FAILURE& ) {
430 MESSAGE( "Caught CORBA::SystemException CommFailure." );
431 error = "Caught CORBA::SystemException CommFailure.";
433 catch ( CORBA::SystemException& ) {
434 MESSAGE( "Caught CORBA::SystemException." );
435 error = "Caught CORBA::SystemException.";
437 catch ( CORBA::Exception& ) {
438 MESSAGE( "Caught CORBA::Exception." );
439 error = "Caught CORBA::Exception.";
442 MESSAGE( "Caught unknown exception." );
443 error = "Caught unknown exception.";
446 if ( i == myAttempts-1 ) {
447 setError( tr( "Module catalogue server is not found.\n%1" ).arg ( error ) );
453 // 5. Check data server
454 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
455 Locker locker( this );
457 setStep( current * myAttempts + i );
460 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
461 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
462 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
464 CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" );
465 SALOME::Session_var session = SALOME::Session::_narrow( obj );
466 if ( !CORBA::is_nil( session ) ) {
467 MESSAGE( "/Kernel/Session is found" );
469 MESSAGE( "SALOME_Session was activated" );
470 setStep( ++current * myAttempts );
474 catch ( ServiceUnreachable& ) {
475 MESSAGE( "Caught exception: Naming Service unreachable." );
476 error = "Naming service unreachable";
478 catch ( CORBA::COMM_FAILURE& ) {
479 MESSAGE( "Caught CORBA::SystemException CommFailure." );
480 error = "Caught CORBA::SystemException CommFailure.";
482 catch ( CORBA::SystemException& ) {
483 MESSAGE( "Caught CORBA::SystemException." );
484 error = "Caught CORBA::SystemException.";
486 catch ( CORBA::Exception& ) {
487 MESSAGE( "Caught CORBA::Exception." );
488 error = "Caught CORBA::Exception.";
491 MESSAGE( "Caught unknown exception." );
492 error = "Caught unknown exception.";
495 if ( i == myAttempts-1 ) {
496 setError( tr( "Session server is not found.\n%1" ).arg ( error ) );
502 // 6. Check C++ container
503 if ( myCheckCppContainer ) {
504 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
505 Locker locker( this );
507 setStep( current * myAttempts + i );
510 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
511 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
512 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
514 QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( Kernel_Utils::GetHostname().c_str() );
515 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
516 Engines::Container_var FScontainer = Engines::Container::_narrow( obj );
517 if ( !CORBA::is_nil( FScontainer ) ) {
518 MESSAGE( containerName.toLatin1().constData() << " is found" );
520 MESSAGE( "FactoryServer container was activated" );
521 setStep( ++current * myAttempts );
525 catch ( ServiceUnreachable& ) {
526 MESSAGE( "Caught exception: Naming Service unreachable." );
527 error = "Naming service unreachable";
529 catch ( CORBA::COMM_FAILURE& ) {
530 MESSAGE( "Caught CORBA::SystemException CommFailure." );
531 error = "Caught CORBA::SystemException CommFailure.";
533 catch ( CORBA::SystemException& ) {
534 MESSAGE( "Caught CORBA::SystemException." );
535 error = "Caught CORBA::SystemException.";
537 catch ( CORBA::Exception& ) {
538 MESSAGE( "Caught CORBA::Exception." );
539 error = "Caught CORBA::Exception.";
542 MESSAGE( "Caught unknown exception." );
543 error = "Caught unknown exception.";
546 if ( i == myAttempts-1 ) {
547 setError( tr( "C++ container is not found.\n%1" ).arg ( error ) );
554 // 7. Check Python container
555 if ( myCheckPyContainer ) {
556 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
557 Locker locker( this );
559 setStep( current * myAttempts + i );
562 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
563 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
564 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
566 QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( Kernel_Utils::GetHostname().c_str() );
567 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
568 Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj );
569 if ( !CORBA::is_nil( FSPcontainer ) ) {
570 MESSAGE( containerName.toLatin1().constData() << " is found" );
571 FSPcontainer->ping();
572 MESSAGE("FactoryServerPy container was activated");
573 setStep( ++current * myAttempts );
577 catch ( ServiceUnreachable& ) {
578 MESSAGE( "Caught exception: Naming Service unreachable." );
579 error = "Naming service unreachable";
581 catch ( CORBA::COMM_FAILURE& ) {
582 MESSAGE( "Caught CORBA::SystemException CommFailure." );
583 error = "Caught CORBA::SystemException CommFailure.";
585 catch ( CORBA::SystemException& ) {
586 MESSAGE( "Caught CORBA::SystemException." );
587 error = "Caught CORBA::SystemException.";
589 catch ( CORBA::Exception& ) {
590 MESSAGE( "Caught CORBA::Exception." );
591 error = "Caught CORBA::Exception.";
594 MESSAGE( "Caught unknown exception." );
595 error = "Caught unknown exception.";
598 if ( i == myAttempts-1 ) {
599 setError( tr( "Python container is not found.\n%1" ).arg ( error ) );
606 // 8. Check supervision container
607 if ( myCheckSVContainer ) {
608 for ( int i = 0; (i < myAttempts) && OK ; i++ ) {
609 Locker locker( this );
611 setStep( current * myAttempts + i );
614 CORBA::ORB_var orb = CORBA::ORB_init( argc, argv );
615 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
616 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
618 QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( Kernel_Utils::GetHostname().c_str() );
619 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
620 Engines::Container_var SVcontainer = Engines::Container::_narrow( obj );
621 if ( !CORBA::is_nil( SVcontainer ) ) {
622 MESSAGE( containerName.toLatin1().constData() << " is found" );
624 MESSAGE("SuperVisionContainer container was activated");
625 setStep( ++current * myAttempts );
629 catch ( ServiceUnreachable& ) {
630 MESSAGE( "Caught exception: Naming Service unreachable." );
631 error = "Naming service unreachable";
633 catch ( CORBA::COMM_FAILURE& ) {
634 MESSAGE( "Caught CORBA::SystemException CommFailure." );
635 error = "Caught CORBA::SystemException CommFailure.";
637 catch ( CORBA::SystemException& ) {
638 MESSAGE( "Caught CORBA::SystemException." );
639 error = "Caught CORBA::SystemException.";
641 catch ( CORBA::Exception& ) {
642 MESSAGE( "Caught CORBA::Exception." );
643 error = "Caught CORBA::Exception.";
646 MESSAGE( "Caught unknown exception." );
647 error = "Caught unknown exception.";
650 if ( i == myAttempts-1 ) {
651 setError( tr( "Supervision container is not found.\n%1" ).arg ( error ) );