Salome HOME
Implementation of working glob var. Remove memory leak on TestSalomeSDS.py.
[modules/yacs.git] / src / SALOMESDS / SALOMESDS_DataServerManager.cxx
1 // Copyright (C) 2007-2015  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   //
47   dftScope->initializePython(argc,argv);// agy : Very important ! invoke this method BEFORE activation !
48   // activate this to be ready to be usable from NS.
49   PortableServer::ObjectId_var id(_poa->activate_object(this));
50   CORBA::Object_var obj(_poa->id_to_reference(id));
51   SALOME::DataServerManager_var obj2(SALOME::DataServerManager::_narrow(obj));
52   // publish Data server manager in NS
53   SALOME_NamingService ns(orb);
54   ns.Register(obj2,NAME_IN_NS);
55   // the default DataScopeServer object is the only one hosted by the current process
56   dftScope->setPOA(_poa);
57   obj=dftScope->activate();
58   SALOME::DataScopeServer_var dftScopePtr(SALOME::DataScopeServer::_narrow(obj));
59   dftScope->registerInNS(dftScopePtr);// agy : Very important ! invoke this method BEFORE activation ! Because this method initializes Python !
60 }
61
62 SALOME::StringVec *DataServerManager::listScopes()
63 {
64   std::vector<std::string> scopes(listOfScopesCpp());
65   SALOME::StringVec *ret(new SALOME::StringVec);
66   std::size_t sz(scopes.size());
67   ret->length(sz);
68   for(std::size_t i=0;i<sz;i++)
69     (*ret)[i]=CORBA::string_dup(scopes[i].c_str());
70   return ret;
71 }
72
73 SALOME::StringVec *DataServerManager::listAliveAndKickingScopes()
74 {
75   std::vector<std::string> scopes(listOfScopesCpp());
76   std::size_t sz(scopes.size());
77   std::vector<std::string> retCpp; retCpp.reserve(sz);
78   for(std::size_t i=0;i<sz;i++)
79     {
80       if(isAliveAndKicking(scopes[i].c_str()))
81         retCpp.push_back(scopes[i]);
82     }
83   //
84   SALOME::StringVec *ret(new SALOME::StringVec);
85   sz=retCpp.size();
86   ret->length(sz);
87   for(std::size_t i=0;i<sz;i++)
88     (*ret)[i]=CORBA::string_dup(retCpp[i].c_str());
89   return ret;
90 }
91
92 SALOME::DataScopeServer_ptr DataServerManager::getDefaultScope()
93 {
94   SALOME::DataScopeServerBase_var ret(retriveDataScope(DFT_SCOPE_NAME_IN_NS));
95   if(CORBA::is_nil(ret))
96     return SALOME::DataScopeServer::_narrow(ret);
97   SALOME::DataScopeServer_ptr ret2(SALOME::DataScopeServer::_narrow(ret));
98   if(CORBA::is_nil(ret2))
99     throw Exception("DataServerManager::getDefaultScope : exists but has not expected sub type !");
100   return ret2;
101 }
102
103 CORBA::Boolean DataServerManager::isAliveAndKicking(const char *scopeName)
104 {
105   SALOME::DataScopeServerBase_var scopePtr(getScopePtrGivenName(scopeName));
106   return IsAliveAndKicking(scopePtr);
107 }
108
109 template<class T>
110 typename T::PtrType CreateDataScope(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns)
111 {
112   int isTransactionInt(T::IsTransaction);
113   if(std::find(scopes.begin(),scopes.end(),scopeName)!=scopes.end())
114     {
115       std::ostringstream oss; oss << "DataServerManager::createDataScope : scope name \"" << scopeName << "\" already exists !";
116       throw Exception(oss.str());
117     }
118   //
119   std::string fullScopeName(DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
120   std::ostringstream oss; oss << "SALOME_DataScopeServer" << " " << scopeName << " " << isTransactionInt << " ";
121   SALOME_ContainerManager::AddOmninamesParams(oss,&ns);
122   std::string command(oss.str());
123   SALOME_ContainerManager::MakeTheCommandToBeLaunchedASync(command);
124   int status(SALOME_ContainerManager::SystemThreadSafe(command.c_str()));
125   int count(SALOME_ContainerManager::GetTimeOutToLoaunchServer());
126   typename T::VarType ret(T::nil());
127   while (CORBA::is_nil(ret) && count)
128     {
129       SALOME_ContainerManager::SleepInSecond(1);
130       count--;
131       CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
132       ret=T::narrow(obj);
133     }
134   return T::duplicate(ret);
135 }
136
137 template<class T>
138 typename T::PtrType GiveADataScopeCalled(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns, CORBA::Boolean& isCreated)
139 {
140   if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
141     {
142       isCreated=true;
143       return CreateDataScope<T>(scopeName,scopes,ns);
144     }
145   else
146     {
147       SALOME::DataScopeServerBase_var ret(SALOMESDS::DataServerManager::GetScopePtrGivenName(scopeName,scopes,ns));
148       if(SALOMESDS::DataServerManager::IsAliveAndKicking(ret))
149         {
150           isCreated=false;
151           typename T::PtrType ret2(T::narrow(ret));
152           if(CORBA::is_nil(ret))
153             return ret2;
154           if(CORBA::is_nil(ret2))
155             {
156               std::ostringstream oss; oss << "DataServerManager::giveADataScopeCalled : scope \"" << scopeName << "\" exists but with invalid type !";
157               throw Exception(oss.str());
158             }
159           return ret2;
160         }
161       else
162         {
163           std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(scopeName));
164           ns.Destroy_Name(fullScopeName.c_str());
165           isCreated=true;
166           return CreateDataScope<T>(scopeName,scopes,ns);
167         }
168     }
169 }
170
171 class NormalFunctor
172 {
173 public:
174   typedef SALOME::DataScopeServer_ptr PtrType;
175   typedef SALOME::DataScopeServer_var VarType;
176   typedef SALOME::DataScopeServer TheType;
177   static const bool IsTransaction=false;
178   static PtrType nil() { return SALOME::DataScopeServer::_nil(); }
179   static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServer::_narrow(obj); }
180   static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServer::_duplicate(obj); }
181 };
182
183 class TransactionFunctor
184 {
185 public:
186   typedef SALOME::DataScopeServerTransaction_ptr PtrType;
187   typedef SALOME::DataScopeServerTransaction_var VarType;
188   typedef SALOME::DataScopeServerTransaction TheType;
189   static const bool IsTransaction=true;
190   static PtrType nil() { return SALOME::DataScopeServerTransaction::_nil(); }
191   static PtrType narrow(CORBA::Object_ptr obj) { return SALOME::DataScopeServerTransaction::_narrow(obj); }
192   static PtrType duplicate(PtrType obj) { return SALOME::DataScopeServerTransaction::_duplicate(obj); }
193 };
194
195 SALOME::DataScopeServer_ptr DataServerManager::createDataScope(const char *scopeName)
196 {
197   SALOME_NamingService ns(_orb);
198   return CreateDataScope<NormalFunctor>(scopeName,listOfScopesCpp(),ns);
199 }
200
201 SALOME::DataScopeServer_ptr DataServerManager::giveADataScopeCalled(const char *scopeName, CORBA::Boolean& isCreated)
202 {
203   SALOME_NamingService ns(_orb);
204   return GiveADataScopeCalled<NormalFunctor>(scopeName,listOfScopesCpp(),ns,isCreated);
205 }
206
207 SALOME::DataScopeServerTransaction_ptr DataServerManager::createDataScopeTransaction(const char *scopeName)
208 {
209   SALOME_NamingService ns(_orb);
210   return CreateDataScope<TransactionFunctor>(scopeName,listOfScopesCpp(),ns);
211 }
212
213 SALOME::DataScopeServerTransaction_ptr DataServerManager::giveADataScopeTransactionCalled(const char *scopeName, CORBA::Boolean& isCreated)
214 {
215   SALOME_NamingService ns(_orb);
216   return GiveADataScopeCalled<TransactionFunctor>(scopeName,listOfScopesCpp(),ns,isCreated);
217 }
218
219 SALOME::DataScopeServerBase_ptr DataServerManager::retriveDataScope(const char *scopeName)
220 {
221   SALOME::DataScopeServerBase_var ret(getScopePtrGivenName(scopeName));
222   return SALOME::DataScopeServerBase::_duplicate(ret);
223 }
224
225 void DataServerManager::removeDataScope(const char *scopeName)
226 {
227   SALOME::DataScopeServerBase_var scs(getScopePtrGivenName(scopeName));
228   SALOME::DataScopeKiller_ptr killer;
229   if(scs->shutdownIfNotHostedByDSM(killer))
230     killer->shutdown();
231   CORBA::release(killer);
232 }
233
234 void DataServerManager::cleanScopesInNS()
235 {
236   SALOME_NamingService ns(_orb);
237   std::vector<std::string> scopes(listOfScopesCpp());
238   for(std::vector<std::string>::const_iterator it=scopes.begin();it!=scopes.end();it++)
239     {
240       if(!isAliveAndKicking((*it).c_str()))
241         {
242           std::string fullScopeName(SALOMESDS::DataServerManager::CreateAbsNameInNSFromScopeName(*it));
243           ns.Destroy_Name(fullScopeName.c_str());
244         }
245     }
246 }
247
248 void DataServerManager::shutdownScopes()
249 {
250   std::vector<std::string> scopeNames(listOfScopesCpp());
251   for(std::vector<std::string>::const_iterator it=scopeNames.begin();it!=scopeNames.end();it++)
252     {
253       SALOME::DataScopeServerBase_var scope(getScopePtrGivenName(*it));
254       SALOME::DataScopeKiller_ptr killer;
255       if(scope->shutdownIfNotHostedByDSM(killer))
256         killer->shutdown();
257       CORBA::release(killer);
258     }
259 }
260
261 std::string DataServerManager::CreateAbsNameInNSFromScopeName(const std::string& scopeName)
262 {
263   std::ostringstream oss; oss << NAME_IN_NS << "/" << scopeName;
264   return oss.str();
265 }
266
267 CORBA::Boolean DataServerManager::IsAliveAndKicking(SALOME::DataScopeServerBase_ptr scopePtr)
268 {
269   CORBA::Boolean ret(true);
270   try
271     {
272       scopePtr->ping();
273     }
274   catch(...)
275     { ret=false; }
276   return ret;
277 }
278
279 std::vector<std::string> DataServerManager::listOfScopesCpp()
280 {
281   SALOME_NamingService ns(_orb);
282   ns.Change_Directory(NAME_IN_NS);
283   std::vector<std::string> ret(ns.list_directory());
284   return ret;
285 }
286
287 SALOME::DataScopeServerBase_var DataServerManager::GetScopePtrGivenName(const std::string& scopeName, const std::vector<std::string>& scopes, SALOME_NamingService& ns)
288 {
289   std::size_t sz(scopes.size());
290   if(std::find(scopes.begin(),scopes.end(),scopeName)==scopes.end())
291     {
292       std::ostringstream oss; oss << "DataServerManager::getScopePtrGivenName : scope name \"" << scopeName << "\" does not exist !";
293       throw Exception(oss.str());
294     }
295   std::string fullScopeName(CreateAbsNameInNSFromScopeName(scopeName));
296   CORBA::Object_var obj(ns.Resolve(fullScopeName.c_str()));
297   SALOME::DataScopeServerBase_var ret(SALOME::DataScopeServerBase::_narrow(obj));
298   return ret;
299 }
300
301 SALOME::DataScopeServerBase_var DataServerManager::getScopePtrGivenName(const std::string& scopeName)
302 {
303   SALOME_NamingService ns(_orb);
304   return GetScopePtrGivenName(scopeName,listOfScopesCpp(),ns);
305 }