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