X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FLifeCycleCORBA%2FSALOME_LifeCycleCORBA.cxx;h=75bf0dd5ee72f618b6f6560013141cb96770c096;hb=f932433e7396f9be950f617c50c9b15db1a33be1;hp=7908d60aead9ffa91c5c1924cdf0082d586114a3;hpb=89d8cdd476c5f4d65bc3fd1089f092af42e2841c;p=modules%2Fyacs.git diff --git a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx index 7908d60ae..75bf0dd5e 100644 --- a/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx +++ b/src/LifeCycleCORBA/SALOME_LifeCycleCORBA.cxx @@ -1,421 +1,838 @@ -// SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +// SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++ // File : SALOME_LifeCycleCORBA.cxx // Author : Paul RASCLE, EDF // Module : SALOME -// $Header$ #include #include #include #include -#include "OpUtil.hxx" +#include +#ifndef WIN32 + #include + #include +#endif + +#include "Basics_Utils.hxx" #include "utilities.h" #include #include "SALOME_LifeCycleCORBA.hxx" +#include "SALOME_ResourcesManager.hxx" +#include "SALOMESDS_DataServerManager.hxx" + #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include CORBA_CLIENT_HEADER(SALOME_Session) +#include CORBA_CLIENT_HEADER(DSC_Engines) +#include CORBA_CLIENT_HEADER(SALOME_Registry) +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(SALOME_SDS) +#include CORBA_CLIENT_HEADER(Logger) +#include CORBA_CLIENT_HEADER(SALOME_Launcher) + +#include "SALOME_ResourcesManager.hxx" +#include "SALOME_ContainerManager.hxx" +#include "SALOME_Component_i.hxx" #include "SALOME_NamingService.hxx" -using namespace std; +#include "SALOME_FileTransferCORBA.hxx" + +IncompatibleComponent::IncompatibleComponent( void ): + SALOME_Exception( "IncompatibleComponent" ) +{ +} -SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA() +IncompatibleComponent::IncompatibleComponent(const IncompatibleComponent &ex): + SALOME_Exception( ex ) { - _NS = NULL; - _FactoryServer = NULL ; } +/*! \class SALOME_LifeCycleCORBA + \brief A class to manage life cycle of SALOME components. + +*/ + +//============================================================================= +/*! + * Constructor + */ +//============================================================================= + SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns) { - _NS = ns; - _FactoryServer = NULL ; + // be sure to have an instance of traceCollector, when used via SWIG + // in a Python module + int argc = 0; + char *xargv = (char*)""; + char **argv = &xargv; + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + // LocalTraceCollector *myThreadTrace = SALOMETraceCollector::instance(orb); + _NSnew=0; + if (!ns) + { + _NS = new SALOME_NamingService(orb); + _NSnew=_NS; + } + else _NS = ns; + //add try catch + _NS->Change_Directory("/"); // mpv 250105: current directory may be not root + // (in SALOMEDS for an example) + // not enough: set a current directory in naming service is not thread safe + // if naming service instance is shared among several threads... + // ==> allways use absolute path and dot rely on current directory! + + CORBA::Object_var obj = + _NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS); + if (CORBA::is_nil(obj)) + throw SALOME_Exception("Error: Cannot resolve ContainerManager in Naming Service"); + _ContManager=Engines::ContainerManager::_narrow(obj); + + obj = _NS->Resolve(SALOME_ResourcesManager::_ResourcesManagerNameInNS); + if (CORBA::is_nil(obj)) + throw SALOME_Exception("Error: Cannot resolve ResourceManager in Naming Service"); + _ResManager=Engines::ResourcesManager::_narrow(obj); } +//============================================================================= +/*! + * Destructor + */ +//============================================================================= + SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA() { + if(_NSnew)delete _NSnew; } -string SALOME_LifeCycleCORBA::ContainerName( - const char * aComputerContainer , - string * theComputer , - string * theContainer ) { - char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ; - strcpy( ContainerName , aComputerContainer ) ; - string theComputerContainer("/Containers/"); - char * slash = strchr( ContainerName , '/' ) ; - if ( !slash ) { - *theComputer = GetHostname() ; - theComputerContainer += *theComputer ; - theComputerContainer += "/" ; - *theContainer = ContainerName ; - theComputerContainer += *theContainer ; - } - else { - slash[ 0 ] = '\0' ; - slash += 1 ; - *theContainer = slash ; - if ( !strcmp( ContainerName , "localhost" ) ) { - *theComputer = GetHostname() ; +//============================================================================= +/*! \brief Find an already existing and registered component instance. + * + * \param params container parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if not found + */ +//============================================================================= +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::FindComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + Engines::ContainerParameters new_params(params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + new_params.resource_params.can_run_containers = true; + Engines::ResourceList_var listOfResources; + try + { + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); } - else { - *theComputer = ContainerName ; + catch( const SALOME::SALOME_Exception& ex ) + { + return Engines::EngineComponent::_nil(); } - theComputerContainer += *theComputer ; - theComputerContainer += "/" ; - theComputerContainer += *theContainer ; - } - return theComputerContainer ; + + Engines::EngineComponent_var compo = _FindComponent(new_params, + componentName, + studyId, + listOfResources); + + return compo._retn(); } -string SALOME_LifeCycleCORBA::ComputerPath( - const char * theComputer ) { - CORBA::String_var path; - CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); - SALOME_ModuleCatalog::ModuleCatalog_var Catalog = - SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; - try { - path = Catalog->GetPathPrefix( theComputer ); - } - catch (SALOME_ModuleCatalog::NotFound&) { - INFOS("GetPathPrefix(" << theComputer << ") not found!"); - path = "" ; +//============================================================================= +/*! \brief Load a component instance on a container defined by its parameters + * + * \param params container parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::LoadComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + // --- Check if Component Name is known in ModuleCatalog + + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + Engines::ContainerParameters new_params(params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + new_params.resource_params.can_run_containers = true; + + Engines::ResourceList_var listOfResources; + try + { + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); + } + catch( const SALOME::SALOME_Exception& ex ) + { + return Engines::EngineComponent::_nil(); + } + new_params.resource_params.resList = listOfResources; + + Engines::EngineComponent_var compo = _LoadComponent(new_params, + componentName, + studyId); + + return compo._retn(); +} + +//============================================================================= +/*! \brief Find an already existing and registered component instance or load a new + * component instance on a container defined by its parameters. + * + * \param params container parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +FindOrLoad_Component(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + // --- Check if Component Name is known in ModuleCatalog + + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + Engines::ContainerParameters new_params(params); + new_params.resource_params.componentList.length(1); + new_params.resource_params.componentList[0] = componentName; + new_params.resource_params.can_run_containers = true; + + Engines::ResourceList_var listOfResources; + try + { + listOfResources = _ResManager->GetFittingResources(new_params.resource_params); + } + catch( const SALOME::SALOME_Exception& ex ) + { + return Engines::EngineComponent::_nil(); + } + + Engines::EngineComponent_var compo = _FindComponent(new_params, + componentName, + studyId, + listOfResources); + + if(CORBA::is_nil(compo)) + { + new_params.resource_params.resList = listOfResources; + compo = _LoadComponent(new_params, + componentName, + studyId); } - SCRUTE( path ) ; - return CORBA::string_dup( path ) ; + + return compo._retn(); } -Engines::Container_var SALOME_LifeCycleCORBA::FindContainer(const char *containerName ) { - ASSERT(_NS != NULL); - string cont ; - if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ... - string theComputer ; - string theContainer ; - cont = ContainerName( containerName , &theComputer , &theContainer ) ; +//============================================================================= +/*! \brief Find an already existing and registered component instance or load a new + * component instance on a container defined by name + * + * \param containerName the name of container, under one of the forms + * - 1 aContainer (local container) + * - 2 machine/aContainer (container on hostname = machine) + * \param componentName the name of component class + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::FindOrLoad_Component(const char *containerName, + const char *componentName) +{ + MESSAGE("SALOME_LifeCycleCORBA::FindOrLoad_Component INTERACTIF " << containerName << " " << componentName ) ; + + // --- Check if Component Name is known in ModuleCatalog + if (! isKnownComponentClass(componentName)) + return Engines::EngineComponent::_nil(); + + // --- Check if containerName contains machine name (if yes: rg>0) + char *stContainer=strdup(containerName); + std::string st2Container(stContainer); + int rg=st2Container.find("/"); + + Engines::ContainerParameters params; + preSet(params); + if (rg<0) + { + // containerName doesn't contain "/" => Local container + params.container_name = CORBA::string_dup(stContainer); } - else { - cont = containerName ; + else + { + stContainer[rg]='\0'; + params.container_name = CORBA::string_dup(stContainer+rg+1); + params.resource_params.hostname = CORBA::string_dup(stContainer); } - try { + params.isMPI = false; + SCRUTE(params.container_name); + free(stContainer); + return FindOrLoad_Component(params, componentName); +} - SCRUTE( cont ); +//============================================================================= +/*! \brief Check if the component class is known in module catalog + * + * \param componentName the name of component class + * \return true if found, false otherwise + */ +//============================================================================= - CORBA::Object_var obj = _NS->Resolve( cont.c_str() ); - if( !CORBA::is_nil( obj ) ) { - return Engines::Container::_narrow( obj ) ; +bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName) +{ + try + { + CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var Catalog = + SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ; + ASSERT(! CORBA::is_nil(Catalog)); + SALOME_ModuleCatalog::Acomponent_var compoInfo = + Catalog->GetComponent(componentName); + if (CORBA::is_nil (compoInfo)) + { + MESSAGE("Catalog Error: Component not found in the catalog " << componentName); + return false; } + else return true; } - catch (ServiceUnreachable&) { + catch (ServiceUnreachable&) + { INFOS("Caught exception: Naming Service Unreachable"); } - catch (...) { + catch (...) + { INFOS("Caught unknown exception."); } - return Engines::Container::_nil(); + return false; } -Engines::Container_var SALOME_LifeCycleCORBA::FindOrStartContainer( - const string aComputerContainer , - const string theComputer , - const string theContainer ) { - Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ; - Engines::Container_var aFactoryServer ; - SCRUTE( aComputerContainer ) ; - SCRUTE( theComputer ) ; - SCRUTE( theContainer ) ; - bool pyCont = false ; - int len = theContainer.length() ; - if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) { - pyCont = true ; - } - if ( !CORBA::is_nil( aContainer ) ) { - return aContainer ; +//============================================================================= +/*! \brief Initialisation of a given Engines::ResourceParameters with default values. + */ +//============================================================================= + +void +SALOME_LifeCycleCORBA::preSet(Engines::ResourceParameters& params) +{ + params.name = ""; + params.hostname = ""; + params.OS = ""; + params.nb_proc = 0; + params.mem_mb = 0; + params.cpu_clock = 0; + params.nb_node = 0; + params.nb_proc_per_node = 0; + params.policy = ""; + params.can_launch_batch_jobs = false; + params.can_run_containers = false; +} + +//============================================================================= +/*! \brief Initialisation of a given Engines::ContainerParameters with default values. + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::preSet( Engines::ContainerParameters& params) +{ + params.container_name = ""; + params.mode = ""; + params.workingdir = ""; + params.nb_proc = 0; + params.isMPI = false; + params.parallelLib = ""; + SALOME_LifeCycleCORBA::preSet(params.resource_params); +} + +//============================================================================= +/*! + * \return a number of processors not 0, only for MPI containers + */ +//============================================================================= + +int SALOME_LifeCycleCORBA::NbProc(const Engines::ContainerParameters& params) +{ + if( !params.isMPI ) + return 0; + else if( params.nb_proc <= 0 ) + return 1; + else + return params.nb_proc; +} + +//============================================================================= +/*! \brief Get the container manager + * + * \return the container Manager + */ +//============================================================================= + +Engines::ContainerManager_ptr SALOME_LifeCycleCORBA::getContainerManager() +{ + Engines::ContainerManager_var contManager = + Engines::ContainerManager::_duplicate(_ContManager); + return contManager._retn(); +} + +//============================================================================= +/*! \brief Get the resources manager + * + * \return the container Manager + */ +//============================================================================= + +Engines::ResourcesManager_ptr SALOME_LifeCycleCORBA::getResourcesManager() +{ + Engines::ResourcesManager_var resManager = + Engines::ResourcesManager::_duplicate(_ResManager); + return resManager._retn(); +} + +//============================================================================= +/*! \brief shutdown all the SALOME servers except SALOME_Session_Server and omniNames + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::shutdownServers() +{ + // get each Container from NamingService => shutdown it + // (the order is inverse to the order of servers initialization) + + SALOME::Session_var session = SALOME::Session::_nil(); + CORBA::Long pid = 0; + CORBA::Object_var objS = _NS->Resolve("/Kernel/Session"); + if (!CORBA::is_nil(objS)) + { + session = SALOME::Session::_narrow(objS); + if (!CORBA::is_nil(session)) + { + pid = session->getPID(); + session->Shutdown(); + } } - else { - string FactoryServer = theComputer ; - if ( pyCont ) { - FactoryServer += "/FactoryServerPy" ; + + std::string hostname = Kernel_Utils::GetHostname(); + + // 1) ConnectionManager + try + { + CORBA::Object_var objCnM=_NS->Resolve("/ConnectionManager"); + Engines::ConnectionManager_var connMan=Engines::ConnectionManager::_narrow(objCnM); + if ( !CORBA::is_nil(connMan) && ( pid != connMan->getPID() ) ) + connMan->ShutdownWithExit(); } - else { - FactoryServer += "/FactoryServer" ; + catch(const CORBA::Exception& e) + { + // ignore and continue } - aFactoryServer = FindContainer( FactoryServer.c_str() ) ; - if ( CORBA::is_nil( aFactoryServer ) ) { -// rsh -n ikkyo /export/home/rahuel/SALOME_ROOT/bin/runSession SALOME_Container -ORBInitRef NameService=corbaname::dm2s0017:1515 & - string rsh( "" ) ; - if ( theComputer!= GetHostname() ) { - rsh += "rsh -n " ; - rsh += theComputer ; - rsh += " " ; - } - string path = ComputerPath( theComputer.c_str() ) ; - SCRUTE( path ) ; - if ( path[0] != '\0' ) { - rsh += path ; - rsh += "/../bin/" ; - } - rsh += "runSession " ; - if ( pyCont ) { - rsh += "SALOME_ContainerPy.py " ; - rsh += "FactoryServerPy -" ; - } - else { - rsh += "SALOME_Container " ; - rsh += "FactoryServer -" ; - } - string omniORBcfg( getenv( "OMNIORB_CONFIG" ) ) ; - ifstream omniORBfile( omniORBcfg.c_str() ) ; - char ORBInitRef[12] ; - char nameservice[132] ; - omniORBfile >> ORBInitRef ; - rsh += ORBInitRef ; - rsh += " " ; - omniORBfile >> nameservice ; - omniORBfile.close() ; - char * bsn = strchr( nameservice , '\n' ) ; - if ( bsn ) { - bsn[ 0 ] = '\0' ; - } - rsh += nameservice ; - if ( pyCont ) { - rsh += " > /tmp/FactoryServerPy_" ; - } - else { - rsh += " > /tmp/FactoryServer_" ; - } - rsh += theComputer ; - rsh += ".log 2>&1 &" ; - SCRUTE( rsh ); - int status = system( rsh.c_str() ) ; - if (status == -1) { - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status -1)") ; - } - else if (status == 217) { - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed (system command status 217)") ; - } - else { - int count = 21 ; - while ( CORBA::is_nil( aFactoryServer ) && count ) { - sleep( 1 ) ; - count-- ; - if ( count != 10 ) - MESSAGE( count << ". Waiting for FactoryServer on " << theComputer) - aFactoryServer = FindContainer( FactoryServer.c_str() ) ; - } - if ( CORBA::is_nil( aFactoryServer ) ) { - MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ; - } - else if ( strcmp( theComputer.c_str() , GetHostname().c_str() ) ) { - _FactoryServer = aFactoryServer ; - } - } + + timespec ts_req; + ts_req.tv_nsec=100000000; + ts_req.tv_sec=0; + +//Wait some time so that ConnectionManager be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 2) SALOMEDS + try + { + CORBA::Object_var objSDS = _NS->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(objSDS) ; + if ( !CORBA::is_nil(studyManager) && ( pid != studyManager->getPID() ) ) + studyManager->Shutdown(); } - if ( !CORBA::is_nil( aFactoryServer ) ) { - if ( strcmp( theContainer.c_str() , "FactoryServer" ) || - strcmp( theContainer.c_str() , "FactoryServerPy" ) ) { - MESSAGE("Container not found ! trying to start " << aComputerContainer); - Engines::Container_var myContainer = aFactoryServer->start_impl( theContainer.c_str() ) ; - if ( !CORBA::is_nil( myContainer ) ) { - MESSAGE("Container " << aComputerContainer << " started"); - return myContainer ; - } - else { - MESSAGE("Container " << aComputerContainer << " NOT started"); - } - } - else { - MESSAGE("Container " << aComputerContainer << " started"); - return aFactoryServer ; - } + catch(const CORBA::Exception& e) + { + // ignore and continue } - } - return Engines::Container::_nil(); -} -Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component - (const char *containerName, - const char *componentName, - const char *implementation) -{ - BEGIN_OF("FindOrLoad_Component(1)"); - ASSERT(_NS != NULL); - string theComputer ; - string theContainer ; - string theComputerContainer = ContainerName( containerName , - &theComputer , - &theContainer ) ; - Engines::Container_var cont = FindOrStartContainer( theComputerContainer , - theComputer , - theContainer ) ; -// ASSERT(!CORBA::is_nil(cont)); - - string path( theComputerContainer ); - path = path + "/"; - path = path + componentName; - SCRUTE(path); +//Wait some time so that study be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 3) ModuleCatalog try { - CORBA::Object_var obj = _NS->Resolve(path.c_str()); - if (CORBA::is_nil(obj)) - { - MESSAGE("Component not found ! trying to load " << path); - Engines::Component_var compo - = cont->load_impl(componentName, implementation); -// ASSERT(!CORBA::is_nil(compo)); - MESSAGE("Component launched !" << path); - return compo; - } - else - { - MESSAGE("Component found !" << path); - Engines::Component_var compo = Engines::Component::_narrow(obj); -// ASSERT(!CORBA::is_nil(compo)); - try - { - compo->ping(); - } - catch (CORBA::COMM_FAILURE&) - { - INFOS("Caught CORBA::SystemException CommFailure. Engine " - << path << "does not respond" ); - } - return compo; - } + CORBA::Object_var objMC=_NS->Resolve("/Kernel/ModulCatalog"); + SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objMC); + if ( !CORBA::is_nil(catalog) && ( pid != catalog->getPID() ) ) + catalog->shutdown(); } - catch (ServiceUnreachable&) + catch(const CORBA::Exception& e) { - INFOS("Caught exception: Naming Service Unreachable"); + // ignore and continue } - catch (...) + +//Wait some time so that ModulCatalog be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + // 4 ) Remote ScopeServer (the DataServer is hosted by SalomeLauncher shutdown right after) + try + { + CORBA::Object_var objDSM(_NS->Resolve(SALOMESDS::DataServerManager::NAME_IN_NS)); + SALOME::DataServerManager_var dsm(SALOME::DataServerManager::_narrow(objDSM)); + if ( !CORBA::is_nil(dsm) ) + dsm->shutdownScopes(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + + // 5) SalomeLauncher + try { - INFOS("Caught unknown exception."); + CORBA::Object_var objSL = _NS->Resolve("/SalomeLauncher"); + Engines::SalomeLauncher_var launcher = Engines::SalomeLauncher::_narrow(objSL); + if (!CORBA::is_nil(launcher) && (pid != launcher->getPID())) + launcher->Shutdown(); } - return Engines::Component::_nil(); + catch(const CORBA::Exception& e) + { + // ignore and continue + } + +//Wait some time so that launcher be completely shutdown +#ifndef WIN32 + nanosleep(&ts_req,0); +#endif + + // 6) Registry + try + { + CORBA::Object_var objR = _NS->Resolve("/Registry"); + Registry::Components_var registry = Registry::Components::_narrow(objR); + if ( !CORBA::is_nil(registry) && ( pid != registry->getPID() ) ) + registry->Shutdown(); + } + catch(const CORBA::Exception& e) + { + // ignore and continue + } + + // 7) Logger + int argc = 0; + char *xargv = (char*)""; + char **argv = &xargv; + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); + + CORBA::Object_var objLog = CORBA::Object::_nil(); + CosNaming::NamingContext_var inc; + CORBA::Object_var theObj = CORBA::Object::_nil(); + std::string stdname = "Logger"; + CosNaming::Name name; + name.length(1); + name[0].id = CORBA::string_dup(stdname.c_str()); + try + { + if(!CORBA::is_nil(orb)) + theObj = orb->resolve_initial_references("NameService"); + if (!CORBA::is_nil(theObj)) + inc = CosNaming::NamingContext::_narrow(theObj); + } + catch(...) + { + } + if(!CORBA::is_nil(inc)) + { + try + { + objLog = inc->resolve(name); + SALOME_Logger::Logger_var logger = SALOME_Logger::Logger::_narrow(objLog); + if ( !CORBA::is_nil(logger) ) + logger->shutdown(); + } + catch(...) + { + } + } +} + +//============================================================================= +/*! \brief shutdown omniNames + */ +//============================================================================= + +void SALOME_LifeCycleCORBA::killOmniNames() +{ + std::string portNumber (::getenv ("NSPORT") ); + std::string python_exe; + + python_exe = std::string("python"); + + if ( !portNumber.empty() ) + { + std::string cmd; + + cmd = std::string("from salome_utils import killOmniNames; "); + cmd += std::string("killOmniNames(") + portNumber + "); "; + cmd = python_exe + std::string(" -c \"") + cmd +"\""; + MESSAGE(cmd); + system( cmd.c_str() ); + + cmd = std::string("from killSalomeWithPort import cleanApplication; "); + cmd += std::string("cleanApplication(") + portNumber + "); "; + cmd = python_exe + std::string(" -c \"") + cmd +"\""; + MESSAGE(cmd); + system( cmd.c_str() ); + } + + // shutdown portmanager + if ( !portNumber.empty() ) + { + std::string cmd; + + cmd = std::string("from PortManager import releasePort; "); + cmd += std::string("releasePort(") + portNumber + "); "; + cmd = python_exe + std::string(" -c \"") + cmd +"\""; + MESSAGE(cmd); + system( cmd.c_str() ); + } } -Engines::Component_var SALOME_LifeCycleCORBA::FindOrLoad_Component - (const char *containerName, - const char *componentName) +//============================================================================= +/*! \brief Find an already existing and registered component instance. + * + * - build a list of machines on which an instance of the component is running, + * - find the best machine among the list + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \param listOfMachines list of machine address + * \return a CORBA reference of the component instance, or _nil if not found + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +_FindComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId, + const Engines::ResourceList& listOfResources) { -// BEGIN_OF("FindOrLoad_Component(2)"); - ASSERT(_NS != NULL); - string theComputer ; - string theContainer ; - string theComputerContainer = ContainerName( containerName , - &theComputer , - &theContainer ) ; - Engines::Container_var cont = FindOrStartContainer( theComputerContainer , - theComputer , - theContainer ) ; - - if ( CORBA::is_nil( cont ) ) { - MESSAGE("Container not found ! " << theComputerContainer ); - return Engines::Component::_nil(); + // --- build the list of machines on which the component is already running + const char *containerName = params.container_name; + int nbproc = NbProc(params); + + Engines::ResourceList_var resourcesOK = new Engines::ResourceList; + + unsigned int lghtOfresourcesOK = 0; + resourcesOK->length(listOfResources.length()); + + for(unsigned int i=0; i < listOfResources.length(); i++) + { + const char * currentResource = listOfResources[i]; + Engines::ResourceDefinition_var resource_definition = + _ResManager->GetResourceDefinition(currentResource); + CORBA::Object_var obj = _NS->ResolveComponent(resource_definition->hostname.in(), + containerName, + componentName, + nbproc); + if (!CORBA::is_nil(obj)) + resourcesOK[lghtOfresourcesOK++] = CORBA::string_dup(currentResource); } -// char * machine = cont->machineName() ; - const char * machine = theComputer.c_str() ; - - string path( theComputerContainer ); - path += "/"; - path += componentName; - SCRUTE(path); - - try { - CORBA::Object_var obj = _NS->Resolve(path.c_str()); - if ( CORBA::is_nil( obj ) ) { - MESSAGE("Component not found ! trying to load " << path); - CORBA::Object_var obj2 = _NS->Resolve("/Kernel/ModulCatalog"); - SALOME_ModuleCatalog::ModuleCatalog_var Catalog = - SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj2); - - SALOME_ModuleCatalog::Acomponent_ptr compoInfo = - Catalog->GetComponent(componentName); - if (CORBA::is_nil (compoInfo)) - { - INFOS("Catalog Error : Component not found in the catalog") - return Engines::Component::_nil(); -// exit (-1); - } - - string path; - try - { - path = compoInfo->GetPathPrefix( machine ) ; - path += "/" ; - } - catch (SALOME_ModuleCatalog::NotFound&) - { - INFOS("GetPathPrefix(" << machine << ") not found!" - << "trying localhost"); - try { - path = compoInfo->GetPathPrefix("localhost") ; - path += "/" ; - } - catch (SALOME_ModuleCatalog::NotFound&) { - INFOS("GetPathPrefix(localhost) not found!") ; - path = "" ; - } - } - - SCRUTE(path); - string implementation(path); - implementation += "lib"; - implementation += componentName; - implementation += "Engine.so"; - - Engines::Component_var compo - = cont->load_impl(componentName, implementation.c_str()); - -// ASSERT(!CORBA::is_nil(compo)); -// MESSAGE("Component launched !" << path); - return compo; - } - else - { - MESSAGE("Component found !" << path); - Engines::Component_var compo = Engines::Component::_narrow(obj); -// ASSERT(!CORBA::is_nil(compo)); - try - { - string instanceName = compo->instanceName(); - } - catch (CORBA::COMM_FAILURE&) - { - INFOS("Caught CORBA::SystemException CommFailure. Engine " - << path << "does not respond" ); - } - return compo; - } - } - catch (ServiceUnreachable&) + // --- find the best machine among the list + if(lghtOfresourcesOK != 0) + { + resourcesOK->length(lghtOfresourcesOK); + CORBA::String_var bestResource = _ResManager->FindFirst(resourcesOK); + Engines::ResourceDefinition_var resource_definition = + _ResManager->GetResourceDefinition(bestResource); + CORBA::Object_var obj = _NS->ResolveComponent(resource_definition->hostname.in(), + containerName, + componentName, + nbproc); + return Engines::EngineComponent::_narrow(obj); + } + else + return Engines::EngineComponent::_nil(); +} + +//============================================================================= +/*! \brief Load a component instance. + * + * - Finds a container in the list of machine or start one. + * - Try to load the component library in the container, + * - then create an instance of the component. + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the component instance, or _nil if problem + */ +//============================================================================= + +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA:: +_LoadComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + MESSAGE("_LoadComponent, required " << params.container_name << + " " << componentName << " " << NbProc(params)); + + Engines::ContainerParameters local_params(params); + local_params.mode = CORBA::string_dup("findorstart"); + Engines::Container_var cont = _ContManager->GiveContainer(local_params); + if (CORBA::is_nil(cont)) return Engines::EngineComponent::_nil(); + + char* reason; + bool isLoadable = cont->load_component_Library(componentName,reason); + if (!isLoadable) { - INFOS("Caught exception: Naming Service Unreachable"); + //std::cerr << reason << std::endl; + CORBA::string_free(reason); + return Engines::EngineComponent::_nil(); } - catch (...) + CORBA::string_free(reason); + + Engines::EngineComponent_var myInstance = + cont->create_component_instance(componentName, studyId); + return myInstance._retn(); +} + +//============================================================================= +/*! \brief Load a parallel component instance. + * + * \param params machine parameters like type or name... + * \param componentName the name of component class + * \param studyId default = 0 : multistudy instance + * \return a CORBA reference of the parallel component instance, or _nil if problem + */ +//============================================================================= +Engines::EngineComponent_ptr +SALOME_LifeCycleCORBA::Load_ParallelComponent(const Engines::ContainerParameters& params, + const char *componentName, + int studyId) +{ + MESSAGE("Entering LoadParallelComponent"); + +/*MESSAGE("Parameters : "); + MESSAGE("Container name : " << params.container_name); + MESSAGE("Number of component nodes : " << params.nb_component_nodes); + MESSAGE("Component Name : " << componentName);*/ + + Engines::ContainerParameters parms(params); + parms.resource_params.componentList.length(1); + parms.resource_params.componentList[0] = componentName; + parms.mode = CORBA::string_dup("findorstart"); + + MESSAGE("Starting Parallel Container"); + Engines::Container_var cont = _ContManager->GiveContainer(parms); + if (CORBA::is_nil(cont)) { + INFOS("FindOrStartParallelContainer() returns a NULL container !"); + return Engines::EngineComponent::_nil(); + } + + MESSAGE("Loading component library"); + char* reason; + bool isLoadable = cont->load_component_Library(componentName,reason); + if (!isLoadable) { + INFOS(componentName <<" library is not loadable !"); + //std::cerr << reason << std::endl; + CORBA::string_free(reason); + return Engines::EngineComponent::_nil(); + } + CORBA::string_free(reason); + + MESSAGE("Creating component instance"); + // @PARALLEL@ permits to identify that the component requested + // is a parallel component. + std::string name = std::string(componentName); + Engines::EngineComponent_var myInstance = cont->create_component_instance(name.c_str(), studyId); + if (CORBA::is_nil(myInstance)) + INFOS("create_component_instance returns a NULL component !"); + return myInstance._retn(); +} + +/*! \brief copy a file from a source host to a destination host + * \param hostSrc the source host + * \param fileSrc the file to copy from the source host to the destination host + * \param hostDest the destination host + * \param fileDest the destination file + */ +void SALOME_LifeCycleCORBA::copyFile(const char* hostSrc, const char* fileSrc, const char* hostDest, const char* fileDest) +{ + if(strcmp(hostDest,"localhost") == 0) { - INFOS("Caught unknown exception."); + //if localhost use a shortcut + SALOME_FileTransferCORBA transfer(hostSrc,fileSrc); + transfer.getLocalFile(fileDest); + return; } - return Engines::Component::_nil(); + + Engines::ContainerManager_var contManager = getContainerManager(); + + Engines::ContainerParameters params; + preSet(params); + + params.resource_params.hostname = hostDest; + params.mode = CORBA::string_dup("findorstart"); + Engines::Container_var containerDest = contManager->GiveContainer(params); + + params.resource_params.hostname = hostSrc; + Engines::Container_var containerSrc = contManager->GiveContainer(params); + + containerDest->copyFile(containerSrc,fileSrc,fileDest); +} + +/*! \brief get the naming service used by the life cycle + * + * \return the naming service + */ +SALOME_NamingService * SALOME_LifeCycleCORBA::namingService() +{ + return _NS; +} + +/*! \brief get the orb used by the life cycle + * + * \return the orb + */ +CORBA::ORB_ptr SALOME_LifeCycleCORBA::orb() +{ + return _NS->orb(); }