OmniEvents
eventc.cc
Go to the documentation of this file.
1 // -*- Mode: C++; -*-
2 // Package : omniEvents
3 // eventc.cc Created : 1/4/98
4 // Author : Paul Nader (pwn)
5 //
6 // Copyright (C) 1998 Paul Nader.
7 //
8 // This file is part of the omniEvents application.
9 //
10 // omniEvents is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // omniEvents is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 //
24 // Description:
25 // Client to the event channel factory. Requests creation of an event
26 // channel and registers it with the Naming service.
27 //
28 
29 /*
30  $Log: eventc.cc,v $
31  Revision 1.4.2.2 2005/04/27 20:49:32 alextingle
32  Merge across changes from HEAD branch (see CHANGES_262. Change version number ready for release 2.6.2.
33 
34  Revision 1.4.2.1 2004/11/01 12:27:12 alextingle
35  New EventChannel parameter `PullRetryPeriod_ms' supercedes `PullRetryPeriod'.
36  The new parameter is set by `eventc -R'. The old parameter and its `-r'
37  option still work as before, for backwards compatibility.
38 
39  Revision 1.4 2004/10/08 09:06:19 alextingle
40  More robust exception minor code handling.
41 
42  Revision 1.3 2004/08/06 16:16:40 alextingle
43  Simplified call to ORB_init().
44 
45  Revision 1.2 2004/08/04 21:52:52 alextingle
46  'n' & 'N' options now take a full name path. No more 'k' or 'K' options.
47 
48  Revision 1.1 2004/05/31 10:29:37 alextingle
49  New 'tools' directory. Contains useful command line tools that previously lived in the 'examples' directory.
50 
51  Revision 1.14 2004/05/28 10:38:23 alextingle
52  Now uses new omniEvents.idl header. Properly this time!
53 
54  Revision 1.13 2004/05/28 10:16:54 alextingle
55  Now uses new omniEvents.idl header.
56 
57  Revision 1.12 2004/04/30 17:48:02 alextingle
58  New 'real time push' feature: -t option.
59 
60  Revision 1.11 2004/04/21 10:23:46 alextingle
61  If there is no Naming Service, eventc only issues a warning unless it is needed to find the factory, or options -n or -k are set.
62 
63  Revision 1.10 2004/04/20 16:51:59 alextingle
64  All examples updated for latest version on omniEvents. Server may now be
65  specified as a 'corbaloc' string or IOR, instead of as naming service id/kind.
66 
67  Revision 1.9 2004/03/28 00:58:05 alextingle
68  New options. -c sets CyclePeriod_ns. -i sets the Channel's InsName.
69 
70  Revision 1.8 2004/03/26 16:06:30 alextingle
71  Added verbose (-v) option that prints the new channel's IOR to standard out.
72 
73  Revision 1.7 2004/02/20 17:41:40 alextingle
74  Moved 'endl;' to the actual end!!
75 
76  Revision 1.6 2004/02/20 14:01:54 alextingle
77  New param: -p sets MaxNumProxies for omniEvents 2.5+.
78  No longer sends parameters that are not explicitly set on
79  the command line. This leaves the server to decide upon
80  default values.
81 
82  Revision 1.5 2004/02/04 22:29:55 alextingle
83  Reworked all C++ examples.
84  Removed catch(...) as it tends to make it harder to see what's going on.
85  Now uses POA instead of BOA.
86  Uses omniORB4's Exception name probing.
87  No longer uses 'naming.h/cc' utility code.
88 
89  Revision 1.4 2003/12/21 11:12:01 alextingle
90  Most exceptions are now caught by a unified catch block.
91 
92  Revision 1.3 2003/11/03 22:21:21 alextingle
93  Removed all platform specific switches. Now uses autoconf, config.h.
94  Removed stub header in order to allow makefile dependency checking to work
95  correctly.
96 
97  Revision 1.1.1.1.2.1 2002/09/28 22:20:51 shamus13
98  Added ifdefs to enable omniEvents to compile
99  with both omniORB3 and omniORB4. If __OMNIORB4__
100  is defined during compilation, omniORB4 headers
101  and command line option syntax is used, otherwise
102  fall back to omniORB3 style.
103 
104  Revision 1.1.1.1 2002/09/25 19:00:25 shamus13
105  Import of OmniEvents source tree from release 2.1.1
106 
107  Revision 1.6 2000/09/05 01:05:38 naderp
108  Added MaxQueueLength QOS.
109 
110  Revision 1.5 2000/08/30 04:39:20 naderp
111  Port to omniORB 3.0.1.
112 
113  Revision 1.4 2000/03/16 05:34:30 naderp
114  Added stdlib.h for solaris getopt()
115 
116  Revision 1.3 2000/03/16 02:44:13 naderp
117  Added iostream and signal headers.
118 
119  Revision 1.2 2000/03/06 13:23:50 naderp
120  Using util getRootNamingContext function.
121  Using stub headers.
122 
123  Revision 1.1 1999/11/01 20:37:42 naderp
124  Updated usage statement.
125 
126 Revision 1.0 99/11/01 17:05:13 17:05:13 naderp (Paul Nader)
127 omniEvents 2.0.
128 Added -m switch to support MaxEventsPerConsumer criteria.
129 
130 Revision 0.6 99/08/27 11:48:22 11:48:22 naderp (Paul Nader)
131 Partitioned EventChannelFactory_i from CosEvent_i.
132 
133 Revision 0.5 99/05/10 11:27:50 11:27:50 naderp (Paul Nader)
134 Initialised rootContext.
135 
136 Revision 0.4 99/04/23 16:02:22 16:02:22 naderp (Paul Nader)
137 gcc port.
138 
139 Revision 0.3 99/04/23 09:32:58 09:32:58 naderp (Paul Nader)
140 Windows Port.
141 
142 Revision 0.2 99/04/21 18:06:23 18:06:23 naderp (Paul Nader)
143 *** empty log message ***
144 
145 Revision 0.1.1.1 98/11/27 17:01:51 17:01:51 naderp (Paul Nader)
146 Enclosed supports call in try block to avoid core dump.
147 Added information messages for exceptions.
148 
149 Revision 0.1 98/11/25 14:07:22 14:07:22 naderp (Paul Nader)
150 Initial Revision
151 
152 */
153 
154 //
155 //
156 
157 #ifdef HAVE_CONFIG_H
158 # include "config.h"
159 #endif
160 
161 #ifdef HAVE_GETOPT
162 # include <unistd.h>
163 extern char* optarg;
164 extern int optind;
165 #else
166 # include "getopt.h"
167 #endif
168 
169 #ifdef HAVE_IOSTREAM
170 # include <iostream>
171 #else
172 # include <iostream.h>
173 #endif
174 
175 #ifdef HAVE_STD_IOSTREAM
176 using namespace std;
177 #endif
178 
179 #ifdef HAVE_STDLIB_H
180 # include <stdlib.h>
181 #endif
182 
183 #ifdef HAVE_SIGNAL_H
184 # include <signal.h>
185 #endif
186 
187 #include <cstdio>
188 
189 #include "omniEvents.hh"
190 #include "naming.h"
191 
192 static void usage(int argc, char **argv);
193 static void appendCriterion( CosLifeCycle::Criteria&,const char*,const char*);
194 static void appendCriterionStr(CosLifeCycle::Criteria&,const char*,const char*);
195 
196 int
197 main(int argc, char **argv)
198 {
199  int result =1;
200 
201  //
202  // Start orb.
203  CORBA::ORB_var orb = CORBA::ORB_init(argc,argv);
204 
205  // Process Options
206  bool verbose =false;
207  bool needNameService =false;
208  const char* channelName ="EventChannel";
209  const char* factoryName ="EventChannelFactory";
210  CosLifeCycle::Criteria criteria;
211 
212  int c;
213  while ((c = getopt(argc,argv,"n:N:m:c:i:p:q:R:r:t:vh")) != EOF)
214  {
215  switch (c)
216  {
217  case 'n':
218  channelName=optarg;
219  needNameService=true;
220  break;
221 
222  case 'N':
223  factoryName=optarg;
224  break;
225 
226  case 'm': // OLD OPTION
227  appendCriterion(criteria,"MaxEventsPerConsumer",optarg);
228  break;
229 
230  case 'c':
231  appendCriterion(criteria,"CyclePeriod_ns",optarg);
232  break;
233 
234  case 'i':
235  appendCriterionStr(criteria,"InsName",optarg);
236  break;
237 
238  case 'p':
239  appendCriterion(criteria,"MaxNumProxies",optarg);
240  break;
241 
242  case 'q':
243  appendCriterion(criteria,"MaxQueueLength",optarg);
244  break;
245 
246  case 'R':
247  appendCriterion(criteria,"PullRetryPeriod_ms",optarg);
248  break;
249 
250  case 'r': // This option is deprecated in favour of -R:
251  appendCriterion(criteria,"PullRetryPeriod",optarg);
252  break;
253 
254  case 't':
255  appendCriterionStr(criteria,"FilterId",optarg);
256  break;
257 
258  case 'v':
259  verbose=true;
260  break;
261 
262  case 'h':
263  usage(argc,argv);
264  exit(0);
265 
266  default :
267  usage(argc,argv);
268  exit(-1);
269  }
270  }
271  // Need the naming service to find the factory if there is no URI argument.
272  needNameService=(needNameService || optind>=argc);
273 
274  //
275  // Use one big try...catch block.
276  // 'action' variable keeps track of what we're doing.
277  const char* action ="start";
278  try
279  {
280  CORBA::Object_var obj;
281 
282  //
283  // Get Name Service root context.(we can carry on without it though)
284  CosNaming::NamingContext_var rootContext=CosNaming::NamingContext::_nil();
285  try {
286  action="resolve initial reference 'NameService'";
287  obj=orb->resolve_initial_references("NameService");
288  rootContext=CosNaming::NamingContext::_narrow(obj);
289  if(CORBA::is_nil(rootContext))
290  throw CORBA::OBJECT_NOT_EXIST();
291  }
292  catch (CORBA::Exception& ex) {
293  if(needNameService)
294  throw;
295  else
296  cerr<<"Warning - failed to "<<action<<"."<<endl;
297  }
298 
299  //
300  // Obtain reference to the Event Channel Factory implementation.
301  // (from command-line argument or from the Naming Service).
302  if(optind<argc)
303  {
304  action="convert URI from command line into object reference";
305  obj=orb->string_to_object(argv[optind]);
306  }
307  else
308  {
309  action="find Event Channel Factory in naming service";
310  obj=rootContext->resolve(str2name(factoryName));
311  }
312 
313  action="narrow object reference to event channel factory";
314  omniEvents::EventChannelFactory_var factory =
315  omniEvents::EventChannelFactory::_narrow(obj);
316  if(CORBA::is_nil(factory))
317  {
318  cerr << "Failed to narrow Event Channel Factory reference." << endl;
319  exit(1);
320  }
321 
322  // Check that the factory is of the right type
323  action="check factory supports EventChannel object interface";
324  CosLifeCycle::Key key;
325  key.length (1);
326  key[0].id = CORBA::string_dup("EventChannel");
327  key[0].kind = CORBA::string_dup("object interface");
328 
329  if(!factory->supports(key))
330  {
331  cerr << "Factory does not support Event Channel Interface! [\""
332  << factoryName << "\"]" << endl;
333  exit(1);
334  }
335 
336  //
337  // Create Event Channel Object.
338  action="create EventChannel object";
339  CORBA::Object_var channelObj =factory->create_object(key, criteria);
340  if (CORBA::is_nil(channelObj))
341  {
342  cerr << "Channel Factory returned nil reference! [\""
343  << channelName << "\"]" << endl;
344  exit(1);
345  }
346 
347  // Narrow object returned to an Event Channel
348  CosEventChannelAdmin::EventChannel_var channel =
349  CosEventChannelAdmin::EventChannel::_narrow(channelObj);
350  if (CORBA::is_nil(channel))
351  {
352  cerr << "Failed to narrow Event Channel! [\""
353  << channelName << "\"]" << endl;
354  exit(1);
355  }
356 
357  // Print the new EventChannel's IOR to standard output.
358  if(verbose)
359  {
360  CORBA::String_var sior =orb->object_to_string(channel);
361  cout<<sior.in()<<endl;
362  }
363 
364  //
365  // Register event channel with naming service
366  if(!CORBA::is_nil(rootContext))
367  {
368  CosNaming::Name name =str2name(channelName);
369  try{
370  action="register (bind) EventChannel with the naming service";
371  rootContext->bind(name,channel.in());
372  }
373  catch(CosNaming::NamingContext::AlreadyBound& ex) {
374  action="register (rebind) EventChannel with the naming service";
375  rootContext->rebind(name,channel.in());
376  }
377  }
378 
379  //
380  // Clean up nicely.
381  action="destroy orb";
382  orb->destroy();
383 
384  //
385  // If we get here, then everything has worked OK.
386  result=0;
387 
388  }
389  catch (CosLifeCycle::NoFactory& ex) /* create_object() */ {
390  cerr<<"Failed to create Event Channel: NoFactory"
391  " (interface not supported) "<<endl;
392  }
393  catch (CosLifeCycle::CannotMeetCriteria& ex) /* create_object() */ {
394  cerr<<"Failed to create Event Channel: CannotMeetCriteria "<<endl;
395  }
396  catch (CosLifeCycle::InvalidCriteria& ex) /* create_object() */ {
397  cerr<<"Failed to create Event Channel: InvalidCriteria "<<endl;
398  }
399  catch (CORBA::COMM_FAILURE& ex) {
400  cerr<<"System exception, unable to "<<action<<": COMM_FAILURE"<<endl;
401  }
402  catch (CORBA::SystemException& ex) {
403  cerr<<"System exception, unable to "<<action;
404 #if defined(HAVE_OMNIORB4)
405  cerr<<" "<<ex._name();
406  if(ex.NP_minorString())
407  cerr<<" ("<<ex.NP_minorString()<<")";
408 #endif
409  cerr<<endl;
410  }
411  catch (CORBA::Exception& ex) {
412  cerr<<"CORBA exception, unable to "<<action
413 #ifdef HAVE_OMNIORB4
414  <<": "<<ex._name()
415 #endif
416  << endl;
417  }
418  catch (omniORB::fatalException& ex) {
419  cerr<<"Fatal Exception, unable to "<<action<<endl;
420  }
421 
422  return result;
423 }
424 
425 static void
426 usage(int argc, char **argv)
427 {
428  cerr<<
429 "\nCreate an EventChannel and register it in the naming service.\n"
430 "syntax: "<<(argc?argv[0]:"eventc")<<" OPTIONS [FACTORY_URI]\n"
431 "\n"
432 "FACTORY_URI: The factory may be specified as a URI.\n"
433 " This may be an IOR, or a corbaloc::: or corbaname::: URI.\n"
434 " For example: corbaloc::localhost:11169/omniEvents\n"
435 "\n"
436 "OPTIONS: DEFAULT:\n"
437 " -n channel name [\"EventChannel\"]\n"
438 " -N factory name (if URI is not specified) [\"EventChannelFactory\"]\n"
439 " -c override default CyclePeriod_ns of new channel (nanoseconds)\n"
440 " -i set the InsName of new channel, to enable access via corbaloc\n"
441 " -p override default MaxNumProxies of new channel\n"
442 " -q override default MaxQueueLength of new channel\n"
443 " -R override default PullRetryPeriod_ms for new channel (milliseconds)\n"
444 " -t set an event type filter, FilterId=<RepositoryId>\n"
445 " -v print the IOR of the new EventChannel to standard output.\n"
446 " -h display this help text\n"
447 "OLD OPTIONS: (only used by omniEvents v2.4 and earlier)\n"
448 " -m override default MaxEventsPerConsumer for new channel\n" << endl;
449 }
450 
451 static void appendCriterion(
452  CosLifeCycle::Criteria& criteria,
453  const char* name,
454  const char* value
455 )
456 {
457  CORBA::ULong criteriaLen =criteria.length();
458  ++criteriaLen;
459  criteria.length(criteriaLen);
460  criteria[criteriaLen-1].name=CORBA::string_dup(name);
461  criteria[criteriaLen-1].value<<=CORBA::ULong(atol(value));
462 }
463 
464 static void appendCriterionStr(
465  CosLifeCycle::Criteria& criteria,
466  const char* name,
467  const char* value
468 )
469 {
470  CORBA::ULong criteriaLen =criteria.length();
471  ++criteriaLen;
472  criteria.length(criteriaLen);
473  criteria[criteriaLen-1].name=CORBA::string_dup(name);
474  criteria[criteriaLen-1].value<<=value;
475 }
int optind
Definition: getopt.cc:82
char * optarg
Definition: getopt.cc:83
int getopt(int argc, char *argv[], const char *optionS)
Definition: getopt.cc:88
CosNaming::Name str2name(const char *namestr)
Converts stringified name to naming service name.
Definition: naming.cc:117
static void appendCriterion(CosLifeCycle::Criteria &, const char *, const char *)
Definition: eventc.cc:451
int main(int argc, char **argv)
The main process entry point.
Definition: eventc.cc:197
static void appendCriterionStr(CosLifeCycle::Criteria &, const char *, const char *)
Definition: eventc.cc:464
static void usage(int argc, char **argv)
Definition: eventc.cc:426
CORBA::ORB_ptr orb
Definition: eventf.cc:60