1 // Copyright (C) 2007-2016 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"
42 #include <QApplication>
43 #include <QWaitCondition>
44 #include <QMutexLocker>
45 #include <QStringList>
52 \brief Default number of attemtps to check SALOME server.
54 This value can be changed by setting the CSF_RepeatServerRequest
55 environment variable. For example, to set number of check attempts
56 for each server to 1000:
58 setenv CSF_RepeatServerRequest 1000
61 const int __DEFAULT__ATTEMPTS__ = 300;
64 \brief Default delay between attempts (in microseconds).
66 This value can be changed by setting the CSF_DelayServerRequest
67 environment variable. For example, to set delay between attemtps
68 to check SALOME servers to 100000 (0.1 second):
70 setenv CSF_DelayServerRequest 100000
73 const int __DEFAULT__DELAY__ = 50000;
75 // The exception being thrown out of a destructor,
76 // that is not allowed by default in C++11.
78 #if __cplusplus >= 201103L
79 # define TYPE_NOEXCEPT noexcept(false)
81 # define TYPE_NOEXCEPT
85 \classSession_ServerCheck::Locker
86 \brief Automatic locker/unlocker.
90 class Session_ServerCheck::Locker
94 \brief Constructor. Tries to aquire lock.
96 Locker( Session_ServerCheck* sc )
99 myChecker->myMutex->lock();
100 myChecker->myMutex->unlock();
103 \brief Destructor. Wakes the calling thread and goes sleeping.
105 ~Locker() TYPE_NOEXCEPT
107 myChecker->myWC->wakeAll();
108 myChecker->usleep( myChecker->myDelay );
111 Session_ServerCheck* myChecker;
115 \class Session_ServerCheck
116 \brief The class Session_ServerCheck is used to check SALOME
117 servers availability.
119 It runs in the secondrary thread. The number of attemts to check
120 each SALOME server and the time delay between checks can be specified
121 via setting the CSF_RepeatServerRequest and CSF_DelayServerRequest
122 environment variables.
124 Total number of the check attempts can be retrieved via totalSteps()
125 method and current check step can be retrieved via currentStep() method.
127 The method currentMessage() can be used to get the information message
128 about what SALOME server is currently checked. If any error occured (some
129 server could not be found) the thread loop is stopped and error status
130 is set. Error message can be retrieved with the error() method.
135 \param mutex a mutex used to serialize progress operations (splash)
136 \param wc a wait condition used in combination with \a mutex
138 Session_ServerCheck::Session_ServerCheck( QMutex* mutex, QWaitCondition* wc )
142 myCheckCppContainer( false ),
143 myCheckPyContainer( false ),
144 myCheckSVContainer( false ),
145 myAttempts( __DEFAULT__ATTEMPTS__ ),
146 myDelay ( __DEFAULT__DELAY__ ),
150 // try to get nb of attempts from environment variable
151 if ( ( cenv = getenv( "CSF_RepeatServerRequest" ) ) && atoi( cenv ) > 0 )
152 myAttempts = atoi( cenv );
153 // try to get delay between attempts from environment variable
154 if ( ( cenv = getenv( "CSF_DelayServerRequest" ) ) && atoi( cenv ) > 0 )
155 myDelay = atoi( cenv );
157 // parse command line check if it is necessary to wait SALOME containers
158 QStringList args = QApplication::arguments();
159 for ( int i = 1; i < args.count(); i++ ) {
160 myCheckCppContainer = myCheckCppContainer || args[i] == "CPP";
161 myCheckPyContainer = myCheckPyContainer || args[i] == "PY";
162 myCheckSVContainer = myCheckSVContainer || args[i] == "SUPERV";
172 Session_ServerCheck::~Session_ServerCheck()
175 while( isRunning() );
179 \brief Get current information message.
180 \return current message
182 QString Session_ServerCheck::currentMessage()
184 static QStringList messages;
185 if ( messages.isEmpty() ) {
186 messages << tr( "Waiting for naming service..." );
187 messages << tr( "Waiting for registry server..." );
188 messages << tr( "Waiting for study server..." );
189 messages << tr( "Waiting for module catalogue server..." );
190 messages << tr( "Waiting for session server..." );
191 messages << tr( "Waiting for C++ container..." );
192 messages << tr( "Waiting for Python container..." );
193 messages << tr( "Waiting for Supervision container..." );
195 QMutexLocker locker( &myDataMutex );
197 int idx = myCurrentStep / myAttempts;
198 if ( idx >= 0 && idx < messages.count() )
199 msg = messages[ idx ];
204 \brief Get error message.
205 \return error message or null string of there was no any error
207 QString Session_ServerCheck::error()
209 QMutexLocker locker( &myDataMutex );
214 \brief Get current step.
217 int Session_ServerCheck::currentStep()
219 QMutexLocker locker( &myDataMutex );
220 return myCurrentStep;
224 \brief Get total number of check steps.
225 \return total number of steps
227 int Session_ServerCheck::totalSteps()
229 QMutexLocker locker( &myDataMutex );
230 int cnt = 5; // base servers
231 if ( myCheckCppContainer ) cnt++; // + C++ container
232 if ( myCheckPyContainer ) cnt++; // + Python container
233 if ( myCheckSVContainer ) cnt++; // + supervision container
234 return cnt * myAttempts;
238 \brief Modify current step.
239 \param step new current step value
241 void Session_ServerCheck::setStep( const int step )
243 QMutexLocker locker( &myDataMutex );
244 myCurrentStep = step;
248 \brief Set error message.
249 \param msg error message
251 void Session_ServerCheck::setError( const QString& msg )
253 QMutexLocker locker( &myDataMutex );
258 \brief Thread loop function. Performs SALOME servers check.
260 void Session_ServerCheck::run()
262 // start check servers
265 Qtx::CmdLineArgs args;
267 // 1. Check naming service
268 for ( int i = 0; i < myAttempts; i++ ) {
269 Locker locker( this );
271 setStep( current * myAttempts + i );
274 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
275 CORBA::ORB_var orb = init( args.argc(), args.argv() );
276 CORBA::Object_var obj = orb->resolve_initial_references( "NameService" );
277 CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow( obj );
278 if ( !CORBA::is_nil( _root_context ) ) {
279 setStep( ++current * myAttempts );
283 catch( CORBA::COMM_FAILURE& ) {
284 MESSAGE( "CORBA::COMM_FAILURE: unable to contact the naming service" );
287 MESSAGE( "Unknown Exception: unable to contact the naming service" );
290 if ( i == myAttempts-1 ) {
291 setError( tr( "Unable to contact the naming service.\n" ) );
296 // 2. Check registry server
297 for ( int i = 0; i < myAttempts ; i++ ) {
298 Locker locker( this );
300 setStep( current * myAttempts + i );
303 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
304 CORBA::ORB_var orb = init( args.argc(), args.argv() );
305 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
306 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
308 CORBA::Object_var obj = NS.Resolve( "/Registry" );
309 Registry::Components_var registry = Registry::Components::_narrow( obj );
310 if ( !CORBA::is_nil( registry ) ) {
311 MESSAGE( "/Registry is found" );
313 MESSAGE( "Registry was activated" );
314 setStep( ++current * myAttempts );
318 catch ( ServiceUnreachable& ) {
319 MESSAGE( "Caught exception: Naming Service unreachable." );
320 error = "Naming service unreachable";
322 catch ( CORBA::COMM_FAILURE& ) {
323 MESSAGE( "Caught CORBA::SystemException CommFailure." );
324 error = "Caught CORBA::SystemException CommFailure.";
326 catch ( CORBA::SystemException& ) {
327 MESSAGE( "Caught CORBA::SystemException." );
328 error = "Caught CORBA::SystemException.";
330 catch ( CORBA::Exception& ) {
331 MESSAGE( "Caught CORBA::Exception." );
332 error = "Caught CORBA::Exception.";
335 MESSAGE( "Caught unknown exception." );
336 error = "Caught unknown exception.";
339 if ( i == myAttempts-1 ) {
340 setError( tr( "Registry server is not found.\n%1" ).arg ( error ) );
345 // 3. Check data server
346 for ( int i = 0; i < myAttempts ; i++ ) {
347 Locker locker( this );
349 setStep( current * myAttempts + i );
352 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
353 CORBA::ORB_var orb = init( args.argc(), args.argv() );
354 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
355 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
357 CORBA::Object_var obj = NS.Resolve( "/myStudyManager" );
358 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow( obj );
359 if ( !CORBA::is_nil( studyManager ) ) {
360 MESSAGE( "/myStudyManager is found" );
361 studyManager->ping();
362 MESSAGE( "StudyManager was activated" );
363 setStep( ++current * myAttempts );
367 catch ( ServiceUnreachable& ) {
368 MESSAGE( "Caught exception: Naming Service unreachable." );
369 error = "Naming service unreachable";
371 catch ( CORBA::COMM_FAILURE& ) {
372 MESSAGE( "Caught CORBA::SystemException CommFailure." );
373 error = "Caught CORBA::SystemException CommFailure.";
375 catch ( CORBA::SystemException& ) {
376 MESSAGE( "Caught CORBA::SystemException." );
377 error = "Caught CORBA::SystemException.";
379 catch ( CORBA::Exception& ) {
380 MESSAGE( "Caught CORBA::Exception." );
381 error = "Caught CORBA::Exception.";
384 MESSAGE( "Caught unknown exception." );
385 error = "Caught unknown exception.";
388 if ( i == myAttempts-1 ) {
389 setError( tr( "Study server is not found.\n%1" ).arg ( error ) );
394 // 4. Check module catalogue server
395 for ( int i = 0; i < myAttempts ; i++ ) {
396 Locker locker( this );
398 setStep( current * myAttempts + i );
401 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
402 CORBA::ORB_var orb = init( args.argc(), args.argv() );
403 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
404 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
406 CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" );
407 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
408 if ( !CORBA::is_nil( catalog ) ){
409 MESSAGE( "/Kernel/ModulCatalog is found" );
411 MESSAGE( "ModuleCatalog was activated" );
412 setStep( ++current * myAttempts );
416 catch ( ServiceUnreachable& ) {
417 MESSAGE( "Caught exception: Naming Service unreachable." );
418 error = "Naming service unreachable";
420 catch ( CORBA::COMM_FAILURE& ) {
421 MESSAGE( "Caught CORBA::SystemException CommFailure." );
422 error = "Caught CORBA::SystemException CommFailure.";
424 catch ( CORBA::SystemException& ) {
425 MESSAGE( "Caught CORBA::SystemException." );
426 error = "Caught CORBA::SystemException.";
428 catch ( CORBA::Exception& ) {
429 MESSAGE( "Caught CORBA::Exception." );
430 error = "Caught CORBA::Exception.";
433 MESSAGE( "Caught unknown exception." );
434 error = "Caught unknown exception.";
437 if ( i == myAttempts-1 ) {
438 setError( tr( "Module catalogue server is not found.\n%1" ).arg ( error ) );
443 // 5. Check data server
444 for ( int i = 0; i < myAttempts ; i++ ) {
445 Locker locker( this );
447 setStep( current * myAttempts + i );
450 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
451 CORBA::ORB_var orb = init( args.argc(), args.argv() );
452 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
453 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
455 CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" );
456 SALOME::Session_var session = SALOME::Session::_narrow( obj );
457 if ( !CORBA::is_nil( session ) ) {
458 MESSAGE( "/Kernel/Session is found" );
460 MESSAGE( "SALOME_Session was activated" );
461 setStep( ++current * myAttempts );
465 catch ( ServiceUnreachable& ) {
466 MESSAGE( "Caught exception: Naming Service unreachable." );
467 error = "Naming service unreachable";
469 catch ( CORBA::COMM_FAILURE& ) {
470 MESSAGE( "Caught CORBA::SystemException CommFailure." );
471 error = "Caught CORBA::SystemException CommFailure.";
473 catch ( CORBA::SystemException& ) {
474 MESSAGE( "Caught CORBA::SystemException." );
475 error = "Caught CORBA::SystemException.";
477 catch ( CORBA::Exception& ) {
478 MESSAGE( "Caught CORBA::Exception." );
479 error = "Caught CORBA::Exception.";
482 MESSAGE( "Caught unknown exception." );
483 error = "Caught unknown exception.";
486 if ( i == myAttempts-1 ) {
487 setError( tr( "Session server is not found.\n%1" ).arg ( error ) );
492 // 6. Check C++ container
493 if ( myCheckCppContainer ) {
494 for ( int i = 0; i < myAttempts ; i++ ) {
495 Locker locker( this );
497 setStep( current * myAttempts + i );
500 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
501 CORBA::ORB_var orb = init( args.argc(), args.argv() );
502 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
503 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
505 QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( Kernel_Utils::GetHostname().c_str() );
506 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
507 Engines::Container_var FScontainer = Engines::Container::_narrow( obj );
508 if ( !CORBA::is_nil( FScontainer ) ) {
509 MESSAGE( containerName.toLatin1().constData() << " is found" );
511 MESSAGE( "FactoryServer container was activated" );
512 setStep( ++current * myAttempts );
516 catch ( ServiceUnreachable& ) {
517 MESSAGE( "Caught exception: Naming Service unreachable." );
518 error = "Naming service unreachable";
520 catch ( CORBA::COMM_FAILURE& ) {
521 MESSAGE( "Caught CORBA::SystemException CommFailure." );
522 error = "Caught CORBA::SystemException CommFailure.";
524 catch ( CORBA::SystemException& ) {
525 MESSAGE( "Caught CORBA::SystemException." );
526 error = "Caught CORBA::SystemException.";
528 catch ( CORBA::Exception& ) {
529 MESSAGE( "Caught CORBA::Exception." );
530 error = "Caught CORBA::Exception.";
533 MESSAGE( "Caught unknown exception." );
534 error = "Caught unknown exception.";
537 if ( i == myAttempts-1 ) {
538 setError( tr( "C++ container is not found.\n%1" ).arg ( error ) );
544 // 7. Check Python container
545 if ( myCheckPyContainer ) {
546 for ( int i = 0; i < myAttempts ; i++ ) {
547 Locker locker( this );
549 setStep( current * myAttempts + i );
552 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
553 CORBA::ORB_var orb = init( args.argc(), args.argv() );
554 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
555 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
557 QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( Kernel_Utils::GetHostname().c_str() );
558 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
559 Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj );
560 if ( !CORBA::is_nil( FSPcontainer ) ) {
561 MESSAGE( containerName.toLatin1().constData() << " is found" );
562 FSPcontainer->ping();
563 MESSAGE("FactoryServerPy container was activated");
564 setStep( ++current * myAttempts );
568 catch ( ServiceUnreachable& ) {
569 MESSAGE( "Caught exception: Naming Service unreachable." );
570 error = "Naming service unreachable";
572 catch ( CORBA::COMM_FAILURE& ) {
573 MESSAGE( "Caught CORBA::SystemException CommFailure." );
574 error = "Caught CORBA::SystemException CommFailure.";
576 catch ( CORBA::SystemException& ) {
577 MESSAGE( "Caught CORBA::SystemException." );
578 error = "Caught CORBA::SystemException.";
580 catch ( CORBA::Exception& ) {
581 MESSAGE( "Caught CORBA::Exception." );
582 error = "Caught CORBA::Exception.";
585 MESSAGE( "Caught unknown exception." );
586 error = "Caught unknown exception.";
589 if ( i == myAttempts-1 ) {
590 setError( tr( "Python container is not found.\n%1" ).arg ( error ) );
596 // 8. Check supervision container
597 if ( myCheckSVContainer ) {
598 for ( int i = 0; i < myAttempts ; i++ ) {
599 Locker locker( this );
601 setStep( current * myAttempts + i );
604 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
605 CORBA::ORB_var orb = init( args.argc(), args.argv() );
606 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
607 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
609 QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( Kernel_Utils::GetHostname().c_str() );
610 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
611 Engines::Container_var SVcontainer = Engines::Container::_narrow( obj );
612 if ( !CORBA::is_nil( SVcontainer ) ) {
613 MESSAGE( containerName.toLatin1().constData() << " is found" );
615 MESSAGE("SuperVisionContainer container was activated");
616 setStep( ++current * myAttempts );
620 catch ( ServiceUnreachable& ) {
621 MESSAGE( "Caught exception: Naming Service unreachable." );
622 error = "Naming service unreachable";
624 catch ( CORBA::COMM_FAILURE& ) {
625 MESSAGE( "Caught CORBA::SystemException CommFailure." );
626 error = "Caught CORBA::SystemException CommFailure.";
628 catch ( CORBA::SystemException& ) {
629 MESSAGE( "Caught CORBA::SystemException." );
630 error = "Caught CORBA::SystemException.";
632 catch ( CORBA::Exception& ) {
633 MESSAGE( "Caught CORBA::Exception." );
634 error = "Caught CORBA::Exception.";
637 MESSAGE( "Caught unknown exception." );
638 error = "Caught unknown exception.";
641 if ( i == myAttempts-1 ) {
642 setError( tr( "Supervision container is not found.\n%1" ).arg ( error ) );