Salome HOME
d846594ab4f36f81bd135c075a4973128059ff54
[modules/kernel.git] / src / LifeCycleCORBA / SALOME_LifeCycleCORBA.cxx
1 //  SALOME LifeCycleCORBA : implementation of containers and engines life cycle both in Python and C++
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOME_LifeCycleCORBA.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SALOME
27 //  $Header$
28
29 #include <iostream>
30 #include <fstream>
31 #include <sstream>
32 #include <iomanip>
33
34 #include "OpUtil.hxx"
35 #include "utilities.h"
36
37 #include <ServiceUnreachable.hxx>
38
39 #include "SALOME_LifeCycleCORBA.hxx"
40 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
41 #include "SALOME_ContainerManager.hxx"
42 #include "SALOME_Component_i.hxx"
43 #include "SALOME_NamingService.hxx"
44 using namespace std;
45
46 SALOME_LifeCycleCORBA::SALOME_LifeCycleCORBA(SALOME_NamingService *ns)
47 {
48   _NS = ns;
49   //add try catch
50   CORBA::Object_var obj=_NS->Resolve(SALOME_ContainerManager::_ContainerManagerNameInNS);
51   ASSERT( !CORBA::is_nil(obj));
52   _ContManager=Engines::ContainerManager::_narrow(obj);
53 }
54
55 SALOME_LifeCycleCORBA::~SALOME_LifeCycleCORBA()
56 {
57 }
58
59 string SALOME_LifeCycleCORBA::ContainerName(
60                                          const char * aComputerContainer ,
61                                          string * theComputer ,
62                                          string * theContainer ) {
63   char * ContainerName = new char [ strlen( aComputerContainer ) + 1 ] ;
64   strcpy( ContainerName , aComputerContainer ) ;
65   string theComputerContainer("/Containers/");
66   char * slash = strchr( ContainerName , '/' ) ;
67   if ( !slash ) {
68     *theComputer = GetHostname() ;
69     theComputerContainer += *theComputer ;
70     theComputerContainer += "/" ;
71     *theContainer = ContainerName ;
72     theComputerContainer += *theContainer ;
73   }
74   else {
75     slash[ 0 ] = '\0' ;
76     slash += 1 ;
77     *theContainer = slash ;
78     if ( !strcmp( ContainerName , "localhost" ) ) {
79       *theComputer = GetHostname() ;
80     }
81     else {
82       *theComputer = ContainerName ;
83     }
84     theComputerContainer += *theComputer ;
85     theComputerContainer += "/" ;
86     theComputerContainer += *theContainer ;
87   }
88   delete [] ContainerName;
89   return theComputerContainer ;
90 }
91
92 bool SALOME_LifeCycleCORBA::isKnownComponentClass(const char *componentName)
93 {
94
95   try
96     {
97       CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
98       SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
99         SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
100       SALOME_ModuleCatalog::Acomponent_ptr compoInfo = 
101         Catalog->GetComponent(componentName);
102       if (CORBA::is_nil (compoInfo)) 
103         {
104           INFOS("Catalog Error : Component not found in the catalog");
105           return false;
106         }
107       else return true;
108     }
109   catch (ServiceUnreachable&)
110     {
111       INFOS("Caught exception: Naming Service Unreachable");
112     }
113   catch (...)
114     {
115       INFOS("Caught unknown exception.");
116     }
117   return false;
118 }
119
120 string SALOME_LifeCycleCORBA::ComputerPath(
121                                          const char * theComputer ) {
122   CORBA::String_var path;
123   CORBA::Object_var obj = _NS->Resolve("/Kernel/ModulCatalog");
124   SALOME_ModuleCatalog::ModuleCatalog_var Catalog = 
125                      SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
126   try {
127     path = Catalog->GetPathPrefix( theComputer );
128   }
129   catch (SALOME_ModuleCatalog::NotFound&) {
130     INFOS("GetPathPrefix(" << theComputer << ") not found!");
131     path = "" ;
132   }
133   SCRUTE( path ) ;
134   return CORBA::string_dup( path ) ;
135 }
136
137 Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component
138                                   (const char *containerName,
139                                    const char *componentName)
140 {
141   if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
142   char *stContainer=strdup(containerName);
143   string st2Container(stContainer);
144   int rg=st2Container.find("/");
145   if(rg<0) {
146     //containerName doesn't contain "/" => Local container
147     free(stContainer);
148     Engines::MachineList_var listOfMachine=new Engines::MachineList;
149     listOfMachine->length(1);
150     listOfMachine[0]=CORBA::string_dup(GetHostname().c_str());
151     Engines::Component_ptr ret=FindComponent(containerName,componentName,listOfMachine.in());
152     if(CORBA::is_nil(ret))
153       return LoadComponent(containerName,componentName,listOfMachine);
154     else
155       return ret;
156   }
157   else {
158     //containerName contains "/" => Remote container
159     stContainer[rg]='\0';
160     Engines::MachineParameters_var params=new Engines::MachineParameters;
161     params->container_name=CORBA::string_dup(stContainer+rg+1);
162     params->hostname=CORBA::string_dup(stContainer);
163     params->OS=CORBA::string_dup("LINUX");
164     free(stContainer);
165     return FindOrLoad_Component(params,componentName);
166   }
167 }
168
169 Engines::Component_ptr SALOME_LifeCycleCORBA::FindOrLoad_Component(const Engines::MachineParameters& params,
170                                                                    const char *componentName)
171 {
172   if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
173   Engines::MachineList_var listOfMachine=_ContManager->GetFittingResources(params,componentName);
174   Engines::Component_ptr ret=FindComponent(params.container_name,componentName,listOfMachine);
175   if(CORBA::is_nil(ret))
176     return LoadComponent(params.container_name,componentName,listOfMachine);
177   else
178     return ret;
179 }
180
181 Engines::Component_ptr SALOME_LifeCycleCORBA::FindComponent(const char *containerName,
182                                                                  const char *componentName,
183                                                                  const Engines::MachineList& listOfMachines)
184 {
185   if (! isKnownComponentClass(componentName)) return Engines::Component::_nil();
186   if(containerName[0]!='\0')
187     {
188       Engines::MachineList_var machinesOK=new Engines::MachineList;
189       unsigned int lghtOfmachinesOK=0;
190       machinesOK->length(listOfMachines.length());
191       for(unsigned int i=0;i<listOfMachines.length();i++)
192         {
193           const char *currentMachine=listOfMachines[i];
194           string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,currentMachine);
195           CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str());
196           if(!CORBA::is_nil(obj))
197             {
198               machinesOK[lghtOfmachinesOK++]=CORBA::string_dup(currentMachine);
199             }
200         }
201       if(lghtOfmachinesOK!=0)
202         {
203           machinesOK->length(lghtOfmachinesOK);
204           CORBA::String_var bestMachine=_ContManager->FindBest(machinesOK);
205           string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine);
206           CORBA::Object_var obj=_NS->Resolve(componentNameForNS.c_str());
207           return Engines::Component::_narrow(obj);
208         }
209       else
210         return Engines::Component::_nil();
211     }
212   else
213     {
214       //user specified no container name so trying to find a component in the best machine among listOfMachines
215       CORBA::String_var bestMachine=_ContManager->FindBest(listOfMachines);
216       //Normally look at all containers launched on bestMachine to see if componentName is already launched on one of them. To do..
217       string componentNameForNS=Engines_Component_i::BuildComponentNameForNS(componentName,containerName,bestMachine);
218       CORBA::Object_var obj = _NS->Resolve(componentNameForNS.c_str());
219       return Engines::Component::_narrow(obj);
220     }
221 }
222
223 Engines::Component_ptr SALOME_LifeCycleCORBA::LoadComponent(const char *containerName, const char *componentName, const Engines::MachineList& listOfMachines)
224 {
225   Engines::Container_var cont=_ContManager->FindOrStartContainer(containerName,listOfMachines);
226   string implementation=Engines_Component_i::GetDynLibraryName(componentName);
227   return cont->load_impl(componentName, implementation.c_str());
228 }