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 #ifndef INCLUDE_RCF_RCFPROTO_HPP
20 #define INCLUDE_RCF_RCFPROTO_HPP
21 
22 #include <RCF/GoogleProtobufs.hpp>
23 
24 #include <RCF/RCF.hpp>
25 #include <RCF/ClientStub.hpp>
26 #include <RCF/Exception.hpp>
27 #include <RCF/Export.hpp>
28 #include <RCF/RemoteCallContext.hpp>
29 
30 #ifdef BOOST_WINDOWS
31 #include <RCF/Win32Certificate.hpp>
32 #endif
33 
34 #if RCF_FEATURE_OPENSSL==1
35 
36 #include <RCF/OpenSslEncryptionFilter.hpp>
37 
38 #else
39 
40 namespace RCF {
41  class RCF_EXPORT PemCertificate : public Certificate
42  {
43  public:
44  PemCertificate(const std::string & pathToCert, const std::string & password = "")
45  {
46  RCF_THROW(Exception(_RcfError_NotSupportedInThisBuild("PemCertificate")));
47  }
48  };
49 
50  class RCF_EXPORT X509Certificate : public Certificate
51  {
52  public:
54  {
55  RCF_THROW(Exception(_RcfError_NotSupportedInThisBuild("X509Certificate")));
56  }
57  std::string getCertificateName() { return "";}
58  std::string getIssuerName() { return ""; }
59 
60  };
61 } // namespace RCF
62 
63 #endif
64 
65 #if RCF_FEATURE_SSPI==1
66 #include <RCF/Schannel.hpp>
67 #endif
68 
69 #if RCF_FEATURE_NAMEDPIPE==1
70 #include <RCF/Win32NamedPipeEndpoint.hpp>
71 #endif
72 
73 #if RCF_FEATURE_LOCALSOCKET==1
74 #include <RCF/UnixLocalEndpoint.hpp>
75 #endif
76 
77 #if RCF_FEATURE_LOCALSOCKET==0
78 
79 namespace RCF {
80 
81  class RCF_EXPORT UnixLocalEndpoint : public Endpoint
82  {
83  public:
84  UnixLocalEndpoint(const std::string & socketName) { RCF_THROW(Exception(_RcfError_NotSupportedInThisBuild("UnixLocalEndpoint"))); }
85 
86  virtual std::auto_ptr<ServerTransport> createServerTransport() const { return std::auto_ptr<ServerTransport>(); }
87  virtual std::auto_ptr<ClientTransport> createClientTransport() const { return std::auto_ptr<ClientTransport>(); }
88  virtual EndpointPtr clone() const { return EndpointPtr(); }
89  virtual std::string asString() const { return std::string(); }
90  };
91 
92 } // namespace RCF
93 
94 #endif // RCF_FEATURE_LOCALSOCKET==0
95 
96 #ifndef BOOST_WINDOWS
97 
98 namespace RCF {
99 
100  class RCF_EXPORT LogToDebugWindow : public LogTarget
101  {
102  public:
103  LogToDebugWindow()
104  {
105  Exception e(_RcfError_SupportedOnWindowsOnly("LogToDebugWindow"));
106  RCF_THROW(e);
107  }
108  virtual LogTarget * clone() const { return NULL; }
109  virtual void write(const RCF::ByteBuffer & output) {}
110  };
111 
112  class RCF_EXPORT LogToEventLog : public LogTarget
113  {
114  public:
115  LogToEventLog(const std::string & appName, int eventLogLevel)
116  {
117  Exception e(_RcfError_SupportedOnWindowsOnly("LogToEventLog"));
118  RCF_THROW(e);
119  }
120  virtual LogTarget * clone() const { return NULL; }
121  virtual void write(const RCF::ByteBuffer & output) {}
122  };
123 
124  class RCF_EXPORT Win32Certificate : public Certificate
125  {
126  public:
128  {
129  Exception e(_RcfError_SupportedOnWindowsOnly("Win32Certificate"));
130  RCF_THROW(e);
131  }
132 
133  virtual CertificateImplementationType _getType()
134  {
135  return Cit_Win32;
136  }
137 
138  tstring getCertificateName() { return tstring(); }
139  tstring getIssuerName() { return tstring(); }
140  void exportToPfx(const std::string & pfxFilePath) {}
141 
142  Win32CertificatePtr findRootCertificate(
143  Win32CertificateLocation certStoreLocation,
144  Win32CertificateStore certStore) { return Win32CertificatePtr(); }
145 
146  };
147 
148  class RCF_EXPORT PfxCertificate : public Win32Certificate
149  {
150  public:
151 
153  const std::string & pathToCert,
154  const tstring & password,
155  const tstring & certName)
156  {
157  Exception e(_RcfError_SupportedOnWindowsOnly("PfxCertificate"));
158  RCF_THROW(e);
159  }
160 
161  void addToStore(
162  Win32CertificateLocation certStoreLocation,
163  Win32CertificateStore certStore) {}
164  };
165 
166  class RCF_EXPORT StoreCertificate : public Win32Certificate
167  {
168  public:
169 
171  Win32CertificateLocation certStoreLocation,
172  Win32CertificateStore certStore,
173  const tstring & certName)
174  {
175  Exception e(_RcfError_SupportedOnWindowsOnly("StoreCertificate"));
176  RCF_THROW(e);
177  }
178 
179  void removeFromStore() {}
180 
181  };
182 
183  class RCF_EXPORT StoreCertificateIterator
184  {
185  public:
186 
188  Win32CertificateLocation certStoreLocation,
189  Win32CertificateStore certStore)
190  {
191  Exception e(_RcfError_SupportedOnWindowsOnly("StoreCertificateIterator"));
192  RCF_THROW(e);
193  }
194 
195  bool moveNext() { return false; }
196  void reset() {}
197  Win32CertificatePtr current() { return Win32CertificatePtr(); }
198  };
199 
200 } // namespace RCF
201 
202 #endif
203 
204 #if RCF_FEATURE_NAMEDPIPE==0
205 
206 namespace RCF {
207 
208  class RCF_EXPORT Win32NamedPipeEndpoint : public Endpoint
209  {
210  public:
211  Win32NamedPipeEndpoint(const tstring & pipeName) { RCF_THROW(Exception(_RcfError_SupportedOnWindowsOnly("Win32NamedPipeEndpoint"))); }
212 
213  virtual std::auto_ptr<ServerTransport> createServerTransport() const { return std::auto_ptr<ServerTransport>(); }
214  virtual std::auto_ptr<ClientTransport> createClientTransport() const { return std::auto_ptr<ClientTransport>(); }
215  virtual EndpointPtr clone() const { return EndpointPtr(); }
216  virtual std::string asString() const { return std::string(); }
217  };
218 
219 } // namespace RCF
220 
221 #endif // RCF_FEATURE_NAMEDPIPE==0
222 
223 #if RCF_FEATURE_SSPI==0
224 
225 namespace RCF {
226 
227 } // namespace RCF
228 
229 #endif // RCF_FEATURE_SSPI==0
230 
231 namespace RCF {
232 
233 RCF_EXPORT bool isProBuild();
234 
235 class RcfProtoChannel;
236 class RcfProtoSession;
237 class RcfProtoController;
238 
239 typedef boost::shared_ptr<RcfProtoController> RcfProtoControllerPtr;
240 
242 class RCF_EXPORT RcfProtoController : public google::protobuf::RpcController
243 {
244 public:
245 
248  virtual void Reset();
249 
253  virtual bool Failed() const;
254 
256  virtual std::string ErrorText() const;
257 
261  virtual void StartCancel();
262 
266  virtual bool Completed() const;
267 
268  // Server-side methods ---------------------------------------------
269 
270  // These calls may be made from the server side only. Their results
271  // are undefined on the client side (may crash).
272 
278  virtual void SetFailed(const std::string& reason);
279 
283  virtual bool IsCanceled() const;
284 
292  virtual void NotifyOnCancel(google::protobuf::Closure* callback);
293 
296 
297  RcfProtoSession * getSession();
298  RcfProtoChannel * getChannel();
299 
300 private:
301 
302  friend class RcfProtoChannel;
303  friend class RcfProtoServer;
304 
305  RcfProtoChannel * mpRcfChannel;
306  RcfProtoSession * mpRcfSession;
307 };
308 
309 
310 //------------------------------------------------------------------------------
311 // Client side implementation
312 
313 class I_Pb;
314 template<typename T> class RcfClient;
315 
316 class RcfProtoServer;
317 class RcfProtoSession;
318 
319 class RCF_EXPORT _SwigCallbackArgs
320 {
321 public:
322 
323  // *** SWIG BEGIN ***
324 
325  std::string mErrorString;
326 
327  CertificatePtr mCertificatePtr;
328 
329  // *** SWIG END ***
330 
331 };
332 
333 class RCF_EXPORT _SwigCallback
334 {
335 public:
336 
337  // *** SWIG BEGIN ***
338 
339  _SwigCallback();
340  virtual ~_SwigCallback();
341 
342  // Run client-side RPC completion handler.
343  virtual void Run();
344 
345  // Run server-side RPC server implementation.
346  virtual void ProtoRpcBegin(
347  _SwigCallbackArgs * args,
348  RcfProtoServer * server,
349  RcfProtoSession * session,
350  const std::string & serviceName,
351  int methodId);
352 
353  // Certificate validation callback.
354  virtual bool ValidateCertificate(
355  _SwigCallbackArgs * args);
356 
357  // *** SWIG END ***
358 
359 };
360 
361 class _SwigCallbackCpp : public _SwigCallback
362 {
363 public:
364  _SwigCallbackCpp(RcfProtoChannel & channel);
365  virtual void Run();
366 
367 private:
368  RcfProtoChannel & mChannel;
369 };
370 
372 class RCF_EXPORT RcfProtoChannel : public google::protobuf::RpcChannel
373 {
374 public:
375 
376  // For C#.
377  void _CallMethodSwig(
378  const std::string& serviceName,
379  int methodId,
380  unsigned char * szBuffer,
381  int szBufferLen,
382  _SwigCallback * closure);
383 
384  int _GetResponseBufferLength() const;
385  void _GetResponseBuffer(unsigned char * szBuffer, int bufferLen) const;
386 
387  // For Java.
388  void _CallMethodSwig(
389  const std::string& serviceName,
390  int methodId,
391  char * szBuffer,
392  size_t szBufferLen,
393  _SwigCallback * closure);
394 
395  void _GetResponseBuffer(char * szBuffer, size_t bufferLen) const;
396 
397 
398  // *** SWIG BEGIN ***
399 
401  RcfProtoChannel(const RCF::Endpoint & endpoint);
402 
403  void _CallMethodSwig_WithCopy(
404  const std::string& serviceName,
405  int methodId,
406  const std::string& strBuffer,
407  _SwigCallback * closure);
408 
409  std::string _GetResponseBuffer_WithCopy() const;
410 
411  // Controller interface.
412 
417  bool Failed();
418 
420  std::string ErrorText();
421 
427  void StartCancel();
428 
429  bool Completed();
430 
431  // RCF specific functionality.
432 
434  void connect();
435 
437  void disconnect();
438 
440  void setMaxMessageLength(std::size_t maxMessageSize);
441 
443  std::size_t getMaxMessageLength() const;
444 
446  void setRemoteCallTimeoutMs(unsigned int remoteCallTimeoutMs);
447 
449  unsigned int getRemoteCallTimeoutMs() const;
450 
452  void setConnectTimeoutMs(unsigned int connectTimeoutMs);
453 
455  unsigned int getConnectTimeoutMs() const;
456 
458  void setTransportProtocol(RCF::TransportProtocol protocol);
459 
461  RCF::TransportProtocol getTransportProtocol();
462 
464  void setAsynchronousRpcMode(bool enable);
465 
467  bool getAsynchronousRpcMode();
468 
469 
472  void setPingBackIntervalMs(int pingBackIntervalMs);
473 
475  int getPingBackIntervalMs();
476 
478  void setHttpProxy(const std::string & httpProxy);
479 
481  std::string getHttpProxy();
482 
484  void setHttpProxyPort(int httpProxyPort);
485 
487  int getHttpProxyPort();
488 
490  TransportType getTransportType();
491 
493  void setUsername(const tstring & username);
494 
496  tstring getUsername();
497 
499  void setPassword(const tstring & password);
500 
502  tstring getPassword();
503 
505  void setKerberosSpn(const tstring & kerberosSpn);
506 
508  tstring getKerberosSpn();
509 
511  void setEnableCompression(bool enableCompression);
512 
514  bool getEnableCompression();
515 
517  void setCertificate(CertificatePtr certificatePtr);
518 
520  CertificatePtr getCertificate();
521 
523  void setCaCertificate(CertificatePtr certificatePtr);
524 
526  CertificatePtr getCaCertificate();
527 
529  void setOpenSslCipherSuite(const std::string & cipherSuite);
530 
532  std::string getOpenSslCipherSuite() const;
533 
536  void setEnableSchannelCertificateValidation(const tstring & peerName);
537 
539  tstring getEnableSchannelCertificateValidation() const;
540 
541  void _setCertificateValidationCallback(_SwigCallback * pcb);
542 
544  void setSslImplementation(SslImplementation sslImplementation);
545 
547  SslImplementation getSslImplementation() const;
548 
549 
550  // *** SWIG END ***
551 
553  typedef ClientStub::CertificateValidationCb CertificateValidationCb;
554  void setCertificateValidationCallback(CertificateValidationCb certificateValidationCb);
555 
557  const CertificateValidationCb & getCertificateValidationCallback() const;
558 
559 
560  // Entry point from C++.
561  virtual void CallMethod(
562  const google::protobuf::MethodDescriptor * method,
563  google::protobuf::RpcController * controller,
564  const google::protobuf::Message * request,
565  google::protobuf::Message * response,
566  google::protobuf::Closure * done);
567 
568  // Common client calling code.
569  void CallMethodInternal(
570  const std::string & serviceName,
571  int methodId,
572  RCF::ByteBuffer requestBuffer,
573  _SwigCallback * closure);
574 
575 private:
576 
577  friend class _SwigCallbackCpp;
578  _SwigCallbackCpp mSwigCallbackCpp;
579 
580  void onCompletionCpp();
581  void onCompletion();
582 
583  boost::shared_ptr< RcfClient<I_Pb> > mRcfClientPtr;
584 
585  const google::protobuf::Message * mpRequest;
586  google::protobuf::Message * mpResponse;
587  google::protobuf::Closure * mpClosure;
588 
589  _SwigCallback * mpSwigCallback;
590 
591  boost::function<void()> mCompletionHandlerSwig;
592 
593  RCF::Future<RCF::ByteBuffer> mFuture;
594  RCF::Exception mError;
595  RCF::ByteBuffer mResponseBuffer;
596 
597  std::string mRequestCopy;
598 
599  bool mAsyncRpcMode;
600 };
601 
602 //------------------------------------------------------------------------------
603 // Server side implementation
604 
605 typedef RCF::RemoteCallContext<
606  RCF::ByteBuffer,
607  const std::string &,
608  int,
609  RCF::ByteBuffer> RcfProtoContext;
610 
611 class RcfProtoSession;
612 typedef boost::shared_ptr<RcfProtoSession> RcfProtoSessionPtr;
613 
615 class RCF_EXPORT RcfProtoSession
616 {
617 public:
618 
619  RcfProtoSession(RCF::RcfSession & session);
620  ~RcfProtoSession();
621 
622  int _GetRequestBufferLength();
623 
624  // For C#.
625  void _GetRequestBuffer(unsigned char * szBuffer, int szBufferLen);
626  void _SetResponseBuffer(unsigned char * szBuffer, int szBufferLen);
627 
628  // For Java
629  void _GetRequestBuffer(char * szBuffer, size_t szBufferLen);
630  void _SetResponseBuffer(char * szBuffer, size_t szBufferLen);
631 
632  // *** SWIG BEGIN ***
633 
639  void SetFailed(const std::string& reason);
640 
644  bool IsCanceled() const;
645 
646  void _Commit(const std::string& errorMsg);
647  void _Commit();
648 
649  std::string _GetRequestBuffer_WithCopy();
650 
651  void _SetResponseBuffer_WithCopy(const std::string& buffer);
652 
654  tstring getClientUsername();
655 
657  TransportProtocol getTransportProtocol();
658 
660  TransportType getTransportType();
661 
663  bool getEnableCompression();
664 
666  std::size_t getConnectionDuration() const;
667 
669  std::size_t getRemoteCallCount() const;
670 
672  boost::uint64_t getTotalBytesReceived() const;
673 
675  boost::uint64_t getTotalBytesSent() const;
676 
677 
678  // *** SWIG END ***
679 
680  // Returns the timestamp at which the client connected.
681  //time_t getConnectedAtTime() const;
682 
683 
689  //
691  void NotifyOnCancel(google::protobuf::Closure * callback);
692 
693  RcfSession& getRcfSession();
694 
695 private:
696 
697  friend class RcfProtoServer;
698 
699  RcfSession & mRcfSession;
700 
701  RcfProtoContext mServerContext;
702 
703  RCF::ByteBuffer mRequestBuffer;
704  RCF::ByteBuffer mResponseBuffer;
705 };
706 
707 typedef boost::shared_ptr<google::protobuf::Message> MessagePtr;
708 
710 class RCF_EXPORT RcfProtoServer : public RCF::RcfServer
711 {
712 public:
713 
714  // *** SWIG BEGIN ***
715 
716  RcfProtoServer();
717  RcfProtoServer(const RCF::Endpoint & endpoint);
718 
719  ~RcfProtoServer();
720 
722  void start();
723 
725  void stop();
726 
727  void _setCallbackTable(_SwigCallback * pCallback);
728 
730  void setThreadPool(ThreadPoolPtr threadPoolPtr) { RcfServer::setThreadPool(threadPoolPtr); }
731 
733  ThreadPoolPtr getThreadPool() { return RcfServer::getThreadPool(); }
734 
736  ServerTransport & addEndpoint(const RCF::Endpoint & endpoint) { return RcfServer::addEndpoint(endpoint); }
737 
744 
745  void setSupportedTransportProtocols(
746  const std::vector<TransportProtocol> & protocols) { RcfServer::setSupportedTransportProtocols(protocols); }
747 
749  const std::vector<TransportProtocol> &
750  getSupportedTransportProtocols() const { return RcfServer::getSupportedTransportProtocols(); }
751 
754  void setSessionTimeoutMs(boost::uint32_t sessionTimeoutMs) { return RcfServer::setSessionTimeoutMs(sessionTimeoutMs); }
755 
757  boost::uint32_t getSessionTimeoutMs() { return RcfServer::getSessionTimeoutMs(); }
758 
761  void setSessionHarvestingIntervalMs(boost::uint32_t sessionHarvestingIntervalMs) { RcfServer::setSessionHarvestingIntervalMs(sessionHarvestingIntervalMs); }
762 
764  boost::uint32_t getSessionHarvestingIntervalMs() { return RcfServer::getSessionHarvestingIntervalMs(); }
765 
767  void setCertificate(CertificatePtr certificatePtr) { RcfServer::setCertificate(certificatePtr); }
768 
770  CertificatePtr getCertificate() { return RcfServer::getCertificate(); }
771 
773  void setOpenSslCipherSuite(const std::string & cipherSuite) { RcfServer::setOpenSslCipherSuite(cipherSuite); }
774 
776  std::string getOpenSslCipherSuite() const { return RcfServer::getOpenSslCipherSuite(); }
777 
779  void setCaCertificate(CertificatePtr certificatePtr) { RcfServer::setCaCertificate(certificatePtr); }
780 
782  CertificatePtr getCaCertificate() { return RcfServer::getCaCertificate(); }
783 
786  void setEnableSchannelCertificateValidation(const tstring & peerName) { RcfServer::setEnableSchannelCertificateValidation(peerName); }
787 
789  tstring getEnableSchannelCertificateValidation() const { return RcfServer::getEnableSchannelCertificateValidation(); }
790 
791  // Sets the SSL implementation of the server.
792  void setSslImplementation(SslImplementation sslImplementation) { RcfServer::setSslImplementation(sslImplementation); }
793 
795  SslImplementation getSslImplementation() const { return RcfServer::getSslImplementation(); }
796 
797  // *** SWIG END ***
798 
800  void setCertificateValidationCallback(CertificateValidationCb certificateValidationCb) { RcfServer::setCertificateValidationCallback(certificateValidationCb); }
801 
803  const CertificateValidationCb & getCertificateValidationCallback() const { return RcfServer::getCertificateValidationCallback(); }
804 
805 
806  void bindService(google::protobuf::Service & service);
807 
808  RCF::ByteBuffer DoProtoRpc(
809  const std::string & serviceName,
810  int methodId,
811  RCF::ByteBuffer requestBuffer);
812 
813 private:
814 
815  void ProtoRpcBeginCpp(
816  RcfProtoSession & session,
817  const std::string & serviceName,
818  int methodId);
819 
820  void ProtoRpcEndCpp(
821  std::pair<MessagePtr, MessagePtr> requestResponsePair,
822  RcfProtoControllerPtr controllerPtr);
823 
824  typedef std::map<std::string, google::protobuf::Service *> ProtobufServices;
825 
826  ProtobufServices mProtobufServices;
827 
828  _SwigCallback * mpSwigCallback;
829 };
830 
831 class BoostBindClosure : public google::protobuf::Closure
832 {
833 public:
834  BoostBindClosure() :
835  mFunc(),
836  mPermanent(true)
837  {
838  }
839 
840  BoostBindClosure(const boost::function<void()> & func, bool permanent = false) :
841  mFunc(func),
842  mPermanent(permanent)
843  {
844  }
845 
846  void assign(const boost::function<void()> & func, bool permanent = true)
847  {
848  mFunc = func;
849  mPermanent = permanent;
850  }
851 
852  void Run()
853  {
854  mFunc();
855  if (!mPermanent)
856  {
857  delete this;
858  }
859  }
860 
861  boost::function<void()> mFunc;
862  bool mPermanent;
863 };
864 
865 } // namespace RCF
866 
867 #endif // ! INCLUDE_RCF_RCFPROTO_HPP