summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Event/ECG_Mcast_Gateway.h
blob: 5ab71be6c18b860f5046f739188930f8d2fbb16f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
// -*- C++ -*-

/**
 *  @file   ECG_Mcast_Gateway.h
 *
 *  @author Marina Spivak (marina@atdesk.com)
 */

#ifndef TAO_ECG_MCAST_GATEWAY_H
#define TAO_ECG_MCAST_GATEWAY_H
#include /**/ "ace/pre.h"

#include "orbsvcs/Event/ECG_UDP_Sender.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#include "orbsvcs/Event/ECG_Defaults.h"
#include /**/ "orbsvcs/Event/event_serv_export.h"
#include "orbsvcs/Event/ECG_UDP_Receiver.h"
#include "orbsvcs/Event/ECG_UDP_Out_Endpoint.h"
#include "ace/Service_Object.h"
#include "ace/Service_Config.h"
#include "ace/SString.h"
#include "ace/os_include/os_stdint.h"

ACE_BEGIN_VERSIONED_NAMESPACE_DECL
class ACE_Event_Handler;
ACE_END_VERSIONED_NAMESPACE_DECL

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @class TAO_ECG_Mcast_Gateway
 *
 * @brief Implement the builder for setting up Event Channel multicast
 *        gateway.
 *        NOT THREAD-SAFE.
 *
 * This class simplifies creation of federated Event Channels by
 * presenting a simple unified interface for creating and configuring
 * all components needed to federate an Event Channel.
 * Configuration options are described below.
 *
 * NOTE: This class does not own any of the components it creates and
 * its lifetime is independent of theirs.  This class acts purely as a
 * wrapper facade for creating and wiring appropriate components
 * together.
 *
 * @todo This class is an ACE_Service_Object, but the only reason for
 * it is the need for easy configuration using files.  Since
 * ACE_Service_Object provides much more than that, we should look
 * into replacing it with a more lightweight utility that would serve
 * our needs.
 *
 * CONFIGURATION OPTIONS
 * There are two ways to use this class:
 * 1) Use service config file to specify configuration options (which
 *    are described below), and use service configurator to obtain a
 *    an instance of configured TAO_ECG_Mcast_Gateway in your program.  (See
 *    TAO/orbsvcs/tests/Event/Mcast/Common and
 *    TAO/orbsvcs/tests/Event/Mcast/Simple for an example.)
 *
 * Service config file options:
 *
 * -ECGService <service>
 *  Valid values: sender, receiver, two_way
 *  Specifies whether this gateway should act as a multicast sender of
 *  the events or multicast receiver, or both.
 *
 * -ECGAddressServer <server_type>
 *  Valid values: basic, source, type
 *  Specifies what implementation of the address server should be used
 *  by the gateway.  basic - the same multicast address is returned for
 *  all event headers.  source - multicast addresses are returned based
 *  on the event source, according to the mapping provided at
 *  initialization.  type - multicast addresses are returned based
 *  on the event type, according to the mapping provided at
 *  initialization.
 *
 * -ECGAddressServerArg <arg>
 *  Valid value: arg is a string, whose format requirements are
 *  specific to the implementation of address server used.
 *  Arg is not interpreted by the gateway, but simply passed to the
 *  address server specified by -ECGAddressServer during initialization.
 *  THIS OPTION MUST ALWAYS BE SPECIFIED BY THE USER (there is no
 *  default value for it)
 *
 * -ECGHandler <handler_type>
 *  Valid values: basic, complex, udp
 *  Specifies what implementation of event handler should be used if
 *  gateway is acting as events receiver. basic - a simple event
 *  handler listening on a single mcast address.  complex -
 *  event handler listening on multiple mcast addresses based on
 *  events of interest to consumers.  udp - similar to basic handler,
 *  except listens on udp address as opposed to a multicast group.
 *
 * -ECGTTL <ttl>
 *  Valid values: a number > 0
 *  IP_Multicast time to live value that should be set on a sending socket.
 *  This option matters only if the gateway is acting as a sender of
 *  mcast messages.
 *
 * -ECGNIC <nic>
 *  Valid values: name of the network interface
 *  This interface is used for sending and/or receiving multicast messages.
 *
 * -ECGNonBlocking
 *  Boolean flag to configure if the socket is in blocking or
 *  non-blocking code.  The default is non-blocking.
 *  NOTE: Certain device drivers block the process if the physical
 *        link fails.
 *
 * 2) Create an instance of TAO_ECG_Mcast_Gateway in your code, on the stack or
 *    dynamically, and use init () method to configure it.  No
 *    configuration files involved.  See service config options above for the
 *    description of configurable options, and init() method below for how
 *    to specify them.
 *
 * Default configuration values (for either use case) can be found in
 * ECG_Defaults.h
 */
