RCFProto
 All Classes Functions Typedefs
RcfServer.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_RCFSERVER_HPP
20 #define INCLUDE_RCF_RCFSERVER_HPP
21 
22 #include <map>
23 #include <memory>
24 #include <set>
25 #include <string>
26 #include <vector>
27 
28 #include <boost/bind.hpp>
29 #include <boost/function.hpp>
30 #include <boost/mpl/bool.hpp>
31 #include <boost/noncopyable.hpp>
32 #include <boost/shared_ptr.hpp>
33 #include <boost/utility/enable_if.hpp>
34 #include <boost/weak_ptr.hpp>
35 
36 #include <RCF/CheckRtti.hpp>
37 #include <RCF/Export.hpp>
38 #include <RCF/GetInterfaceName.hpp>
39 #include <RCF/RcfClient.hpp>
40 #include <RCF/ServerObjectService.hpp>
41 #include <RCF/ServerStub.hpp>
42 #include <RCF/ServerTransport.hpp>
43 #include <RCF/ThreadLibrary.hpp>
44 #include <RCF/ThreadPool.hpp>
45 
46 #if RCF_FEATURE_FILETRANSFER==1
47 #include <RCF/FileTransferService.hpp>
48 #endif
49 
50 #if RCF_FEATURE_PUBSUB==1
51 #include <RCF/PublishingService.hpp>
52 #include <RCF/SubscriptionService.hpp>
53 #endif
54 
55 namespace RCF {
56 
57  class ServerTransport;
58  class StubEntry;
59  class I_Service;
60  class RcfSession;
61  class Endpoint;
62  class I_FilterFactoryLookupProvider;
63  class I_RcfClient;
64  class IpServerTransport;
65  class PingBackService;
66  class FileTransferService;
67  class ObjectFactoryService;
68  class FilterService;
69  class SessionTimeoutService;
70  class PublishingService;
71  class SubscriptionService;
72  class SessionObjectFactoryService;
73  class ObjectFactoryService;
74  class CallbackConnectionService;
75 
76  typedef boost::shared_ptr<ServerTransport> ServerTransportPtr;
77  typedef boost::shared_ptr<StubEntry> StubEntryPtr;
78  typedef boost::shared_ptr<I_Service> ServicePtr;
79  typedef boost::shared_ptr<RcfSession> RcfSessionPtr;
80  typedef boost::shared_ptr<I_FilterFactoryLookupProvider> FilterFactoryLookupProviderPtr;
81  typedef boost::shared_ptr<I_RcfClient> RcfClientPtr;
82  typedef boost::shared_ptr<Endpoint> EndpointPtr;
83  typedef boost::shared_ptr<PingBackService> PingBackServicePtr;
84  typedef boost::shared_ptr<FileTransferService> FileTransferServicePtr;
85  typedef boost::shared_ptr<ObjectFactoryService> ObjectFactoryServicePtr;
86  typedef boost::shared_ptr<FilterService> FilterServicePtr;
87  typedef boost::shared_ptr<SessionTimeoutService> SessionTimeoutServicePtr;
88  typedef boost::shared_ptr<PublishingService> PublishingServicePtr;
89  typedef boost::shared_ptr<SubscriptionService> SubscriptionServicePtr;
90  typedef boost::shared_ptr<SessionObjectFactoryService> SessionObjectFactoryServicePtr;
91  typedef boost::shared_ptr<ObjectFactoryService> ObjectFactoryServicePtr;
92  typedef boost::shared_ptr<CallbackConnectionService> CallbackConnectionServicePtr;
93  typedef boost::weak_ptr<RcfSession> RcfSessionWeakPtr;
94 
95  template<typename Interface>
96  class Publisher;
97 
98  class Subscription;
99  typedef boost::shared_ptr<Subscription> SubscriptionPtr;
100 
101  class SubscriptionParms;
102 
103  class BandwidthQuota;
104  typedef boost::shared_ptr<BandwidthQuota> BandwidthQuotaPtr;
105 
106  class FileDownloadInfo;
107  class FileUploadInfo;
108 
109  class JsonRpcRequest;
110  class JsonRpcResponse;
111 
112  class SspiFilter;
113 
114  typedef boost::function2<void, RcfSessionPtr, ClientTransportAutoPtr> OnCallbackConnectionCreated;
115 
116  class RCF_EXPORT RcfServer : boost::noncopyable
117  {
118  public:
119 
120  RcfServer();
121  RcfServer(const Endpoint &endpoint);
122  RcfServer(ServicePtr servicePtr);
123  RcfServer(ServerTransportPtr serverTransportPtr);
124 
125  ~RcfServer();
126 
127  typedef boost::function0<void> JoinFunctor;
128  typedef boost::function1<void, RcfServer&> StartCallback;
129 
130  void start();
131  void stop();
132 
133  private:
134 
135  void init();
136 
137  public:
138 
139  ServerTransport &
140  getServerTransport();
141 
142  I_Service &
143  getServerTransportService();
144 
145  ServerTransportPtr
146  getServerTransportPtr();
147 
148  IpServerTransport &
149  getIpServerTransport();
150 
151  private:
152 
153  bool addService(
154  ServicePtr servicePtr);
155 
156  bool removeService(
157  ServicePtr servicePtr);
158 
159  public:
160 
161  PingBackServicePtr
162  getPingBackServicePtr();
163 
164  FileTransferServicePtr
165  getFileTransferServicePtr();
166 
167  SessionTimeoutServicePtr
168  getSessionTimeoutServicePtr();
169 
170  ObjectFactoryServicePtr
171  getObjectFactoryServicePtr();
172 
173  SessionObjectFactoryServicePtr
174  getSessionObjectFactoryServicePtr();
175 
176  PublishingServicePtr
177  getPublishingServicePtr();
178 
179  SubscriptionServicePtr
180  getSubscriptionServicePtr();
181 
182  bool addServerTransport(
183  ServerTransportPtr serverTransportPtr);
184 
185  bool removeServerTransport(
186  ServerTransportPtr serverTransportPtr);
187 
188  ServerTransport & findTransportCompatibleWith(ClientTransport & clienetTransport);
189 
190  void setStartCallback(const StartCallback &startCallback);
191 
192  private:
193  void invokeStartCallback();
194 
195  private:
196  ServerBindingPtr bindImpl(
197  const std::string &name,
198  RcfClientPtr rcfClientPtr);
199 
200  //*************************************
201  // async io transport interface
202 
203  //private:
204  public:
205  SessionPtr createSession();
206  void onReadCompleted(SessionPtr sessionPtr);
207  void onWriteCompleted(SessionPtr sessionPtr);
208 
209 
210  //*************************************
211  // transports, queues and threads
212 
213  private:
214 
215  void startImpl();
216 
217  public:
218 
219 
220  template<typename Iter>
221  void enumerateSessions(const Iter & iter)
222  {
223 
224  for (std::size_t i=0; i<mServerTransports.size(); ++i)
225  {
226  mServerTransports[i]->enumerateSessions(iter);
227  }
228 
229  }
230 
231  //*************************************
232  // stub management
233 
234  private:
235  ReadWriteMutex mStubMapMutex;
236  typedef std::map<std::string, StubEntryPtr> StubMap;
237  StubMap mStubMap;
238 
239  typedef boost::function<void(const JsonRpcRequest &, JsonRpcResponse &)> JsonRpcMethod;
240  typedef std::map<std::string, JsonRpcMethod> JsonRpcMethods;
241  JsonRpcMethods mJsonRpcMethods;
242 
243  friend class RcfSession;
244 
245 
246 
247  //*************************************
248  // service management
249 
250  private:
251  std::vector<ServerTransportPtr> mServerTransports;
252  std::vector<ServicePtr> mServices;
253  FilterServicePtr mFilterServicePtr;
254  PingBackServicePtr mPingBackServicePtr;
255  FileTransferServicePtr mFileTransferServicePtr;
256  SessionTimeoutServicePtr mSessionTimeoutServicePtr;
257  PublishingServicePtr mPublishingServicePtr;
258  SubscriptionServicePtr mSubscriptionServicePtr;
259  CallbackConnectionServicePtr mCallbackConnectionServicePtr;
260  SessionObjectFactoryServicePtr mSessionObjectFactoryServicePtr;
261  ObjectFactoryServicePtr mObjectFactoryServicePtr;
262  ServerObjectServicePtr mServerObjectServicePtr;
263 
264  void startService(ServicePtr servicePtr) const;
265  void stopService(ServicePtr servicePtr) const;
266  void resolveServiceThreadPools(ServicePtr servicePtr) const;
267 
268  friend class AsioSessionState;
269  FilterPtr createFilter(int filterId);
270 
271  private:
272  // start/stop functionality
273  StartCallback mStartCallback;
274  Condition mStartEvent;
275  Condition mStopEvent;
276 
277  Mutex mStartStopMutex;
278  bool mStarted;
279 
280 
281  public:
282  void setThreadPool(ThreadPoolPtr threadPoolPtr);
283  ThreadPoolPtr getThreadPool();
284  ServerTransport & addEndpoint(const Endpoint & endpoint);
285 
286  private:
287  ThreadPoolPtr mThreadPoolPtr;
288 
289  public:
290 
291  void waitForStopEvent();
292  void waitForStartEvent();
293 
294  bool isStarted();
295 
296  // TODO: get rid of this hack
297  private:
298  friend class MethodInvocationRequest;
299 
300  public:
301  boost::uint32_t getRuntimeVersion();
302  void setRuntimeVersion(boost::uint32_t version);
303 
304  boost::uint32_t getArchiveVersion();
305  void setArchiveVersion(boost::uint32_t version);
306 
307  private:
308  boost::uint32_t mRuntimeVersion;
309  boost::uint32_t mArchiveVersion;
310 
311 
312  public:
313 
314  template<typename I1, typename ImplementationT>
315  ServerBindingPtr bind(ImplementationT & t, const std::string &name = "")
316  {
317  boost::shared_ptr< I_Deref<ImplementationT> > derefPtr(
318  new DerefObj<ImplementationT>(t) );
319 
320  RcfClientPtr rcfClientPtr = createServerStub(
321  (I1 *) 0,
322  (ImplementationT *) 0, derefPtr);
323 
324  return bindImpl(
325  name.empty() ?
326  I1::getInterfaceName() :
327  name ,
328  rcfClientPtr);
329  }
330 
331  template<typename I1, typename I2, typename ImplementationT>
332  ServerBindingPtr bind(ImplementationT & t, const std::string &name = "")
333  {
334  boost::shared_ptr< I_Deref<ImplementationT> > derefPtr(
335  new DerefObj<ImplementationT>(t) );
336 
337  RcfClientPtr rcfClientPtr = createServerStub(
338  (I1 *) 0,
339  (ImplementationT *) 0, derefPtr);
340 
341  {
342  RcfClientPtr toMergePtr = createServerStub(
343  (I2 *) 0,
344  (ImplementationT *) 0,
345  derefPtr);
346 
347  rcfClientPtr->getServerStub().merge(toMergePtr);
348  }
349  return bindImpl(
350  name.empty() ?
351  I1::getInterfaceName() :
352  name ,
353  rcfClientPtr);
354  }
355 
356  template<typename I1, typename I2, typename I3, typename ImplementationT>
357  ServerBindingPtr bind(ImplementationT & t, const std::string &name = "")
358  {
359  boost::shared_ptr< I_Deref<ImplementationT> > derefPtr(
360  new DerefObj<ImplementationT>(t) );
361 
362  RcfClientPtr rcfClientPtr = createServerStub( (I1 *) 0, (ImplementationT *) 0, derefPtr);
363  {
364  RcfClientPtr toMergePtr = createServerStub(
365  (I2 *) 0,
366  (ImplementationT *) 0,
367  derefPtr);
368 
369  rcfClientPtr->getServerStub().merge(toMergePtr);
370  }
371  {
372  RcfClientPtr toMergePtr = createServerStub(
373  (I3 *) 0,
374  (ImplementationT *) 0,
375  derefPtr);
376 
377  rcfClientPtr->getServerStub().merge(toMergePtr);
378  }
379 
380  return bindImpl(
381  name.empty() ?
382  I1::getInterfaceName() :
383  name ,
384  rcfClientPtr);
385  }
386 
387  template<typename I1, typename I2, typename I3, typename I4, typename ImplementationT>
388  ServerBindingPtr bind(ImplementationT & t, const std::string &name = "")
389  {
390  boost::shared_ptr< I_Deref<ImplementationT> > derefPtr(
391  new DerefObj<ImplementationT>(t) );
392 
393  RcfClientPtr rcfClientPtr = createServerStub(
394  (I1 *) 0,
395  (ImplementationT *) 0,
396  derefPtr);
397 
398  {
399  RcfClientPtr toMergePtr = createServerStub(
400  (I2 *) 0,
401  (ImplementationT *) 0,
402  derefPtr);
403 
404  rcfClientPtr->getServerStub().merge(toMergePtr);
405  }
406 
407  {
408  RcfClientPtr toMergePtr = createServerStub(
409  (I3 *) 0,
410  (ImplementationT *) 0, derefPtr);
411 
412  rcfClientPtr->getServerStub().merge(toMergePtr);
413  }
414 
415  {
416  RcfClientPtr toMergePtr = createServerStub(
417  (I4 *) 0,
418  (ImplementationT *) 0,
419  derefPtr);
420 
421  rcfClientPtr->getServerStub().merge(toMergePtr);
422  }
423 
424  return bindImpl(
425  name.empty() ?
426  I1::getInterfaceName() :
427  name ,
428  rcfClientPtr);
429  }
430 
431  template<typename InterfaceT>
432  bool unbind(const std::string &name_ = "")
433  {
434  const std::string &name = (name_ == "") ?
435  getInterfaceName((InterfaceT *) NULL) :
436  name_;
437 
438  WriteLock writeLock(mStubMapMutex);
439  mStubMap.erase(name);
440  return true;
441  }
442 
443 #if RCF_FEATURE_JSON==1
444  void bindJsonRpc(JsonRpcMethod jsonRpcMethod, const std::string & jsonRpcName);
445  void unbindJsonRpc(const std::string & jsonRpcName);
446 #endif
447 
448  void setSupportedTransportProtocols(
449  const std::vector<TransportProtocol> & protocols);
450 
451  const std::vector<TransportProtocol> &
452  getSupportedTransportProtocols() const;
453 
454  void setCertificate(CertificatePtr certificatePtr);
455  CertificatePtr getCertificate();
456 
457  void setOpenSslCipherSuite(const std::string & cipherSuite);
458  std::string getOpenSslCipherSuite() const;
459 
460  void setCaCertificate(CertificatePtr certificatePtr);
461  CertificatePtr getCaCertificate();
462 
463 
464  typedef boost::function<bool(Certificate *)> CertificateValidationCb;
465  void setCertificateValidationCallback(CertificateValidationCb certificateValidationCb);
466  const CertificateValidationCb & getCertificateValidationCallback() const;
467 
468  void setEnableSchannelCertificateValidation(const tstring & peerName);
469  tstring getEnableSchannelCertificateValidation() const;
470 
471  void setSslImplementation(SslImplementation sslImplementation);
472  SslImplementation getSslImplementation() const;
473 
474  void setSessionTimeoutMs(boost::uint32_t sessionTimeoutMs);
475  boost::uint32_t getSessionTimeoutMs();
476 
477  void setSessionHarvestingIntervalMs(boost::uint32_t sessionHarvestingIntervalMs);
478  boost::uint32_t getSessionHarvestingIntervalMs();
479 
480  void setOnCallbackConnectionCreated(OnCallbackConnectionCreated onCallbackConnectionCreated);
481  OnCallbackConnectionCreated getOnCallbackConnectionCreated();
482 
483  void setOfsMaxNumberOfObjects(boost::uint32_t ofsMaxNumberOfObjects);
484  void setOfsObjectTimeoutS(boost::uint32_t ofsObjectTimeoutS);
485  void setOfsCleanupIntervalS(boost::uint32_t ofsCleanupIntervalS);
486  void setOfsCleanupThreshold(float ofsCleanupThreshold);
487 
488  boost::uint32_t getOfsMaxNumberOfObjects() const;
489  boost::uint32_t getOfsObjectTimeoutS() const;
490  boost::uint32_t getOfsCleanupIntervalS() const;
491  float getOfsCleanupThreshold() const;
492 
493 #if RCF_FEATURE_FILETRANSFER==1
494 
495  typedef FileTransferService::OnFileDownloadProgress OnFileDownloadProgress;
496  typedef FileTransferService::OnFileUploadProgress OnFileUploadProgress;
497 
498  void setOnFileDownloadProgress(OnFileDownloadProgress onFileDownloadProgress);
499  void setOnFileUploadProgress(OnFileUploadProgress onFileUploadProgress);
500 
501  void setFileUploadDirectory(const std::string & uploadDir);
502  std::string getFileUploadDirectory() const;
503 
504  typedef boost::function1<BandwidthQuotaPtr, RcfSession &> BandwidthQuotaCallback;
505  typedef BandwidthQuotaCallback FileUploadQuotaCallback;
506  typedef BandwidthQuotaCallback FileDownloadQuotaCallback;
507 
508  void setFileUploadBandwidthLimit(boost::uint32_t uploadQuotaBps);
509  boost::uint32_t getFileUploadBandwidthLimit() const;
510 
511  void setFileUploadCustomBandwidthLimit(FileUploadQuotaCallback uploadQuotaCb);
512 
513  void setFileDownloadBandwidthLimit(boost::uint32_t downloadQuotaBps);
514  boost::uint32_t getFileDownloadBandwidthLimit() const;
515 
516  void setFileDownloadCustomBandwidthLimit(FileDownloadQuotaCallback downloadQuotaCb);
517 
518  private:
519 
520  OnFileDownloadProgress mOnFileDownloadProgress;
521  OnFileUploadProgress mOnFileUploadProgress;
522 
523  std::string mFileUploadDirectory;
524 
525  boost::uint32_t mFileUploadQuota;
526  FileUploadQuotaCallback mFileUploadQuotaCb;
527 
528  boost::uint32_t mFileDownloadQuota;
529  FileDownloadQuotaCallback mFileDownloadQuotaCb;
530 
531  friend class FileTransferService;
532 
533 #endif
534 
535  private:
536 
537  mutable ReadWriteMutex mPropertiesMutex;
538 
539  std::vector<TransportProtocol> mSupportedProtocols;
540  CertificatePtr mCertificatePtr;
541  std::string mOpenSslCipherSuite;
542 
543  CertificatePtr mCaCertificatePtr;
544  CertificateValidationCb mCertificateValidationCb;
545  tstring mSchannelCertificateValidation;
546 
547  SslImplementation mSslImplementation;
548 
549  boost::uint32_t mSessionTimeoutMs;
550  boost::uint32_t mSessionHarvestingIntervalMs;
551 
552  OnCallbackConnectionCreated mOnCallbackConnectionCreated;
553 
554  boost::uint32_t mOfsMaxNumberOfObjects;
555  boost::uint32_t mOfsObjectTimeoutS;
556  boost::uint32_t mOfsCleanupIntervalS;
557  float mOfsCleanupThreshold;
558 
559  public:
560 
561 #if RCF_FEATURE_PUBSUB==1
562 
563  template<typename Interface>
564  boost::shared_ptr< Publisher<Interface> > createPublisher()
565  {
566  PublisherParms parms;
567  return mPublishingServicePtr->createPublisher<Interface>(parms);
568  }
569 
570  template<typename Interface>
571  boost::shared_ptr< Publisher<Interface> > createPublisher(
572  const PublisherParms & parms)
573  {
574  return mPublishingServicePtr->createPublisher<Interface>(parms);
575  }
576 
577  template<typename Interface, typename T>
578  boost::shared_ptr< Subscription > createSubscription(
579  T & t,
580  const RCF::Endpoint & publisherEp)
581  {
582  RCF_ASSERT(mStarted);
583  SubscriptionParms parms;
584  parms.setPublisherEndpoint(publisherEp);
585  return mSubscriptionServicePtr->createSubscription<Interface>(t, publisherEp);
586  }
587 
588  template<typename Interface, typename T>
589  boost::shared_ptr< Subscription > createSubscription(
590  T & t,
591  const SubscriptionParms & parms)
592  {
593  RCF_ASSERT(mStarted);
594  return mSubscriptionServicePtr->createSubscription<Interface>(t, parms);
595  }
596 
597 #endif
598 
599  private:
600 
601  boost::uint32_t mServerObjectHarvestingIntervalS;
602 
603 
604  public:
605 
606  boost::uint32_t getServerObjectHarvestingIntervalS() const;
607  void setServerObjectHarvestingIntervalS(boost::uint32_t harvestingIntervalS);
608 
609  template<typename T>
610  boost::shared_ptr<T> queryServerObject(
611  const std::string & objectKey,
612  boost::uint32_t timeoutMs)
613  {
614  return mServerObjectServicePtr->queryServerObject<T>(objectKey, timeoutMs);
615  }
616 
617  template<typename T>
618  boost::shared_ptr<T> getServerObject(
619  const std::string & objectKey,
620  boost::uint32_t timeoutMs)
621  {
622  return mServerObjectServicePtr->getServerObject<T>(objectKey, timeoutMs);
623  }
624 
625  void deleteServerObject(const std::string & objectKey);
626  };
627 
628 } // namespace RCF
629 
630 #endif // ! INCLUDE_RCF_RCFSERVER_HPP
631