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