1 // SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++
3 // Copyright (C) 2003 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.
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SALOME_LifeCycleCORBA.cxx
25 // Author : Paul RASCLE, EDF
35 #include "utilities.h"
36 #include "Launchers.hxx"
38 #include <ServiceUnreachable.hxx>
40 #include "SALOME_LifeCycleCORBA.hxx"
41 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
42 #include "SALOME_ContainerManager.hxx"
43 #include "SALOME_Component_i.hxx"
44 #include "SALOME_NamingService.hxx"
47 SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns)
51 _NS->Change_Directory("/"); // mpv 250105: current directory may be not root (in SALOMEDS for an example)
52 CORBA::Object_var obj=_NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
53 ASSERT( !CORBA::is_nil(obj));
54 _ContManager=Engines::ContainerManager::_narrow(obj);
57 SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA()
61 string SALOME_LifeCycleCORBA::ContainerName(
62 const char * aComputerContainer ,
63 string * theComputer ,
64 string * theContainer ) {
65 char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ;
66 strcpy( ContainerName , aComputerContainer ) ;
67 string theComputerContainer("/Containers/");
68 char * slash = strchr( ContainerName , '/' ) ;
70 *theComputer = GetHostname() ;
71 theComputerContainer += *theComputer ;
72 theComputerContainer += "/" ;
73 *theContainer = ContainerName ;
74 theComputerContainer += *theContainer ;
79 *theContainer = slash ;
80 if ( !strcmp( ContainerName , "localhost" ) ) {
81 *theComputer = GetHostname() ;
84 *theComputer = ContainerName ;
86 theComputerContainer += *theComputer ;
87 theComputerContainer += "/" ;
88 theComputerContainer += *theContainer ;
90 delete [] ContainerName;
91 return theComputerContainer ;
94 bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName)
99 CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
100 SALOME_ModuleCatalog::ModuleCatalog_var Catalog =
101 SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
102 SALOME_ModuleCatalog::Acomponent_ptr compoInfo =
103 Catalog->GetComponent(componentName);
104 if (CORBA::is_nil (compoInfo))
106 INFOS("Catalog Error : Component not found in the catalog");
111 catch (ServiceUnreachable&)
113 INFOS("Caught exception: Naming Service Unreachable");
117 INFOS("Caught unknown exception.");
122 string SALOME_LifeCycleCORBA::ComputerPath(
123 const char * theComputer ) {
124 CORBA::String_var path;
125 CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
126 SALOME_ModuleCatalog::ModuleCatalog_var Catalog =
127 SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
129 path = Catalog->GetPathPrefix( theComputer );
131 catch (SALOME_ModuleCatalog::NotFound&) {
132 INFOS("GetPathPrefix(" << theComputer << ") not found!");
136 return CORBA::string_dup( path ) ;
139 Engines::Container_ptr SALOME_LifeCycleCORBA::FindContainer(const char *containerName)
143 if ( strncmp( containerName , "/Containers/" , 12 ) ) { // Compatibility ...
145 string theContainer ;
146 cont = ContainerName( containerName , &theComputer , &theContainer ) ;
149 cont = containerName ;
155 CORBA::Object_var obj = _NS->Resolve( cont.c_str() );
156 if( !CORBA::is_nil( obj ) ) {
157 return Engines::Container::_narrow( obj ) ;
160 catch (ServiceUnreachable&) {
161 INFOS("Caught exception: Naming Service Unreachable");
164 INFOS("Caught unknown exception.");
166 return Engines::Container::_nil();
169 Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component
170 (const char *containerName,
171 const char *componentName)
173 if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
174 char *stContainer=strdup(containerName);
175 string st2Container(stContainer);
176 int rg=st2Container.find("/");
179 stContainer[rg]='\0';
180 if(strcmp(stContainer,"localhost")==0)
182 Engines::Component_ptr ret=FindOrLoad_Component(stContainer+rg+1,componentName);
188 //containerName doesn't contain "/" => Local container
190 Engines::MachineList_var listOfMachine=new Engines::MachineList;
191 listOfMachine->length(1);
192 listOfMachine[0]=CORBA::string_dup(GetHostname().c_str());
193 Engines::Component_ptr ret=FindComponent(containerName,componentName,listOfMachine.in());
194 if(CORBA::is_nil(ret))
195 return LoadComponent(containerName,componentName,listOfMachine);
200 //containerName contains "/" => Remote container
201 stContainer[rg]='\0';
202 Engines::MachineParameters_var params=new Engines::MachineParameters;
203 params->container_name=CORBA::string_dup(stContainer+rg+1);
204 params->hostname=CORBA::string_dup(stContainer);
205 params->OS=CORBA::string_dup("LINUX");
207 return FindOrLoad_Component(params,componentName);
211 Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component(const Engines::MachineParameters& params,
212 const char *componentName)
214 if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
215 Engines::MachineList_var listOfMachine=_ContManager->GetFittingResources(params,componentName);
216 Engines::Component_ptr ret=FindComponent(params.container_name,componentName,listOfMachine);
217 if(CORBA::is_nil(ret))
218 return LoadComponent(params.container_name,componentName,listOfMachine);
223 Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containerName,
224 const char *componentName,
225 const Engines::MachineList& listOfMachines)
227 if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
228 if(containerName[0]!='\0')
230 Engines::MachineList_var machinesOK=new Engines::MachineList;
231 unsigned int lghtOfmachinesOK=0;
232 machinesOK->length(listOfMachines.length());
233 for(unsigned int i=0;i<listOfMachines.length();i++)
235 const char *currentMachine=listOfMachines[i];
236 string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,currentMachine);
237 CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str());
238 if(!CORBA::is_nil(obj))
240 machinesOK[lghtOfmachinesOK++]=CORBA::string_dup(currentMachine);
243 if(lghtOfmachinesOK!=0)
245 machinesOK->length(lghtOfmachinesOK);
246 CORBA::String_var bestMachine=_ContManager->FindBest(machinesOK);
247 string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine);
248 CORBA::Object_var obj=_NS->Resolve(componentNameForNS.c_str());
249 return Engines::Component::_narrow(obj);
252 return Engines::Component::_nil();
256 //user specified no container name so trying to find a component in the best machine among listOfMachines
257 CORBA::String_var bestMachine=_ContManager->FindBest(listOfMachines);
258 //Normally look at all containers launched on bestMachine to see if componentName is already launched on one of them. To do..
259 string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine);
260 CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str());
261 return Engines::Component::_narrow(obj);
265 Engines::Component_ptr SALOME_LifeCycleCORBA::LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines)
267 Engines::Container_var cont=_ContManager->FindOrStartContainer(containerName,listOfMachines);
268 string implementation=Engines_Component_i::GetDynLibraryName(componentName);
269 return cont->load_impl(componentName, implementation.c_str());
273 Engines::Container_ptr SALOME_LifeCycleCORBA::FindOrStartContainer(
274 const string aComputerContainer ,
275 const string theComputer ,
276 const string theContainer ) {
277 SCRUTE( aComputerContainer ) ;
278 SCRUTE( theComputer ) ;
279 SCRUTE( theContainer ) ;
281 Engines::Container_var aContainer = FindContainer( aComputerContainer.c_str() ) ;
283 if ( !CORBA::is_nil( aContainer ) ) {
287 Engines::Container_var aFactoryServer ;
289 bool pyCont = false ;
290 int len = theContainer.length() ;
291 if ( !strcmp( &theContainer.c_str()[len-2] , "Py" ) ) {
295 string addr=_NS->getIORaddr();
296 string CMD="SALOME_Container";
298 CMD="SALOME_ContainerPy.py";
300 CMD=CMD + " " + theContainer;
301 CMD=CMD + " -ORBInitRef NameService="+addr;
304 * Get the appropriate launcher and ask to launch
306 PyObject * launcher=getLauncher((char *)theComputer.c_str());
307 Launcher_Slaunch(launcher,(char *)theComputer.c_str(),(char *)CMD.c_str());
309 * Wait until the container is registered in Naming Service
312 while ( CORBA::is_nil( aFactoryServer ) && count ) {
316 MESSAGE( count << ". Waiting for FactoryServer on " << theComputer)
317 aFactoryServer = FindContainer( aComputerContainer.c_str() ) ;
319 if ( !CORBA::is_nil( aFactoryServer ) ) {
320 return aFactoryServer;
322 MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed") ;
323 return Engines::Container::_nil();