class TAO_RTEvent_Serv_Export TAO_ECG_Mcast_Gateway
  : public ACE_Service_Object
{
public:

  /// The Service_Object entry points.
  //@{
  virtual int init (int argc, ACE_TCHAR* argv[]);
  virtual int fini (void);
  //@}

  /// Helper function to register the Gateway into the service
  /// configurator.
  static int init_svcs (void);

  /// Constructor.
  TAO_ECG_Mcast_Gateway (void);

  /// Values for some configuration parameters to init ().
  //@{
  enum Service_Type {ECG_MCAST_SENDER,
                     ECG_MCAST_RECEIVER,
                     ECG_MCAST_TWO_WAY};

  enum Address_Server_Type {ECG_ADDRESS_SERVER_BASIC,
                            ECG_ADDRESS_SERVER_SOURCE,
                            ECG_ADDRESS_SERVER_TYPE};

  enum Handler_Type {ECG_HANDLER_BASIC,
                     ECG_HANDLER_COMPLEX,
                     ECG_HANDLER_UDP};
  //@}

  /**
   * @struct Attributes
   *
   * @brief Helper class to initialize a TAO_ECG_Mcast_Gateway.
   *
   * The TAO_ECG_Mcast_Gateway class has several properties that can
   * be configured at initialization time, with default values.  The
   * canonical trick of using a constructor or init() method with
   * multiple arguments does not work because to change the last
   * argument the application developer needs to know all the other
   * defaults.
   *
   * Instead we define a helper class that initializes all the fields
   * to reasonable defaults.  The application only sets the fields
   * that it is interested into, if new fields are added applications
   * do not need to change.
   *
   * With a little trickery we can even eliminate named temporaries:
   *
   * TAO_ECG_Mcast_Gateway gw;<BR>
   * gw.init(TAO_ECG_Mcast_Gateway::Attributes().set_foo(x).set_bar(y));
   *
   * but we are not implementing that one (detecting errors is too
   * hard without exceptions and ACE+TAO are somewhat shy of
   * exceptions at this point.)
   */
  struct TAO_RTEvent_Serv_Export Attributes
  {
    Attributes (void);

    Address_Server_Type address_server_type;
    Handler_Type handler_type;
    Service_Type service_type;
    u_char ttl_value;
    ACE_CString nic;
    int ip_multicast_loop;
    int non_blocking;
  };

  /// Configure TAO_ECG_Mcast_Gateway programatically.  This method should
  /// be used when NOT using service configurator to obtain/configure
  /// TAO_ECG_Mcast_Gateway.  See class documentation above for more
  /// info.
  int init (const char * address_server_arg,
            const Attributes & attributes = Attributes());

  /// Same as the method above, but also gives the client an opportunity to
  /// specify consumer qos, i.e., which EC traffic should get multicasted.
  /*
   * By default, multicast sender subscribes to all events in the
   * Event Channel, i.e., all events pushed to the EC get multicasted
   * (as long as their ttl is > 0).  This method allows clients to
   * specify a more restrictive qos, hence limiting which EC traffic
   * gets multicasted.
   */
  int init (const RtecEventChannelAdmin::ConsumerQOS & consumer_qos,
            const char * address_server_arg,
            const Attributes & attributes = Attributes());

  /// The main method - create, configure and run federation
  /// components according to the specified configuration.
  void run (CORBA::ORB_ptr orb,
            RtecEventChannelAdmin::EventChannel_ptr ec);

private:

  /// Helpers.
  //@{
  /// Check that arguments to run() are not nil.
  void verify_args (CORBA::ORB_ptr orb,
                    RtecEventChannelAdmin::EventChannel_ptr ec);

  /// Verifies configuration values specified through init() make sense.
  int validate_configuration (void);
  //@}

  /// Allocate and initialize appropriate objects.
  //@{
  PortableServer::ServantBase *
        init_address_server (void);

  PortableServer::Servant_var<TAO_ECG_UDP_Sender>
        init_sender (RtecEventChannelAdmin::EventChannel_ptr ec,
                     RtecUDPAdmin::AddrServer_ptr address_server,
                     TAO_ECG_Refcounted_Endpoint endpoint_rptr);

  PortableServer::Servant_var<TAO_ECG_UDP_Receiver>
        init_receiver (RtecEventChannelAdmin::EventChannel_ptr ec,
                       RtecUDPAdmin::AddrServer_ptr address_server,
                       TAO_ECG_Refcounted_Endpoint endpoint_rptr);

  TAO_ECG_Refcounted_Endpoint init_endpoint (void);

  TAO_ECG_Refcounted_Handler
        init_handler (TAO_ECG_Dgram_Handler *recv,
                      RtecEventChannelAdmin::EventChannel_ptr ec,
                      ACE_Reactor * reactor);
  //@}

  /// Flags controlling configuration.
  //@{
  Service_Type service_type_;
  Handler_Type handler_type_;
  Address_Server_Type address_server_type_;
  ACE_CString address_server_arg_;
  u_char ttl_value_;
  ACE_TString nic_;
  int ip_multicast_loop_;
  int non_blocking_;

  RtecEventChannelAdmin::ConsumerQOS consumer_qos_;
  //@}
};

TAO_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "orbsvcs/Event/ECG_Mcast_Gateway.inl"
#endif /* __ACE_INLINE__ */

ACE_STATIC_SVC_DECLARE (TAO_ECG_Mcast_Gateway)
ACE_FACTORY_DECLARE (TAO_RTEvent_Serv, TAO_ECG_Mcast_Gateway)

#include /**/ "ace/post.h"
#endif /* TAO_ECG_MCAST_GATEWAY_H */