RCFProto
 All Classes Functions Typedefs
TransportFactories.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_TEST_TRANSPORTFACTORIES_HPP
20 #define INCLUDE_RCF_TEST_TRANSPORTFACTORIES_HPP
21 
22 #include <iostream>
23 #include <typeinfo>
24 #include <utility>
25 #include <vector>
26 
27 #include <sys/stat.h>
28 
29 #include <boost/config.hpp>
30 #include <boost/shared_ptr.hpp>
31 #include <boost/version.hpp>
32 
33 #include <RCF/ClientStub.hpp>
34 #include <RCF/InitDeinit.hpp>
35 #include <RCF/ThreadLibrary.hpp>
36 
37 #include <RCF/TcpAsioServerTransport.hpp>
38 #include <RCF/Asio.hpp>
39 #include <RCF/Config.hpp>
40 
41 #ifdef RCF_HAS_LOCAL_SOCKETS
42 #include <RCF/UnixLocalClientTransport.hpp>
43 #include <RCF/UnixLocalServerTransport.hpp>
44 #endif
45 
46 #if RCF_FEATURE_NAMEDPIPE==1
47 #include <RCF/Win32NamedPipeClientTransport.hpp>
48 #include <RCF/Win32NamedPipeEndpoint.hpp>
49 #include <RCF/Win32NamedPipeServerTransport.hpp>
50 #endif
51 
52 #include <RCF/TcpClientTransport.hpp>
53 #include <RCF/UdpClientTransport.hpp>
54 #include <RCF/UdpServerTransport.hpp>
55 
56 #include <RCF/ObjectFactoryService.hpp>
57 
58 template<typename Interface>
59 inline bool tryCreateRemoteObject(
60  RCF::I_RcfClient &rcfClient,
61  std::string objectName = "")
62 {
63  try
64  {
65  rcfClient.getClientStub().createRemoteObject(objectName);
66  return true;
67  }
68  catch (const RCF::Exception &e)
69  {
70  RCF_LOG_1()(e);
71  return false;
72  }
73 }
74 
75 
76 namespace RCF {
77 
78  typedef boost::shared_ptr<ClientTransportAutoPtr> ClientTransportAutoPtrPtr;
79 
80  typedef std::pair<ServerTransportPtr, ClientTransportAutoPtrPtr> TransportPair;
81 
82  class I_TransportFactory
83  {
84  public:
85  virtual ~I_TransportFactory() {}
86  virtual TransportPair createTransports() = 0;
87  virtual TransportPair createNonListeningTransports() = 0;
88  virtual bool isConnectionOriented() = 0;
89  virtual bool supportsTransportFilters() = 0;
90  virtual std::string desc() = 0;
91  };
92 
93  typedef boost::shared_ptr<I_TransportFactory> TransportFactoryPtr;
94 
95  typedef std::vector<TransportFactoryPtr> TransportFactories;
96 
97  static TransportFactories &getTransportFactories()
98  {
99  static TransportFactories transportFactories;
100  return transportFactories;
101  }
102 
103  static TransportFactories &getIpTransportFactories()
104  {
105  static TransportFactories ipTransportFactories;
106  return ipTransportFactories;
107  }
108 
109  //**************************************************
110  // transport factories
111 
112  static std::string loopBackV4 = "127.0.0.1";
113  static std::string loopBackV6 = "::1";
114 
115 #if RCF_FEATURE_NAMEDPIPE==1
116 
117  class Win32NamedPipeTransportFactory : public I_TransportFactory
118  {
119  public:
120  TransportPair createTransports()
121  {
122  typedef boost::shared_ptr<Win32NamedPipeServerTransport> Win32NamedPipeServerTransportPtr;
123  Win32NamedPipeServerTransportPtr serverTransportPtr(
124  new Win32NamedPipeServerTransport(RCF_T("")));
125 
126  tstring pipeName = serverTransportPtr->getPipeName();
127 
128  ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
129  new ClientTransportAutoPtr(
130  new Win32NamedPipeClientTransport(pipeName)));
131 
132  return std::make_pair(
133  ServerTransportPtr(serverTransportPtr),
134  clientTransportAutoPtrPtr);
135 
136  }
137 
138  TransportPair createNonListeningTransports()
139  {
140  return std::make_pair(
141  ServerTransportPtr( new Win32NamedPipeServerTransport( RCF_T("")) ),
142  ClientTransportAutoPtrPtr());
143 
144  }
145 
146  bool isConnectionOriented()
147  {
148  return true;
149  }
150 
151  bool supportsTransportFilters()
152  {
153  return true;
154  }
155 
156  std::string desc()
157  {
158  return "Win32NamedPipeTransportFactory";
159  }
160  };
161 
162 #endif
163 
164 #if RCF_FEATURE_TCP==1
165 
166  class TcpAsioTransportFactory : public I_TransportFactory
167  {
168  public:
169 
170  TcpAsioTransportFactory(IpAddress::Type type = IpAddress::V4)
171  {
172  switch (type)
173  {
174  case IpAddress::V4: mLoopback = loopBackV4; break;
175  case IpAddress::V6: mLoopback = loopBackV6; break;
176  default: RCF_ASSERT(0);
177  }
178  }
179 
180  TransportPair createTransports()
181  {
182  typedef boost::shared_ptr<TcpAsioServerTransport> TcpAsioServerTransportPtr;
183  TcpAsioServerTransportPtr tcpServerTransportPtr(
184  new TcpAsioServerTransport( IpAddress(mLoopback, 0)));
185 
186  tcpServerTransportPtr->open();
187  int port = tcpServerTransportPtr->getPort();
188 
189  ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
190  new ClientTransportAutoPtr(
191  new TcpClientTransport( IpAddress(mLoopback, port))));
192 
193  return std::make_pair(
194  ServerTransportPtr(tcpServerTransportPtr),
195  clientTransportAutoPtrPtr);
196  }
197 
198  TransportPair createNonListeningTransports()
199  {
200  return std::make_pair(
201  ServerTransportPtr( new TcpAsioServerTransport( IpAddress(mLoopback, 0)) ),
202  ClientTransportAutoPtrPtr());
203  }
204 
205  bool isConnectionOriented()
206  {
207  return true;
208  }
209 
210  bool supportsTransportFilters()
211  {
212  return true;
213  }
214 
215  std::string desc()
216  {
217  return "TcpAsioTransportFactory (" + mLoopback + ")";
218  }
219 
220  private:
221 
222  std::string mLoopback;
223 
224  };
225 
226 #endif
227 
228 #if RCF_FEATURE_LOCALSOCKET==1
229 
230  class UnixLocalTransportFactory : public I_TransportFactory
231  {
232  public:
233 
234  UnixLocalTransportFactory() : mIndex(0)
235  {
236  }
237 
238  private:
239 
240  TransportPair createTransports()
241  {
242  std::string pipeName = generateNewPipeName();
243 
244  RCF_LOG_2()(pipeName) << "Creating unix local socket transport pair";
245 
246  return std::make_pair(
247  ServerTransportPtr( new UnixLocalServerTransport(pipeName) ),
248  ClientTransportAutoPtrPtr(
249  new ClientTransportAutoPtr(
250  new UnixLocalClientTransport(pipeName))));
251  }
252 
253  TransportPair createNonListeningTransports()
254  {
255  return std::make_pair(
256  ServerTransportPtr( new UnixLocalServerTransport("") ),
257  ClientTransportAutoPtrPtr());
258  }
259 
260  bool isConnectionOriented()
261  {
262  return true;
263  }
264 
265  bool supportsTransportFilters()
266  {
267  return true;
268  }
269 
270  private:
271 
272  bool fileExists(const std::string & path)
273  {
274  struct stat stFileInfo = {};
275  int ret = stat(path.c_str(), &stFileInfo);
276  return ret == 0;
277  }
278 
279  std::string generateNewPipeName()
280  {
281  std::string tempDir = RCF::getRelativeTestDataPath();
282 
283  std::string candidate;
284 
285  while (candidate.empty() || fileExists(candidate))
286  {
287  std::ostringstream os;
288  os
289  << tempDir
290  << "TestPipe_"
291  << ++mIndex;
292 
293  candidate = os.str();
294  }
295 
296  return candidate;
297  }
298 
299  std::string desc()
300  {
301  return "UnixLocalTransportFactory";
302  }
303 
304  int mIndex;
305 
306  };
307 
308 #endif // RCF_HAS_LOCAL_SOCKETS
309 
310 #if RCF_FEATURE_UDP==1
311 
312  class UdpTransportFactory : public I_TransportFactory
313  {
314  public:
315 
316  UdpTransportFactory(IpAddress::Type type = IpAddress::V4)
317  {
318  switch (type)
319  {
320  case IpAddress::V4: mLoopback = loopBackV4; break;
321  case IpAddress::V6: mLoopback = loopBackV6; break;
322  default: RCF_ASSERT(0);
323  }
324  }
325 
326  TransportPair createTransports()
327  {
328  typedef boost::shared_ptr<UdpServerTransport> UdpServerTransportPtr;
329  UdpServerTransportPtr udpServerTransportPtr(
330  new UdpServerTransport( IpAddress(mLoopback, 0) ));
331 
332  udpServerTransportPtr->open();
333  int port = udpServerTransportPtr->getPort();
334 
335  ClientTransportAutoPtrPtr clientTransportAutoPtrPtr(
336  new ClientTransportAutoPtr(
337  new UdpClientTransport( IpAddress(mLoopback, port) )));
338 
339  return std::make_pair(
340  ServerTransportPtr(udpServerTransportPtr),
341  clientTransportAutoPtrPtr);
342  }
343 
344  TransportPair createNonListeningTransports()
345  {
346  return std::make_pair(
347  ServerTransportPtr( new UdpServerTransport( IpAddress(mLoopback, 0) ) ),
348  ClientTransportAutoPtrPtr());
349  }
350 
351  bool isConnectionOriented()
352  {
353  return false;
354  }
355 
356  bool supportsTransportFilters()
357  {
358  return false;
359  }
360 
361  std::string desc()
362  {
363  return "UdpTransportFactory (" + mLoopback + ")";
364  }
365 
366  private:
367 
368  std::string mLoopback;
369  };
370 
371 #endif
372 
373  typedef TcpAsioTransportFactory TcpTransportFactory;
374 
375  void initializeTransportFactories()
376  {
377 
378 #if RCF_FEATURE_IPV6==1
379  const bool compileTimeIpv6 = true;
380  ExceptionPtr ePtr;
381  IpAddress("::1").resolve(ePtr);
382  const bool runTimeIpv6 = (ePtr.get() == NULL);
383 #else
384  const bool compileTimeIpv6 = false;
385  const bool runTimeIpv6 = false;
386 #endif
387 
388 #if RCF_FEATURE_NAMEDPIPE==1
389 
390  getTransportFactories().push_back(
391  TransportFactoryPtr( new Win32NamedPipeTransportFactory()));
392 
393 #endif
394 
395 #if RCF_FEATURE_TCP==1
396 
397  getTransportFactories().push_back(
398  TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));
399 
400  getIpTransportFactories().push_back(
401  TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V4)));
402 
403  if (compileTimeIpv6 && runTimeIpv6)
404  {
405  getTransportFactories().push_back(
406  TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));
407 
408  getIpTransportFactories().push_back(
409  TransportFactoryPtr( new TcpAsioTransportFactory(IpAddress::V6)));
410  }
411 
412 #endif
413 
414 #if RCF_FEATURE_LOCALSOCKET==1
415 
416  getTransportFactories().push_back(
417  TransportFactoryPtr( new UnixLocalTransportFactory()));
418 
419 #endif
420 
421 #if RCF_FEATURE_UDP==1
422 
423  getTransportFactories().push_back(
424  TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));
425 
426  getIpTransportFactories().push_back(
427  TransportFactoryPtr( new UdpTransportFactory(IpAddress::V4)));
428 
429  if (compileTimeIpv6 && runTimeIpv6)
430  {
431  getTransportFactories().push_back(
432  TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
433 
434  getIpTransportFactories().push_back(
435  TransportFactoryPtr( new UdpTransportFactory(IpAddress::V6)));
436  }
437 
438 #endif
439 
440  }
441 
442 } // namespace RCF
443 
444 #endif // ! INCLUDE_RCF_TEST_TRANSPORTFACTORIES_HPP