]> SALOME platform Git repositories - modules/kernel.git/blob - src/SALOMESDS/SALOMESDS_DataServerManager.cxx
Salome HOME
Go on for RequestSwitcher conquest
[modules/kernel.git] / src / SALOMESDS / SALOMESDS_DataServerManager.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony GEAY (EDF R&D)
20
21 #include "SALOMESDS_DataServerManager.hxx"
22 #include "SALOMESDS_Exception.hxx"
23
24 #include "SALOME_ContainerManager.hxx"
25 #include "SALOME_NamingService.hxx"
26
27 #include <sstream>
28 #include <algorithm>
29
30 using namespace SALOMESDS;
31
32 const char DataServerManager::NAME_IN_NS[]="/DataServerManager";
33
34 const char DataServerManager::DFT_SCOPE_NAME_IN_NS[]="Default";
35
36 DataServerManager::DataServerManager(int argc, char *argv[], CORBA::ORB_ptr orb, PortableServer::POA_ptr poa):_orb(CORBA::ORB::_duplicate(orb))
37 {
38   DataScopeServer *dftScope(new DataScopeServer(orb,SALOME::DataScopeKiller::_nil(),DFT_SCOPE_NAME_IN_NS));//_remove_ref will be call by DataScopeServer::shutdownIfNotHostedByDSM
39   PortableServer::POAManager_var pman(poa->the_POAManager());
40   CORBA::PolicyList policies;
41   policies.length(1);
42   PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
43   policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
44   _poa=poa->create_POA("SingleThPOA4SDS",pman,policies);
45   threadPol->destroy();
46   //An another _poa_for_request_control to give to my boss the pure power
47   {
48     CORBA::PolicyList policies;
49     policies.length(1);
50     PortableServer::ThreadPolicy_var threadPol(poa->create_thread_policy(PortableServer::SINGLE_THREAD_MODEL));
51     policies[0]=PortableServer::ThreadPolicy::_duplicate(threadPol);
52     // all is in PortableServer::POAManager::_nil. By specifying _nil cf Advanced CORBA Programming with C++ p 506
53     // a new POA manager is created. This POA manager is independent from POA manager of the son ones.
54     _poa_for_request_control=poa->create_POA("4RqstSwitcher",PortableServer::POAManager::_nil(),policies);
55     threadPol->destroy();
56     PortableServer::POAManager_var mgr(_poa_for_request_control->the_POAManager());
57     mgr->activate();
58   }
59   //
60   dftScope->initializePython(argc,argv);// agy : Very important ! invoke this method BEFORE activation !
61   // activate this to be ready to be usable from NS.
62   PortableServer::ObjectId_var id(_poa->activate_object(this));
63   CORBA::Object_var obj(_poa->id_to_reference(id));
64   SALOME::DataServerManager_var obj2(SALOME::DataServerManager::_narrow(obj));
65   // publish Data server manager in NS
66   SALOME_NamingService ns(orb);
67   ns.Register(obj2,NAME_IN_NS);
68   // the default DataScopeServer object is the only one hosted by the current process
69   dftScope->setPOA(_poa);
70   obj=dftScope->activate();
71   SALOME::DataScopeServer_var dftScopePtr(SALOME::DataScopeServer::_narrow(obj));
72   dftScope->registerInNS(dftScopePtr);// agy : Very important ! invoke this method BEFORE activation ! Because this method initializes Python !
73 }
74
75 SALOME::StringVec *DataServerManager::listScopes()
76 {
77   std::vector<std::string> scopes(listOfScopesCpp());
78   SALOME::StringVec *ret(new SALOME::StringVec);
79   std::size_t sz(scopes.size());
80   ret->length(sz);
81   for(std::size_t i=0;i<sz;i++)
82     (*ret)[i]=CORBA::string_dup(scopes[i].c_str());
83   return ret;
84 }
85
86 SALOME::StringVec *DataServerManager::listAliveAndKickingScopes()
87 {
88   std::vector<std::string> scopes(listOfScopesCpp());
89   std::size_t sz(scopes.size());
90   std::vector<std::string> retCpp; retCpp.reserve(sz);
91   for(std::size_t i=0;i<sz;i++)
92     {
93       if(isAliveAndKicking(scopes[i].c_str()))
94         retCpp.push_back(scopes[i]);
95     }
96   //
97   SALOME::StringVec *ret(new SALOME::StringVec);
98   sz=retCpp.size();
99   ret->length(sz);
100   for(std::size_t i=0;i<sz;i++)
101     (*ret)[i]=CORBA::string_dup(retCpp[i].c_str());
102   return ret;
103 }
104
105 SALOME::DataScopeServer_ptr DataServerManager::getDefaultScope()
106 {
107   SALOME::DataScopeServerBase_var ret(retriveDataScope(DFT_SCOPE_NAME_IN_NS));
108   if(CORBA::is_nil(ret))
109     return SALOME::DataScopeServer::_narrow(ret);
110   SALOME::DataScopeServer_ptr ret2(SALOME::DataScopeServer::_narrow(ret));
111   if(CORBA::is_nil(ret2))
112     throw Exception("DataServerManager::getDefaultScope : exists but has not expected sub type !");
113   return ret2;
114 }
115
116 CORBA::Boolean DataServerManager::isAliveAndKicking(const char *scopeName)
117 {
118   SALOME::DataScopeServerBase_var scopePtr(getScopePtrGivenName(scopeName));
119   return IsAliveAndKicking(scopePtr);
120 }
121
122 template<class T>
123 typename T::PtrType CreateDataScope(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns)
124 {
125   int isTransactionInt(T::IsTransaction);
126   if(std::find(scopes.begin(),scopes.end(),scopeName)!=scopes.end())
127     {
128       std::ostringstream oss; oss << "DataServerManager::createDataScope : scope name \"" << scopeName << "\" already exists !";
129       throw Exception(oss.str());
130     }
131   //
132   std::string fullScopeName(DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
133   std::ostringstream oss; oss << "SALOME_DataScopeServer" << " " << scopeName << " " << isTransactionInt << " ";
134   SALOME_ContainerManager::AddOmninamesParams(oss,&ns);
135   std::string command(oss.str());
136   SALOME_ContainerManager::MakeTheCommandToBeLaunchedASync(command);
137   int status(SALOME_ContainerManager::SystemThreadSafe(command.c_str()));
138   if(status!=0)
139     {
140       std::ostringstream oss2; oss2 << "CreateDataScope : Fail to launch \"" << command << "\" ! Return code was : " << status << " !";
141       throw Exception(oss2.str());
142     }
143   int count(SALOME_ContainerManager::GetTimeOutToLoaunchServer());
144   typename T::VarType ret(T::nil());
145   while (CORBA::is_nil(ret) && count)
146     {
147       SALOME_ContainerManager::SleepInSecond(1);
148       count--;
149       CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
150       ret=T::narrow(obj);
151     }
152   return T::duplicate(ret);
153 }
154
155 template<class T>
156 typename T::PtrType GiveADataScopeCalled(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns, CORBA::Boolean& isCreated)
157 {
158   if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
159     {
160       isCreated=true;
161       return CreateDataScope<T>(scopeName,scopes,ns);
162     }
163   else
164     {
165       SALOME::DataScopeServerBase_var ret(SALOMESDS::DataServerManager::GetScopePtrGivenName(scopeName,scopes,ns));
166       if(SALOMESDS::DataServerManager::IsAliveAndKicking(ret))
167         {
168           isCreated=false;
169           typename T::PtrType ret2(T::narrow(ret));
170           if(CORBA::is_nil(ret))
171             return ret2;
172           if(CORBA::is_nil(ret2))
173             {
174               std::ostringstream oss; oss << "DataServerManager::giveADataScopeCalled : scope \"" << scopeName << "\" exists but with invalid type !";
175               throw Exception(oss.str());
176             }
177           return ret2;
178         }
179       else
180         {
181           std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
182           ns.Destroy_Name(fullScopeName.c_str());
183           isCreated=true;
184           return CreateDataScope<T>(scopeName,scopes,ns);
185         }
186     }
187 }
188
189 class NormalFunctor
190 {
191 public:
192   typedef SALOME::DataScopeServer_ptr PtrType;
193   typedef SALOME::DataScopeServer_var VarType;
194   typedef SALOME::DataScopeServer TheType;
195   static const bool IsTransaction=false;
196   static PtrType nil() { return SALOME::DataScopeServer::_nil(); }
197   static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServer::_narrow(obj); }
198   static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServer::_duplicate(obj); }
199 };
200
201 class TransactionFunctor
202 {
203 public:
204   typedef SALOME::DataScopeServerTransaction_ptr PtrType;
205   typedef SALOME::DataScopeServerTransaction_var VarType;
206   typedef SALOME::DataScopeServerTransaction TheType;
207   static const bool IsTransaction=true;
208   static PtrType nil() { return SALOME::DataScopeServerTransaction::_nil(); }
209   static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServerTransaction::_narrow(obj); }
210   static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServerTransaction::_duplicate(obj); }
211 };
212
213 SALOME::DataScopeServer_ptr DataServerManager::createDataScope(const char *scopeName)
214 {
215   SALOME_NamingService ns(_orb);
216   return CreateDataScope<NormalFunctor>(scopeName,listOfScopesCpp(),ns);
217 }
218
219 SALOME::DataScopeServer_ptr DataServerManager::giveADataScopeCalled(const char *scopeName, CORBA::Boolean& isCreated)
220 {
221   SALOME_NamingService ns(_orb);
222   return GiveADataScopeCalled<NormalFunctor>(scopeName,listOfScopesCpp(),ns,isCreated);
223 }
224
225 SALOME::DataScopeServerTransaction_ptr DataServerManager::createDataScopeTransaction(const char *scopeName)
226 {
227   SALOME_NamingService ns(_orb);
228   return CreateDataScope<TransactionFunctor>(scopeName,listOfScopesCpp(),ns);
229 }
230
231 SALOME::DataScopeServerTransaction_ptr DataServerManager::giveADataScopeTransactionCalled(const char *scopeName, CORBA::Boolean& isCreated)
232 {
233   SALOME_NamingService ns(_orb);
234   return GiveADataScopeCalled<TransactionFunctor>(scopeName,listOfScopesCpp(),ns,isCreated);
235 }
236
237 SALOME::DataScopeServerBase_ptr DataServerManager::retriveDataScope(const char *scopeName)
238 {
239   SALOME::DataScopeServerBase_var ret(getScopePtrGivenName(scopeName));
240   return SALOME::DataScopeServerBase::_duplicate(ret);
241 }
242
243 void DataServerManager::removeDataScope(const char *scopeName)
244 {
245   SALOME::DataScopeServerBase_var scs(getScopePtrGivenName(scopeName));
246   SALOME::DataScopeKiller_ptr killer;
247   if(scs->shutdownIfNotHostedByDSM(killer))
248     killer->shutdown();
249   CORBA::release(killer);
250 }
251
252 void DataServerManager::cleanScopesInNS()
253 {
254   SALOME_NamingService ns(_orb);
255   std::vector<std::string> scopes(listOfScopesCpp());
256   for(std::vector<std::string>::const_iterator it=scopes.begin();it!=scopes.end();it++)
257     {
258       if(!isAliveAndKicking((*it).c_str()))
259         {
260           std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(*it));
261           ns.Destroy_Name(fullScopeName.c_str());
262         }
263     }
264 }
265
266 void DataServerManager::shutdownScopes()
267 {
268   std::vector<std::string> scopeNames(listOfScopesCpp());
269   for(std::vector<std::string>::const_iterator it=scopeNames.begin();it!=scopeNames.end();it++)
270     {
271       SALOME::DataScopeServerBase_var scope(getScopePtrGivenName(*it));
272       SALOME::DataScopeKiller_ptr killer;
273       if(scope->shutdownIfNotHostedByDSM(killer))
274         killer->shutdown();
275       CORBA::release(killer);
276     }
277 }
278
279 std::string DataServerManager::CreateAbsNameInNSFromScopeName(const std::string& scopeName)
280 {
281   std::ostringstream oss; oss << NAME_IN_NS << "/" << scopeName;
282   return oss.str();
283 }
284
285 CORBA::Boolean DataServerManager::IsAliveAndKicking(SALOME::DataScopeServerBase_ptr scopePtr)
286 {
287   CORBA::Boolean ret(true);
288   try
289     {
290       scopePtr->ping();
291     }
292   catch(...)
293     { ret=false; }
294   return ret;
295 }
296
297 std::vector<std::string> DataServerManager::listOfScopesCpp()
298 {
299   SALOME_NamingService ns(_orb);
300   ns.Change_Directory(NAME_IN_NS);
301   std::vector<std::string> ret(ns.list_directory());
302   return ret;
303 }
304
305 SALOME::DataScopeServerBase_var DataServerManager::GetScopePtrGivenName(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns)
306 {
307   if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
308     {
309       std::ostringstream oss; oss << "DataServerManager::getScopePtrGivenName : scope name \"" << scopeName << "\" does not exist !";
310       throw Exception(oss.str());
311     }
312   std::string fullScopeName(CreateAbsNameInNSFromScopeName(scopeName));
313   CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
314   SALOME::DataScopeServerBase_var ret(SALOME::DataScopeServerBase::_narrow(obj));
315   return ret;
316 }
317
318 SALOME::DataScopeServerBase_var DataServerManager::getScopePtrGivenName(const std::string& scopeName)
319 {
320   SALOME_NamingService ns(_orb);
321   return GetScopePtrGivenName(scopeName,listOfScopesCpp(),ns);
322 }