1 // Copyright (C) 2007-2019 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 QString errfmt = "\n%1";
298 // 2. Check registry server
299 for ( int i = 0; i < myAttempts ; i++ ) {
300 Locker locker( this );
302 setStep( current * myAttempts + i );
305 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
306 CORBA::ORB_var orb = init( args.argc(), args.argv() );
307 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
308 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
310 CORBA::Object_var obj = NS.Resolve( "/Registry" );
311 Registry::Components_var registry = Registry::Components::_narrow( obj );
312 if ( !CORBA::is_nil( registry ) ) {
313 MESSAGE( "/Registry is found" );
315 MESSAGE( "Registry was activated" );
316 setStep( ++current * myAttempts );
320 catch ( ServiceUnreachable& ) {
321 MESSAGE( "Caught exception: Naming Service unreachable." );
322 error = "Naming service unreachable";
324 catch ( CORBA::COMM_FAILURE& ) {
325 MESSAGE( "Caught CORBA::SystemException CommFailure." );
326 error = "Caught CORBA::SystemException CommFailure.";
328 catch ( CORBA::SystemException& ) {
329 MESSAGE( "Caught CORBA::SystemException." );
330 error = "Caught CORBA::SystemException.";
332 catch ( CORBA::Exception& ) {
333 MESSAGE( "Caught CORBA::Exception." );
334 error = "Caught CORBA::Exception.";
337 MESSAGE( "Caught unknown exception." );
338 error = "Caught unknown exception.";
341 if ( i == myAttempts-1 ) {
342 setError( tr( "Registry server is not found." ) + errfmt.arg( error ) );
347 // 3. Check data server
348 for ( int i = 0; i < myAttempts ; i++ ) {
349 Locker locker( this );
351 setStep( current * myAttempts + i );
354 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
355 CORBA::ORB_var orb = init( args.argc(), args.argv() );
356 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
357 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
359 CORBA::Object_var obj = NS.Resolve( "/Study" );
360 SALOMEDS::Study_var study = SALOMEDS::Study::_narrow( obj );
361 if ( !CORBA::is_nil( study ) ) {
362 MESSAGE( "/Study is found" );
364 MESSAGE( "Study was activated" );
365 setStep( ++current * myAttempts );
369 catch ( ServiceUnreachable& ) {
370 MESSAGE( "Caught exception: Naming Service unreachable." );
371 error = "Naming service unreachable";
373 catch ( CORBA::COMM_FAILURE& ) {
374 MESSAGE( "Caught CORBA::SystemException CommFailure." );
375 error = "Caught CORBA::SystemException CommFailure.";
377 catch ( CORBA::SystemException& ) {
378 MESSAGE( "Caught CORBA::SystemException." );
379 error = "Caught CORBA::SystemException.";
381 catch ( CORBA::Exception& ) {
382 MESSAGE( "Caught CORBA::Exception." );
383 error = "Caught CORBA::Exception.";
386 MESSAGE( "Caught unknown exception." );
387 error = "Caught unknown exception.";
390 if ( i == myAttempts-1 ) {
391 setError( tr( "Study server is not found." ) + errfmt.arg( error ) );
396 // 4. Check module catalogue server
397 for ( int i = 0; i < myAttempts ; i++ ) {
398 Locker locker( this );
400 setStep( current * myAttempts + i );
403 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
404 CORBA::ORB_var orb = init( args.argc(), args.argv() );
405 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
406 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
408 CORBA::Object_var obj = NS.Resolve( "/Kernel/ModulCatalog" );
409 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
410 if ( !CORBA::is_nil( catalog ) ){
411 MESSAGE( "/Kernel/ModulCatalog is found" );
413 MESSAGE( "ModuleCatalog was activated" );
414 setStep( ++current * myAttempts );
418 catch ( ServiceUnreachable& ) {
419 MESSAGE( "Caught exception: Naming Service unreachable." );
420 error = "Naming service unreachable";
422 catch ( CORBA::COMM_FAILURE& ) {
423 MESSAGE( "Caught CORBA::SystemException CommFailure." );
424 error = "Caught CORBA::SystemException CommFailure.";
426 catch ( CORBA::SystemException& ) {
427 MESSAGE( "Caught CORBA::SystemException." );
428 error = "Caught CORBA::SystemException.";
430 catch ( CORBA::Exception& ) {
431 MESSAGE( "Caught CORBA::Exception." );
432 error = "Caught CORBA::Exception.";
435 MESSAGE( "Caught unknown exception." );
436 error = "Caught unknown exception.";
439 if ( i == myAttempts-1 ) {
440 setError( tr( "Module catalogue server is not found." ) + errfmt.arg( error ) );
445 // 5. Check data server
446 for ( int i = 0; i < myAttempts ; i++ ) {
447 Locker locker( this );
449 setStep( current * myAttempts + i );
452 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
453 CORBA::ORB_var orb = init( args.argc(), args.argv() );
454 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
455 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
457 CORBA::Object_var obj = NS.Resolve( "/Kernel/Session" );
458 SALOME::Session_var session = SALOME::Session::_narrow( obj );
459 if ( !CORBA::is_nil( session ) ) {
460 MESSAGE( "/Kernel/Session is found" );
462 MESSAGE( "SALOME_Session was activated" );
463 setStep( ++current * myAttempts );
467 catch ( ServiceUnreachable& ) {
468 MESSAGE( "Caught exception: Naming Service unreachable." );
469 error = "Naming service unreachable";
471 catch ( CORBA::COMM_FAILURE& ) {
472 MESSAGE( "Caught CORBA::SystemException CommFailure." );
473 error = "Caught CORBA::SystemException CommFailure.";
475 catch ( CORBA::SystemException& ) {
476 MESSAGE( "Caught CORBA::SystemException." );
477 error = "Caught CORBA::SystemException.";
479 catch ( CORBA::Exception& ) {
480 MESSAGE( "Caught CORBA::Exception." );
481 error = "Caught CORBA::Exception.";
484 MESSAGE( "Caught unknown exception." );
485 error = "Caught unknown exception.";
488 if ( i == myAttempts-1 ) {
489 setError( tr( "Session server is not found." ) + errfmt.arg( error ) );
494 // 6. Check C++ container
495 if ( myCheckCppContainer ) {
496 for ( int i = 0; i < myAttempts ; i++ ) {
497 Locker locker( this );
499 setStep( current * myAttempts + i );
502 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
503 CORBA::ORB_var orb = init( args.argc(), args.argv() );
504 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
505 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
507 QString containerName = QString( "/Containers/%1/FactoryServer" ).arg( Kernel_Utils::GetHostname().c_str() );
508 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
509 Engines::Container_var FScontainer = Engines::Container::_narrow( obj );
510 if ( !CORBA::is_nil( FScontainer ) ) {
511 MESSAGE( containerName.toLatin1().constData() << " is found" );
513 MESSAGE( "FactoryServer container was activated" );
514 setStep( ++current * myAttempts );
518 catch ( ServiceUnreachable& ) {
519 MESSAGE( "Caught exception: Naming Service unreachable." );
520 error = "Naming service unreachable";
522 catch ( CORBA::COMM_FAILURE& ) {
523 MESSAGE( "Caught CORBA::SystemException CommFailure." );
524 error = "Caught CORBA::SystemException CommFailure.";
526 catch ( CORBA::SystemException& ) {
527 MESSAGE( "Caught CORBA::SystemException." );
528 error = "Caught CORBA::SystemException.";
530 catch ( CORBA::Exception& ) {
531 MESSAGE( "Caught CORBA::Exception." );
532 error = "Caught CORBA::Exception.";
535 MESSAGE( "Caught unknown exception." );
536 error = "Caught unknown exception.";
539 if ( i == myAttempts-1 ) {
540 setError( tr( "C++ container is not found." ) + errfmt.arg( error ) );
546 // 7. Check Python container
547 if ( myCheckPyContainer ) {
548 for ( int i = 0; i < myAttempts ; i++ ) {
549 Locker locker( this );
551 setStep( current * myAttempts + i );
554 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
555 CORBA::ORB_var orb = init( args.argc(), args.argv() );
556 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
557 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
559 QString containerName = QString( "/Containers/%1/FactoryServerPy" ).arg( Kernel_Utils::GetHostname().c_str() );
560 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
561 Engines::Container_var FSPcontainer = Engines::Container::_narrow( obj );
562 if ( !CORBA::is_nil( FSPcontainer ) ) {
563 MESSAGE( containerName.toLatin1().constData() << " is found" );
564 FSPcontainer->ping();
565 MESSAGE("FactoryServerPy container was activated");
566 setStep( ++current * myAttempts );
570 catch ( ServiceUnreachable& ) {
571 MESSAGE( "Caught exception: Naming Service unreachable." );
572 error = "Naming service unreachable";
574 catch ( CORBA::COMM_FAILURE& ) {
575 MESSAGE( "Caught CORBA::SystemException CommFailure." );
576 error = "Caught CORBA::SystemException CommFailure.";
578 catch ( CORBA::SystemException& ) {
579 MESSAGE( "Caught CORBA::SystemException." );
580 error = "Caught CORBA::SystemException.";
582 catch ( CORBA::Exception& ) {
583 MESSAGE( "Caught CORBA::Exception." );
584 error = "Caught CORBA::Exception.";
587 MESSAGE( "Caught unknown exception." );
588 error = "Caught unknown exception.";
591 if ( i == myAttempts-1 ) {
592 setError( tr( "Python container is not found." ) + errfmt.arg( error ) );
598 // 8. Check supervision container
599 if ( myCheckSVContainer ) {
600 for ( int i = 0; i < myAttempts ; i++ ) {
601 Locker locker( this );
603 setStep( current * myAttempts + i );
606 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
607 CORBA::ORB_var orb = init( args.argc(), args.argv() );
608 SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance();
609 ASSERT( SINGLETON_<SALOME_NamingService>::IsAlreadyExisting() );
611 QString containerName = QString( "/Containers/%1/SuperVisionContainer" ).arg( Kernel_Utils::GetHostname().c_str() );
612 CORBA::Object_var obj = NS.Resolve( containerName.toLatin1() );
613 Engines::Container_var SVcontainer = Engines::Container::_narrow( obj );
614 if ( !CORBA::is_nil( SVcontainer ) ) {
615 MESSAGE( containerName.toLatin1().constData() << " is found" );
617 MESSAGE("SuperVisionContainer container was activated");
618 setStep( ++current * myAttempts );
622 catch ( ServiceUnreachable& ) {
623 MESSAGE( "Caught exception: Naming Service unreachable." );
624 error = "Naming service unreachable";
626 catch ( CORBA::COMM_FAILURE& ) {
627 MESSAGE( "Caught CORBA::SystemException CommFailure." );
628 error = "Caught CORBA::SystemException CommFailure.";
630 catch ( CORBA::SystemException& ) {
631 MESSAGE( "Caught CORBA::SystemException." );
632 error = "Caught CORBA::SystemException.";
634 catch ( CORBA::Exception& ) {
635 MESSAGE( "Caught CORBA::Exception." );
636 error = "Caught CORBA::Exception.";
639 MESSAGE( "Caught unknown exception." );
640 error = "Caught unknown exception.";
643 if ( i == myAttempts-1 ) {
644 setError( tr( "Supervision container is not found." ) + errfmt.arg( error ) );