Salome HOME
b7a3c708e1c68133adde04f27734be07ee527cf7
[modules/kernel.git] / src / Container / SALOME_ContainerManager.cxx
1 #include "SALOME_ContainerManager.hxx"
2 #include "SALOME_NamingService.hxx"
3 #include "OpUtil.hxx"
4 #include <sys/types.h>
5 #ifndef WNT
6 #include <unistd.h>
7 #endif
8 #include <vector>
9 #include "Utils_CorbaException.hxx"
10
11 #define TIME_OUT_TO_LAUNCH_CONT 21
12
13 using namespace std;
14
15 const char *SALOME_ContainerManager::_ContainerManagerNameInNS = 
16   "/ContainerManager";
17
18 //=============================================================================
19 /*! 
20  *  Constructor
21  *  \param orb
22  *  Define a CORBA single thread policy for the server, which avoid to deal
23  *  with non thread-safe usage like Change_Directory in SALOME naming service
24  */
25 //=============================================================================
26
27 SALOME_ContainerManager::SALOME_ContainerManager(CORBA::ORB_ptr orb)
28 {
29   MESSAGE("constructor");
30   _NS = new SALOME_NamingService(orb);
31   _ResManager = new SALOME_ResourcesManager(orb);
32   PortableServer::POA_var root_poa = PortableServer::POA::_the_root_poa();
33   PortableServer::POAManager_var pman = root_poa->the_POAManager();
34   PortableServer::POA_var my_poa;
35
36   CORBA::PolicyList policies;
37   policies.length(1);
38   PortableServer::ThreadPolicy_var threadPol = 
39     root_poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL);
40   policies[0] = PortableServer::ThreadPolicy::_duplicate(threadPol);
41
42   my_poa = 
43     root_poa->create_POA("SThreadPOA",pman,policies);
44   threadPol->destroy();
45   PortableServer::ObjectId_var id = my_poa->activate_object(this);
46   CORBA::Object_var obj = my_poa->id_to_reference(id);
47   Engines::ContainerManager_var refContMan =
48     Engines::ContainerManager::_narrow(obj);
49
50   _NS->Register(refContMan,_ContainerManagerNameInNS);
51   MESSAGE("constructor end");
52 }
53
54 //=============================================================================
55 /*! 
56  * destructor
57  */
58 //=============================================================================
59
60 SALOME_ContainerManager::~SALOME_ContainerManager()
61 {
62   MESSAGE("destructor");
63   delete _NS;
64   delete _ResManager;
65 }
66
67 //=============================================================================
68 /*! CORBA method:
69  *  shutdown all the containers, then the ContainerManager servant
70  */
71 //=============================================================================
72
73 void SALOME_ContainerManager::Shutdown()
74 {
75   MESSAGE("Shutdown");
76   ShutdownContainers();
77   PortableServer::ObjectId_var oid = _default_POA()->servant_to_id(this);
78   _default_POA()->deactivate_object(oid);
79   _remove_ref();
80   
81 }
82
83 //=============================================================================
84 /*! CORBA Method:
85  *  Loop on all the containers listed in naming service, ask shutdown on each
86  */
87 //=============================================================================
88
89 void SALOME_ContainerManager::ShutdownContainers()
90 {
91   MESSAGE("ShutdownContainers");
92   _NS->Change_Directory("/Containers");
93   vector<string> vec = _NS->list_directory_recurs();
94   for(vector<string>::iterator iter = vec.begin();iter!=vec.end();iter++)
95     {
96       SCRUTE((*iter));
97       CORBA::Object_var obj=_NS->Resolve((*iter).c_str());
98       Engines::Container_var cont=Engines::Container::_narrow(obj);
99       if(!CORBA::is_nil(cont))
100         {
101           MESSAGE("ShutdownContainers: " << (*iter));
102           cont->Shutdown();
103         }
104       else MESSAGE("ShutdownContainers: no container ref for " << (*iter));
105     }
106 }
107
108 //=============================================================================
109 /*! CORBA Method:
110  *  Find a suitable Container in a list of machines, or start one
111  *  \param params            Machine Parameters required for the container
112  *  \param possibleComputers list of machines usable for find or start
113  */
114 //=============================================================================
115
116 Engines::Container_ptr
117 SALOME_ContainerManager::
118 FindOrStartContainer(const Engines::MachineParameters& params,
119                      const Engines::MachineList& possibleComputers)
120 {
121   Engines::Container_ptr ret = FindContainer(params,possibleComputers);
122   if(!CORBA::is_nil(ret))
123     return ret;
124   MESSAGE("Container doesn't exist try to launch it ...");
125   MESSAGE("SALOME_ContainerManager::FindOrStartContainer " <<
126           possibleComputers.length());
127   //vector<string> vector;
128   string theMachine=_ResManager->FindBest(possibleComputers);
129   MESSAGE("try to launch it on " << theMachine);
130
131   string command;
132   if(theMachine=="")
133     {
134       MESSAGE("SALOME_ContainerManager::FindOrStartContainer : " <<
135               "no possible computer");
136       return Engines::Container::_nil();
137     }
138   else if(theMachine==GetHostname())
139     {
140       command=_ResManager->BuildCommandToLaunchLocalContainer(params);
141     }
142   else
143     command =
144       _ResManager->BuildCommandToLaunchRemoteContainer(theMachine,params);
145
146   _ResManager->RmTmpFile();
147   int status=system(command.c_str());
148   if (status == -1)
149     {
150       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed " <<
151               "(system command status -1)");
152       return Engines::Container::_nil();
153     }
154   else if (status == 217)
155     {
156       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed " <<
157               "(system command status 217)");
158       return Engines::Container::_nil();
159     }
160   else
161     {
162       int count=TIME_OUT_TO_LAUNCH_CONT;
163       while ( CORBA::is_nil(ret) && count )
164         {
165 #ifndef WNT
166           sleep( 1 ) ;
167 #else
168           Sleep(1000);
169 #endif
170           count-- ;
171           if ( count != 10 )
172             MESSAGE( count << ". Waiting for FactoryServer on " << theMachine);
173           string containerNameInNS =
174             _NS->BuildContainerNameForNS(params,theMachine.c_str());
175           SCRUTE(containerNameInNS);
176           CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
177           ret=Engines::Container::_narrow(obj);
178         }
179       if ( CORBA::is_nil(ret) )
180         {
181           MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed");
182         }
183       return ret;
184     }
185 }
186
187 //=============================================================================
188 /*! 
189  * 
190  */
191 //=============================================================================
192
193 Engines::MachineList *
194 SALOME_ContainerManager::
195 GetFittingResources(const Engines::MachineParameters& params,
196                     const char *componentName)
197 {
198   MESSAGE("SALOME_ContainerManager::GetFittingResources");
199   Engines::MachineList *ret=new Engines::MachineList;
200   vector<string> vec;
201   try
202     {
203       vec = _ResManager->GetFittingResources(params,componentName);
204     }
205   catch(const SALOME_Exception &ex)
206     {
207       INFOS("Caught exception.");
208       THROW_SALOME_CORBA_EXCEPTION(ex.what(),SALOME::BAD_PARAM);
209       //return ret;
210     }
211
212   MESSAGE("Machine list length "<<vec.size());
213   ret->length(vec.size());
214   for(unsigned int i=0;i<vec.size();i++)
215     {
216       (*ret)[i]=(vec[i]).c_str();
217     }
218   return ret;
219 }
220
221 //=============================================================================
222 /*! 
223  * 
224  */
225 //=============================================================================
226
227 char*
228 SALOME_ContainerManager::
229 FindBest(const Engines::MachineList& possibleComputers)
230 {
231   string theMachine=_ResManager->FindBest(possibleComputers);
232   return CORBA::string_dup(theMachine.c_str());
233 }
234
235 //=============================================================================
236 /*! 
237  * 
238  */
239 //=============================================================================
240
241 Engines::Container_ptr
242 SALOME_ContainerManager::
243 FindContainer(const Engines::MachineParameters& params,
244               const char *theMachine)
245 {
246   string containerNameInNS(_NS->BuildContainerNameForNS(params,theMachine));
247   CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
248   if( !CORBA::is_nil(obj) )
249     return Engines::Container::_narrow(obj);
250   else
251     return Engines::Container::_nil();
252 }
253
254 //=============================================================================
255 /*! 
256  * 
257  */
258 //=============================================================================
259
260 Engines::Container_ptr
261 SALOME_ContainerManager::
262 FindContainer(const Engines::MachineParameters& params,
263               const Engines::MachineList& possibleComputers)
264 {
265   MESSAGE("FindContainer "<<possibleComputers.length());
266   for(unsigned int i=0;i<possibleComputers.length();i++)
267     {
268       MESSAGE("FindContainer possible " << possibleComputers[i]);
269       Engines::Container_ptr cont = FindContainer(params,possibleComputers[i]);
270       if( !CORBA::is_nil(cont) )
271         return cont;
272     }
273   MESSAGE("FindContainer: not found");
274   return Engines::Container::_nil();
275 }