RCFProto

- Main Page
- Classes
- Files

- File List

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:
44 X509Certificate()
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:
128 Win32Certificate()
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
154 PfxCertificate(
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
172 StoreCertificate(
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
189 StoreCertificateIterator(
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
262 RcfProtoController();
263 RcfProtoController(RcfProtoSession * context);
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