RCFProto
 All Classes Functions Typedefs
RCFProto.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 #pragma once
20 
21 #include <RCF/GoogleProtobufs.hpp>
22 
23 #include <RCF/RCF.hpp>
24 #include <RCF/ClientStub.hpp>
25 #include <RCF/Exception.hpp>
26 #include <RCF/Export.hpp>
27 #include <RCF/RemoteCallContext.hpp>
28 
29 #if RCF_FEATURE_OPENSSL==1
30 #include <RCF/OpenSslEncryptionFilter.hpp>
31 #else
32 namespace RCF {
33  class RCF_EXPORT PemCertificate : public Certificate
34  {
35  public:
36  PemCertificate(const std::string & pathToCert, const std::string & password = "")
37  {
38  RCF_THROW(Exception(_RcfError_NotSupportedInThisBuild("PemCertificate")));
39  }
40  };
41  class RCF_EXPORT X509Certificate : public Certificate
42  {
43  public:
45  {
46  RCF_THROW(Exception(_RcfError_NotSupportedInThisBuild("X509Certificate")));
47  }
48  std::string getCertificateName() { return "";}
49  std::string getIssuerName() { return ""; }
50 
51  };
52 } // namespace RCF
53 #endif
54 
55 #if RCF_FEATURE_SSPI==1
56 #include <RCF/Schannel.hpp>
57 #endif
58 
59 #if RCF_FEATURE_NAMEDPIPE==1
60 #include <RCF/Win32NamedPipeEndpoint.hpp>
61 #endif
62 
63 #if RCF_FEATURE_LOCALSOCKET==1
64 #include <RCF/UnixLocalEndpoint.hpp>
65 #endif
66 
67 #ifdef BOOST_WINDOWS
68 
69 // On Windows, stub out some Unix-only functionality.
70 namespace RCF {
71 
72  class RCF_EXPORT UnixLocalEndpoint : public Endpoint
73  {
74  public:
75  UnixLocalEndpoint(const std::string & socketName) { RCF_THROW(Exception(_RcfError_NotSupportedOnWindows("UnixLocalEndpoint"))); }
76 
77  virtual std::auto_ptr<ServerTransport> createServerTransport() const { return std::auto_ptr<ServerTransport>(); }
78  virtual std::auto_ptr<ClientTransport> createClientTransport() const { return std::auto_ptr<ClientTransport>(); }
79  virtual EndpointPtr clone() const { return EndpointPtr(); }
80  virtual std::string asString() const { return std::string(); }
81  };
82 
83 } // namespace RCF
84 
85 #else
86 
87 // On Unix, stub out some Windows-only functionality.
88 namespace RCF {
89 
90  class RCF_EXPORT LogToDebugWindow : public LogTarget
91  {
92  public:
93  LogToDebugWindow()
94  {
95  Exception e(_RcfError_SupportedOnWindowsOnly("LogToDebugWindow"));
96  RCF_THROW(e);
97  }
98  virtual LogTarget * clone() const { return NULL; }
99  virtual void write(const RCF::ByteBuffer & output) {}
100  };
101 
102  class RCF_EXPORT LogToEventLog : public LogTarget
103  {
104  public:
105  LogToEventLog(const std::string & appName, int eventLogLevel)
106  {
107  Exception e(_RcfError_SupportedOnWindowsOnly("LogToEventLog"));
108  RCF_THROW(e);
109  }
110  virtual LogTarget * clone() const { return NULL; }
111  virtual void write(const RCF::ByteBuffer & output) {}
112  };
113 
114  class RCF_EXPORT Win32NamedPipeEndpoint : public Endpoint
115  {
116  public:
117  Win32NamedPipeEndpoint(const tstring & pipeName) { RCF_THROW(Exception(_RcfError_SupportedOnWindowsOnly("Win32NamedPipeEndpoint"))); }
118 
119  virtual std::auto_ptr<ServerTransport> createServerTransport() const { return std::auto_ptr<ServerTransport>(); }
120  virtual std::auto_ptr<ClientTransport> createClientTransport() const { return std::auto_ptr<ClientTransport>(); }
121  virtual EndpointPtr clone() const { return EndpointPtr(); }
122  virtual std::string asString() const { return std::string(); }
123  };
124 
125  class RCF_EXPORT Win32Certificate : public Certificate
126  {
127  public:
129  {
130  Exception e(_RcfError_SupportedOnWindowsOnly("Win32Certificate"));
131  RCF_THROW(e);
132  }
133 
134  virtual CertificateImplementationType _getType()
135  {
136  return Cit_Win32;
137  }
138 
139  tstring getCertificateName() { return tstring(); }
140  tstring getIssuerName() { return tstring(); }
141  void exportToPfx(const std::string & pfxFilePath) {}
142 
143  Win32CertificatePtr findRootCertificate(
144  Win32CertificateLocation certStoreLocation,
145  Win32CertificateStore certStore) { return Win32CertificatePtr(); }
146 
147  // *** SWIG END ***
148  };
149 
150  class RCF_EXPORT PfxCertificate : public Win32Certificate
151  {
152  public:
153 
155  const std::string & pathToCert,
156  const tstring & password,
157  const tstring & certName)
158  {
159  Exception e(_RcfError_SupportedOnWindowsOnly("PfxCertificate"));
160  RCF_THROW(e);
161  }
162 
163  void addToStore(
164  Win32CertificateLocation certStoreLocation,
165  Win32CertificateStore certStore) {}
166  };
167 
168  class RCF_EXPORT StoreCertificate : public Win32Certificate
169  {
170  public:
171 
173  Win32CertificateLocation certStoreLocation,
174  Win32CertificateStore certStore,
175  const tstring & certName)
176  {
177  Exception e(_RcfError_SupportedOnWindowsOnly("StoreCertificate"));
178  RCF_THROW(e);
179  }
180 
181  void removeFromStore() {}
182 
183  };
184 
185  class RCF_EXPORT StoreCertificateIterator
186  {
187  public:
188 
190  Win32CertificateLocation certStoreLocation,
191  Win32CertificateStore certStore)
192  {
193  Exception e(_RcfError_SupportedOnWindowsOnly("StoreCertificateIterator"));
194  RCF_THROW(e);
195  }
196 
197  bool moveNext() { return false; }
198  void reset() {}
199  Win32CertificatePtr current() { return Win32CertificatePtr(); }
200  };
201 
202 } // namespace RCF
203 
204 #endif // ! BOOST_WINDOWS
205 
206 using namespace google::protobuf;
207 using namespace RCF;
208 
209 namespace RCF {
210 
211 class RcfProtoChannel;
212 class RcfProtoSession;
213 
215 class RCF_EXPORT RcfProtoController : public RpcController
216 {
217 public:
218 
221  virtual void Reset();
222 
226  virtual bool Failed() const;
227 
229  virtual std::string ErrorText() const;
230 
234  virtual void StartCancel();
235 
236  // Server-side methods ---------------------------------------------
237 
238  // These calls may be made from the server side only. Their results
239  // are undefined on the client side (may crash).
240 
246  virtual void SetFailed(const std::string& reason);
247 
251  virtual bool IsCanceled() const;
252 
260  virtual void NotifyOnCancel(Closure* callback);
261 
264 
265  RcfProtoSession * getSession();
266  RcfProtoChannel * getChannel();
267 
268 private:
269 
270  friend class RcfProtoChannel;
271  friend class RcfProtoServer;
272 
273  RcfProtoChannel * mpRcfChannel;
274  RcfProtoSession * mpRcfContext;
275 };
276 
277 
278 //------------------------------------------------------------------------------
279 // Client side implementation
280 
281 class I_Pb;
282 template<typename T> class RcfClient;
283 
284 class RcfProtoServer;
285 class RcfProtoSession;
286 
287 class RCF_EXPORT _SwigCallbackArgs
288 {
289 public:
290 
291  // *** SWIG BEGIN ***
292 
293  std::string mErrorString;
294 
295  CertificatePtr mCertificatePtr;
296 
297  // *** SWIG END ***
298 
299 };
300 
301 class RCF_EXPORT _SwigCallback
302 {
303 public:
304 
305  // *** SWIG BEGIN ***
306 
307  _SwigCallback();
308  virtual ~_SwigCallback();
309 
310  // Run client-side RPC completion handler.
311  virtual void Run();
312 
313  // Run server-side RPC server implementation.
314  virtual void ProtoRpcBegin(
315  _SwigCallbackArgs * args,
316  RcfProtoServer * server,
317  RcfProtoSession * context,
318  const std::string & serviceName,
319  int methodId);
320 
321  // Certificate validation callback.
322  virtual bool ValidateCertificate(
323  _SwigCallbackArgs * args);
324 
325  // *** SWIG END ***
326 
327 };
328 
329 class _SwigCallbackCpp : public _SwigCallback
330 {
331 public:
332  _SwigCallbackCpp(RcfProtoChannel & channel);
333  virtual void Run();
334 
335 private:
336  RcfProtoChannel & mChannel;
337 };
338 
340 class RCF_EXPORT RcfProtoChannel : public RpcChannel
341 {
342 public:
343 
344  // For C#.
345  void _CallMethodSwig(
346  const std::string& serviceName,
347  int methodId,
348  unsigned char * szBuffer,
349  int szBufferLen,
350  _SwigCallback * closure);
351 
352  int _GetResponseBufferLength() const;
353  void _GetResponseBuffer(unsigned char * szBuffer, int bufferLen) const;
354 
355  // For Java.
356  void _CallMethodSwig(
357  const std::string& serviceName,
358  int methodId,
359  char * szBuffer,
360  size_t szBufferLen,
361  _SwigCallback * closure);
362 
363  void _GetResponseBuffer(char * szBuffer, size_t bufferLen) const;
364 
365 
366  // *** SWIG BEGIN ***
367 
369  RcfProtoChannel(const RCF::Endpoint & endpoint);
370 
371  void _CallMethodSwig_WithCopy(
372  const std::string& serviceName,
373  int methodId,
374  const std::string& strBuffer,
375  _SwigCallback * closure);
376 
377  std::string _GetResponseBuffer_WithCopy() const;
378 
379  // Controller interface.
380 
385  bool Failed();
386 
388  std::string ErrorText();
389 
395  void StartCancel();
396 
397  // RCF specific functionality.
398 
400  void connect();
401 
403  void disconnect();
404 
406  void setRemoteCallTimeoutMs(unsigned int remoteCallTimeoutMs);
407 
409  unsigned int getRemoteCallTimeoutMs() const;
410 
412  void setConnectTimeoutMs(unsigned int connectTimeoutMs);
413 
415  unsigned int getConnectTimeoutMs() const;
416 
418  void setTransportProtocol(RCF::TransportProtocol protocol);
419 
421  RCF::TransportProtocol getTransportProtocol();
422 
424  void setEnableAsynchronousRpc(bool enable);
425 
427  bool getEnableAsynchronousRpc();
428 
429 
432  void setPingBackIntervalMs(int pingBackIntervalMs);
433 
435  int getPingBackIntervalMs();
436 
438  void setHttpProxy(const std::string & httpProxy);
439 
441  std::string getHttpProxy();
442 
444  void setHttpProxyPort(int httpProxyPort);
445 
447  int getHttpProxyPort();
448 
450  TransportType getTransportType();
451 
453  void setUsername(const tstring & username);
454 
456  tstring getUsername();
457 
459  void setPassword(const tstring & password);
460 
462  tstring getPassword();
463 
465  void setKerberosSpn(const tstring & kerberosSpn);
466 
468  tstring getKerberosSpn();
469 
471  void setEnableCompression(bool enableCompression);
472 
474  bool getEnableCompression();
475 
477  void setCertificate(CertificatePtr certificatePtr);
478 
480  CertificatePtr getCertificate();
481 
483  void setCaCertificate(CertificatePtr certificatePtr);
484 
486  CertificatePtr getCaCertificate();
487 
489  void setOpenSslCipherSuite(const std::string & cipherSuite);
490 
492  std::string getOpenSslCipherSuite() const;
493 
496  void setEnableSchannelCertificateValidation(const tstring & peerName);
497 
499  tstring getEnableSchannelCertificateValidation() const;
500 
501  void _setCertificateValidationCallback(_SwigCallback * pcb);
502 
504  void setSslImplementation(SslImplementation sslImplementation);
505 
507  SslImplementation getSslImplementation() const;
508 
509 
510  // *** SWIG END ***
511 
513  typedef ClientStub::CertificateValidationCb CertificateValidationCb;
514  void setCertificateValidationCallback(CertificateValidationCb certificateValidationCb);
515 
517  const CertificateValidationCb & getCertificateValidationCallback() const;
518 
519 
520  // Entry point from C++.
521  virtual void CallMethod(
522  const MethodDescriptor* method,
523  RpcController* controller,
524  const Message* request,
525  Message* response,
526  google::protobuf::Closure* done);
527 
528  // Common client calling code.
529  void CallMethodInternal(
530  const std::string & serviceName,
531  int methodId,
532  RCF::ByteBuffer requestBuffer,
533  _SwigCallback * closure);
534 
535 private:
536 
537  friend class _SwigCallbackCpp;
538  _SwigCallbackCpp mSwigCallbackCpp;
539 
540  void onCompletionCpp();
541  void onCompletion();
542 
543  boost::shared_ptr< RcfClient<I_Pb> > mRcfClientPtr;
544 
545  const Message * mpRequest;
546  Message * mpResponse;
547  Closure * mpClosure;
548 
549  _SwigCallback * mpSwigCallback;
550 
551  boost::function<void()> mCompletionHandlerSwig;
552 
553  RCF::Future<RCF::ByteBuffer> mFuture;
554  RCF::Exception mError;
555  RCF::ByteBuffer mResponseBuffer;
556 
557  std::string mRequestCopy;
558 
559  bool mEnableAsynchronousRpc;
560 };
561 
562 //------------------------------------------------------------------------------
563 // Server side implementation
564 
565 typedef RCF::RemoteCallContext<
566  RCF::ByteBuffer,
567  const std::string &,
568  int,
569  RCF::ByteBuffer> RcfProtoContext;
570 
572 class RCF_EXPORT RcfProtoSession
573 {
574 public:
575 
576  RcfProtoSession(RCF::RcfSession & session);
577 
578  int _GetRequestBufferLength();
579 
580  // For C#.
581  void _GetRequestBuffer(unsigned char * szBuffer, int szBufferLen);
582  void _SetResponseBuffer(unsigned char * szBuffer, int szBufferLen);
583 
584  // For Java
585  void _GetRequestBuffer(char * szBuffer, size_t szBufferLen);
586  void _SetResponseBuffer(char * szBuffer, size_t szBufferLen);
587 
588  // *** SWIG BEGIN ***
589 
595  void SetFailed(const std::string& reason);
596 
600  bool IsCanceled() const;
601 
602  void _Commit(const std::string& errorMsg);
603  void _Commit();
604 
605  std::string _GetRequestBuffer_WithCopy();
606 
607  void _SetResponseBuffer_WithCopy(const std::string& buffer);
608 
610  tstring getClientUsername();
611 
613  TransportProtocol getTransportProtocol();
614 
616  TransportType getTransportType();
617 
619  bool getEnableCompression();
620 
622  std::size_t getConnectionDuration() const;
623 
625  std::size_t getRemoteCallCount() const;
626 
628  boost::uint64_t getTotalBytesReceived() const;
629 
631  boost::uint64_t getTotalBytesSent() const;
632 
633 
634  // *** SWIG END ***
635 
636  // Returns the timestamp at which the client connected.
637  //time_t getConnectedAtTime() const;
638 
639 
645  //
647  void NotifyOnCancel(Closure* callback);
648 
649 
650 private:
651 
652  friend class RcfProtoServer;
653 
654  RcfSession & mRcfSession;
655 
656  RcfProtoContext mServerContext;
657 
658  RCF::ByteBuffer mRequestBuffer;
659  RCF::ByteBuffer mResponseBuffer;
660 };
661 
662 /*
663 class RCF_EXPORT RcfProtoServer_Vtbl
664 {
665 public:
666  RcfProtoServer_Vtbl()
667  {
668  }
669 
670  virtual ~RcfProtoServer_Vtbl()
671  {
672  }
673 
674  virtual void ProtoRpcBegin(
675  RcfProtoServer * server,
676  RcfProtoSession * context,
677  const std::string & serviceName,
678  int methodId)
679  {
680 
681  }
682 
683 };
684 */
685 
687 class RCF_EXPORT RcfProtoServer : public RCF::RcfServer
688 {
689 public:
690 
691  // *** SWIG BEGIN ***
692 
693  RcfProtoServer();
694  RcfProtoServer(const RCF::Endpoint & endpoint);
695 
696  ~RcfProtoServer();
697 
699  void start();
700 
702  void stop();
703 
704  void _setCallbackTable(_SwigCallback * pCallback);
705 
707  void setThreadPool(ThreadPoolPtr threadPoolPtr) { RcfServer::setThreadPool(threadPoolPtr); }
708 
710  ThreadPoolPtr getThreadPool() { return RcfServer::getThreadPool(); }
711 
713  ServerTransport & addEndpoint(const RCF::Endpoint & endpoint) { return RcfServer::addEndpoint(endpoint); }
714 
721 
722  void setSupportedTransportProtocols(
723  const std::vector<TransportProtocol> & protocols) { RcfServer::setSupportedTransportProtocols(protocols); }
724 
726  const std::vector<TransportProtocol> &
727  getSupportedTransportProtocols() const { return RcfServer::getSupportedTransportProtocols(); }
728 
731  void setSessionTimeoutMs(boost::uint32_t sessionTimeoutMs) { return RcfServer::setSessionTimeoutMs(sessionTimeoutMs); }
732 
734  boost::uint32_t getSessionTimeoutMs() { return RcfServer::getSessionTimeoutMs(); }
735 
738  void setSessionHarvestingIntervalMs(boost::uint32_t sessionHarvestingIntervalMs) { RcfServer::setSessionHarvestingIntervalMs(sessionHarvestingIntervalMs); }
739 
741  boost::uint32_t getSessionHarvestingIntervalMs() { return RcfServer::getSessionHarvestingIntervalMs(); }
742 
744  void setCertificate(CertificatePtr certificatePtr) { RcfServer::setCertificate(certificatePtr); }
745 
747  CertificatePtr getCertificate() { return RcfServer::getCertificate(); }
748 
750  void setOpenSslCipherSuite(const std::string & cipherSuite) { RcfServer::setOpenSslCipherSuite(cipherSuite); }
751 
753  std::string getOpenSslCipherSuite() const { return RcfServer::getOpenSslCipherSuite(); }
754 
756  void setCaCertificate(CertificatePtr certificatePtr) { RcfServer::setCaCertificate(certificatePtr); }
757 
759  CertificatePtr getCaCertificate() { return RcfServer::getCaCertificate(); }
760 
763  void setEnableSchannelCertificateValidation(const tstring & peerName) { RcfServer::setEnableSchannelCertificateValidation(peerName); }
764 
766  tstring getEnableSchannelCertificateValidation() const { return RcfServer::getEnableSchannelCertificateValidation(); }
767 
768  // Sets the SSL implementation of the server.
769  void setSslImplementation(SslImplementation sslImplementation) { RcfServer::setSslImplementation(sslImplementation); }
770 
772  SslImplementation getSslImplementation() const { return RcfServer::getSslImplementation(); }
773 
774  // *** SWIG END ***
775 
777  void setCertificateValidationCallback(CertificateValidationCb certificateValidationCb) { RcfServer::setCertificateValidationCallback(certificateValidationCb); }
778 
780  const CertificateValidationCb & getCertificateValidationCallback() const { return RcfServer::getCertificateValidationCallback(); }
781 
782 
783  void bindService(Service & service);
784 
785  RCF::ByteBuffer DoProtoRpc(
786  const std::string & serviceName,
787  int methodId,
788  RCF::ByteBuffer requestBuffer);
789 
790 private:
791 
792  void ProtoRpcBeginCpp(RcfProtoSession * context, const std::string & serviceName, int methodId);
793  void ProtoRpcEndCpp(Message * pResponse, RcfProtoController * controller);
794 
795  typedef std::map<std::string, Service *> ProtobufServices;
796  ProtobufServices mProtobufServices;
797 
798  _SwigCallback * mpSwigCallback;
799 };
800 
801 class BoostBindClosure : public Closure
802 {
803 public:
804  BoostBindClosure() :
805  mFunc(),
806  mPermanent(true)
807  {
808  }
809 
810  BoostBindClosure(const boost::function<void()> & func, bool permanent = false) :
811  mFunc(func),
812  mPermanent(permanent)
813  {
814  }
815 
816  void assign(const boost::function<void()> & func, bool permanent = true)
817  {
818  mFunc = func;
819  mPermanent = permanent;
820  }
821 
822  void Run()
823  {
824  mFunc();
825  if (!mPermanent)
826  {
827  delete this;
828  }
829  }
830 
831  boost::function<void()> mFunc;
832  bool mPermanent;
833 };
834 
835 } // namespace RCF