Salome HOME
de43d8696ac1fc84cf34466a64fe9e0f43c16375
[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         cont->Shutdown();
101     }
102 }
103
104 //=============================================================================
105 /*! CORBA Method:
106  *  Find a suitable Container in a list of machines, or start one
107  *  \param params            Machine Parameters required for the container
108  *  \param possibleComputers list of machines usable for find or start
109  */
110 //=============================================================================
111
112 Engines::Container_ptr
113 SALOME_ContainerManager::
114 FindOrStartContainer(const Engines::MachineParameters& params,
115                      const Engines::MachineList& possibleComputers)
116 {
117   Engines::Container_ptr ret = FindContainer(params,possibleComputers);
118   if(!CORBA::is_nil(ret))
119     return ret;
120   MESSAGE("Container doesn't exist try to launch it ...");
121   MESSAGE("SALOME_ContainerManager::FindOrStartContainer " <<
122           possibleComputers.length());
123   //vector<string> vector;
124   string theMachine=_ResManager->FindBest(possibleComputers);
125   MESSAGE("try to launch it on " << theMachine);
126
127   string command;
128   if(theMachine=="")
129     {
130       MESSAGE("SALOME_ContainerManager::FindOrStartContainer : " <<
131               "no possible computer");
132       return Engines::Container::_nil();
133     }
134   else if(theMachine==GetHostname())
135     {
136       command=_ResManager->BuildCommandToLaunchLocalContainer(params);
137     }
138   else
139     command =
140       _ResManager->BuildCommandToLaunchRemoteContainer(theMachine,params);
141
142   _ResManager->RmTmpFile();
143   int status=system(command.c_str());
144   if (status == -1)
145     {
146       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed " <<
147               "(system command status -1)");
148       return Engines::Container::_nil();
149     }
150   else if (status == 217)
151     {
152       MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed " <<
153               "(system command status 217)");
154       return Engines::Container::_nil();
155     }
156   else
157     {
158       int count=TIME_OUT_TO_LAUNCH_CONT;
159       while ( CORBA::is_nil(ret) && count )
160         {
161 #ifndef WNT
162           sleep( 1 ) ;
163 #else
164           Sleep(1000);
165 #endif
166           count-- ;
167           if ( count != 10 )
168             MESSAGE( count << ". Waiting for FactoryServer on " << theMachine);
169           string containerNameInNS =
170             _NS->BuildContainerNameForNS(params,theMachine.c_str());
171           SCRUTE(containerNameInNS);
172           CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
173           ret=Engines::Container::_narrow(obj);
174         }
175       if ( CORBA::is_nil(ret) )
176         {
177           MESSAGE("SALOME_LifeCycleCORBA::StartOrFindContainer rsh failed");
178         }
179       return ret;
180     }
181 }
182
183 //=============================================================================
184 /*! 
185  * 
186  */
187 //=============================================================================
188
189 Engines::MachineList *
190 SALOME_ContainerManager::
191 GetFittingResources(const Engines::MachineParameters& params,
192                     const char *componentName)
193 {
194   MESSAGE("SALOME_ContainerManager::GetFittingResources");
195   Engines::MachineList *ret=new Engines::MachineList;
196   vector<string> vec;
197   try
198     {
199       vec = _ResManager->GetFittingResources(params,componentName);
200     }
201   catch(const SALOME_Exception &ex)
202     {
203       INFOS("Caught exception.");
204       THROW_SALOME_CORBA_EXCEPTION(ex.what(),SALOME::BAD_PARAM);
205       //return ret;
206     }
207
208   MESSAGE("Machine list length "<<vec.size());
209   ret->length(vec.size());
210   for(unsigned int i=0;i<vec.size();i++)
211     {
212       (*ret)[i]=(vec[i]).c_str();
213     }
214   return ret;
215 }
216
217 //=============================================================================
218 /*! 
219  * 
220  */
221 //=============================================================================
222
223 char*
224 SALOME_ContainerManager::
225 FindBest(const Engines::MachineList& possibleComputers)
226 {
227   string theMachine=_ResManager->FindBest(possibleComputers);
228   return CORBA::string_dup(theMachine.c_str());
229 }
230
231 //=============================================================================
232 /*! 
233  * 
234  */
235 //=============================================================================
236
237 Engines::Container_ptr
238 SALOME_ContainerManager::
239 FindContainer(const Engines::MachineParameters& params,
240               const char *theMachine)
241 {
242   string containerNameInNS(_NS->BuildContainerNameForNS(params,theMachine));
243   CORBA::Object_var obj = _NS->Resolve(containerNameInNS.c_str());
244   if( !CORBA::is_nil(obj) )
245     return Engines::Container::_narrow(obj);
246   else
247     return Engines::Container::_nil();
248 }
249
250 //=============================================================================
251 /*! 
252  * 
253  */
254 //=============================================================================
255
256 Engines::Container_ptr
257 SALOME_ContainerManager::
258 FindContainer(const Engines::MachineParameters& params,
259               const Engines::MachineList& possibleComputers)
260 {
261   MESSAGE("FindContainer "<<possibleComputers.length());
262   for(unsigned int i=0;i<possibleComputers.length();i++)
263     {
264       MESSAGE("FindContainer possible " << possibleComputers[i]);
265       Engines::Container_ptr cont = FindContainer(params,possibleComputers[i]);
266       if( !CORBA::is_nil(cont) )
267         return cont;
268     }
269   MESSAGE("FindContainer: not found");
270   return Engines::Container::_nil();
271 }