OmniEvents
pushsupp.cc
Go to the documentation of this file.
1// -*- Mode: C++; -*-
2// Package : omniEvents
3// pushsupp.cc Created on: 1/4/98
4// Author : Paul Nader (pwn)
5//
6// Copyright (C) 1998 Paul Nader, 2003-2004 Alex Tingle
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// Push Model supplier implementation.
26//
27
28/*
29 $Log: pushsupp.cc,v $
30 Revision 1.10 2004/10/08 09:06:08 alextingle
31 More robust exception minor code handling.
32
33 Revision 1.9 2004/08/18 17:49:45 alextingle
34 Added check for SIGPIPE before trying to use it.
35
36 Revision 1.8 2004/08/06 16:19:23 alextingle
37 -k & -K options removed.
38 Naming service names may now be as complex as you like.
39
40 Revision 1.7 2004/04/20 16:52:17 alextingle
41 All examples updated for latest version on omniEvents. Server may now be
42 specified as a 'corbaloc' string or IOR, instead of as naming service id/kind.
43
44 Revision 1.6 2004/03/23 19:09:26 alextingle
45 Fixed typos.
46
47 Revision 1.5 2004/02/21 19:07:45 alextingle
48 Corrected servants to use POA instead of BOA.
49
50 Revision 1.4 2004/02/04 22:29:55 alextingle
51 Reworked all C++ examples.
52 Removed catch(...) as it tends to make it harder to see what's going on.
53 Now uses POA instead of BOA.
54 Uses omniORB4's Exception name probing.
55 No longer uses 'naming.h/cc' utility code.
56
57 Revision 1.3 2003/11/03 22:19:25 alextingle
58 Removed all platform specific switches. Now uses autoconf, config.h.
59 Removed stub header in order to allow makefile dependency checking to work
60 correctly.
61 Changed int to bool where appropriate.
62
63 Revision 1.1.1.1.2.1 2002/09/28 22:20:51 shamus13
64 Added ifdefs to enable omniEvents to compile
65 with both omniORB3 and omniORB4. If __OMNIORB4__
66 is defined during compilation, omniORB4 headers
67 and command line option syntax is used, otherwise
68 fall back to omniORB3 style.
69
70 Revision 1.1.1.1 2002/09/25 19:00:26 shamus13
71 Import of OmniEvents source tree from release 2.1.1
72
73 Revision 0.14 2000/10/11 01:16:21 naderp
74 *** empty log message ***
75
76 Revision 0.13 2000/08/30 04:39:48 naderp
77 Port to omniORB 3.0.1.
78
79 Revision 0.12 2000/03/16 05:37:27 naderp
80 Added stdlib.h for getopt.
81
82 Revision 0.11 2000/03/06 13:27:10 naderp
83 Using util getRootNamingContext function.
84 Using stub headers.
85 Fixed error messages.
86
87 Revision 0.10 2000/03/02 03:21:20 naderp
88 Added -r option to connect using nil reference.
89 Added retry resiliency for handling COMM_FAUILURE exceptions.
90
91Revision 0.9 99/11/02 13:39:17 13:39:17 naderp (Paul Nader)
92Added <signal.h>
93
94 Revision 0.8 1999/11/02 07:57:18 naderp
95 Updated usage.
96
97Revision 0.7 99/11/01 19:22:43 19:22:43 naderp (Paul Nader)
98Added catch for COMM_FAILURE exception in obtain_push_consumer
99and disconnect_push_consumer calls.
100
101Revision 0.6 99/11/01 16:12:03 16:12:03 naderp (Paul Nader)
102omniEvents 2.0 Release.
103
104Revision 0.5 99/10/27 19:42:31 19:42:31 naderp (Paul Nader)
105Ignoring Unix SIGPIPE signal.
106Reporting sleep beforhand.
107
108Revision 0.4 99/04/23 16:05:47 16:05:47 naderp (Paul Nader)
109gcc port.
110
111Revision 0.3 99/04/23 09:34:04 09:34:04 naderp (Paul Nader)
112Windows Port.
113
114Revision 0.2 99/04/21 18:06:26 18:06:26 naderp (Paul Nader)
115*** empty log message ***
116
117Revision 0.1.1.1 98/11/27 16:59:40 16:59:40 naderp (Paul Nader)
118Added -s option to sleep after disconnecting.
119
120Revision 0.1 98/11/25 14:08:25 14:08:25 naderp (Paul Nader)
121Initial Revision
122
123*/
124
125#ifdef HAVE_CONFIG_H
126# include "config.h"
127#endif
128
129#ifdef HAVE_GETOPT
130# include <unistd.h>
131extern char* optarg;
132extern int optind;
133#else
134# include "getopt.h"
135#endif
136
137#ifdef HAVE_IOSTREAM
138# include <iostream>
139#else
140# include <iostream.h>
141#endif
142
143#ifdef HAVE_STD_IOSTREAM
144using namespace std;
145#endif
146
147#ifdef HAVE_STDLIB_H
148# include <stdlib.h>
149#endif
150
151#ifdef HAVE_SIGNAL_H
152# include <signal.h>
153#endif
154
155#include <cstdio>
156
157#include "CosEventComm.hh"
158#include "CosEventChannelAdmin.hh"
159#include "naming.h"
160
161static void usage(int argc, char **argv);
162
163class Supplier_i : virtual public POA_CosEventComm::PushSupplier {
164public:
167};
168
169void
171 cout << "Push Supplier: disconnected." << endl;
172}
173
174int main (int argc, char** argv)
175{
176 long l = 0;
177 CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv);
178
179 // Process Options
180 int discnum =0;
181 bool refnil =false;
182 int sleepInterval =0;
183 const char* channelName ="EventChannel";
184
185 int c;
186 while ((c = getopt(argc,argv,"d:rs:n:h")) != EOF)
187 {
188 switch (c)
189 {
190 case 'd': discnum = atoi(optarg);
191 break;
192
193 case 'r': refnil = true;
194 break;
195
196 case 's': sleepInterval = atoi(optarg);
197 break;
198
199 case 'n': channelName = optarg;
200 break;
201
202 case 'h':
203 default : usage(argc,argv);
204 exit(-1);
205 break;
206 }
207 }
208
209#if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
210 // Ignore broken pipes
211 signal(SIGPIPE, SIG_IGN);
212#endif
213
214 Supplier_i* supplier = NULL;
215 CosEventChannelAdmin::EventChannel_var channel;
216
217 const char* action=""; // Use this variable to help report errors.
218 try {
219 CORBA::Object_var obj;
220
221 // A Push Supplier can be implemented as a pure client or as a mixed
222 // client-server process, depending on whether it requires and is
223 // prepared to service disconnect requests from the channel.
224 // If it is then create the servant object and activate the POA.
225 if(!refnil)
226 {
227 supplier=new Supplier_i();
228
229 action="resolve initial reference 'RootPOA'";
230 obj=orb->resolve_initial_references("RootPOA");
231 PortableServer::POA_var rootPoa =PortableServer::POA::_narrow(obj);
232 if(CORBA::is_nil(rootPoa))
233 throw CORBA::OBJECT_NOT_EXIST();
234
235 action="activate the RootPOA's POAManager";
236 PortableServer::POAManager_var pman =rootPoa->the_POAManager();
237 pman->activate();
238 }
239
240 //
241 // Obtain object reference to EventChannel
242 // (from command-line argument or from the Naming Service).
243 if(optind<argc)
244 {
245 action="convert URI from command line into object reference";
246 obj=orb->string_to_object(argv[optind]);
247 }
248 else
249 {
250 action="resolve initial reference 'NameService'";
251 obj=orb->resolve_initial_references("NameService");
252 CosNaming::NamingContext_var rootContext=
253 CosNaming::NamingContext::_narrow(obj);
254 if(CORBA::is_nil(rootContext))
255 throw CORBA::OBJECT_NOT_EXIST();
256
257 action="find EventChannel in NameService";
258 cout << action << endl;
259 obj=rootContext->resolve(str2name(channelName));
260 }
261
262 action="narrow object reference to event channel";
263 channel=CosEventChannelAdmin::EventChannel::_narrow(obj);
264 if(CORBA::is_nil(channel))
265 {
266 cerr << "Failed to narrow Event Channel reference." << endl;
267 exit(1);
268 }
269
270 }
271 catch(CORBA::ORB::InvalidName& ex) { // resolve_initial_references
272 cerr<<"Failed to "<<action<<". ORB::InvalidName"<<endl;
273 exit(1);
274 }
275 catch(CosNaming::NamingContext::InvalidName& ex) { // resolve
276 cerr<<"Failed to "<<action<<". NamingContext::InvalidName"<<endl;
277 exit(1);
278 }
279 catch(CosNaming::NamingContext::NotFound& ex) { // resolve
280 cerr<<"Failed to "<<action<<". NamingContext::NotFound"<<endl;
281 exit(1);
282 }
283 catch(CosNaming::NamingContext::CannotProceed& ex) { // resolve
284 cerr<<"Failed to "<<action<<". NamingContext::CannotProceed"<<endl;
285 exit(1);
286 }
287 catch(CORBA::TRANSIENT& ex) { // _narrow()
288 cerr<<"Failed to "<<action<<". TRANSIENT"<<endl;
289 exit(1);
290 }
291 catch(CORBA::OBJECT_NOT_EXIST& ex) { // _narrow()
292 cerr<<"Failed to "<<action<<". OBJECT_NOT_EXIST"<<endl;
293 exit(1);
294 }
295 catch(CORBA::SystemException& ex) {
296 cerr<<"Failed to "<<action<<".";
297#if defined(HAVE_OMNIORB4)
298 cerr<<" "<<ex._name();
299 if(ex.NP_minorString())
300 cerr<<" ("<<ex.NP_minorString()<<")";
301#endif
302 cerr<<endl;
303 exit(1);
304 }
305 catch(CORBA::Exception& ex) {
306 cerr<<"Failed to "<<action<<"."
307#if defined(HAVE_OMNIORB4)
308 " "<<ex._name()
309#endif
310 <<endl;
311 exit(1);
312 }
313
314 //
315 // Get Supplier Admin interface - retrying on Comms Failure.
316 CosEventChannelAdmin::SupplierAdmin_var supplier_admin;
317 while (1)
318 {
319 try {
320 supplier_admin = channel->for_suppliers ();
321 if (CORBA::is_nil(supplier_admin))
322 {
323 cerr << "Event Channel returned nil Supplier Admin!"
324 << endl;
325 exit(1);
326 }
327 break;
328 }
329 catch (CORBA::COMM_FAILURE& ex) {
330 cerr << "Caught COMM_FAILURE Exception "
331 << "obtaining Supplier Admin! Retrying..."
332 << endl;
333 continue;
334 }
335 }
336 cout << "Obtained SupplierAdmin." << endl;
337
338 while (1)
339 {
340 //
341 // Get proxy consumer - retrying on Comms Failure.
342 CosEventChannelAdmin::ProxyPushConsumer_var proxy_consumer;
343 while (1)
344 {
345 try {
346 proxy_consumer = supplier_admin->obtain_push_consumer ();
347 if (CORBA::is_nil(proxy_consumer))
348 {
349 cerr << "Supplier Admin returned nil proxy_consumer!"<< endl;
350 exit(1);
351 }
352 break;
353 }
354 catch (CORBA::COMM_FAILURE& ex) {
355 cerr << "Caught COMM_FAILURE Exception "
356 << "obtaining Proxy Push Consumer! Retrying..."
357 << endl;
358 continue;
359 }
360 }
361 cout << "Obtained ProxyPushConsumer." << endl;
362
363 //
364 // Connect Push Supplier - retrying on Comms Failure.
365 CosEventComm::PushSupplier_var sptr =CosEventComm::PushSupplier::_nil();
366 if (! refnil) {
367 sptr = supplier->_this();
368 }
369
370 while (1)
371 {
372 try {
373 proxy_consumer->connect_push_supplier(sptr.in());
374 break;
375 }
376 catch (CORBA::BAD_PARAM& ex) {
377 cerr << "Caught BAD_PARAM Exception connecting Push Supplier!"
378 << endl;
379 exit (1);
380 }
381 catch (CosEventChannelAdmin::AlreadyConnected& ex) {
382 cerr << "Proxy Push Consumer already connected!"
383 << endl;
384 break;
385 }
386 catch (CORBA::COMM_FAILURE& ex) {
387 cerr << "Caught COMM_FAILURE Exception "
388 << "connecting Push Supplier! Retrying..."
389 << endl;
390 continue;
391 }
392 }
393 cout << "Connected Push Supplier." << endl;
394
395 // Push data.
396 for (int i=0; (discnum == 0) || (i < discnum); i++)
397 {
398 CORBA::Any any;
399 any <<= (CORBA::ULong) l++;
400 try {
401 cout << "Push Supplier: push() called. " << flush;
402 proxy_consumer->push(any);
403 cout << "Data : " << l-1 << endl;
404 }
405 catch(CosEventComm::Disconnected&) {
406 cout << "Failed. Caught Disconnected Exception!" << endl;
407 }
408 catch(CORBA::COMM_FAILURE&) {
409 cout << "Failed. Caught COMM_FAILURE Exception!" << endl;
410 }
411 }
412
413 // Disconnect - retrying on Comms Failure.
414 while (1)
415 {
416 try {
417 proxy_consumer->disconnect_push_consumer();
418 break;
419 }
420 catch (CORBA::COMM_FAILURE& ex) {
421 cerr << "Caught COMM_FAILURE Exception "
422 << "disconnecting Push Supplier! Retrying..."
423 << endl;
424 continue;
425 }
426 }
427 cout << "ProxyPushConsumer disconnected." << endl;
428
429 // Yawn.
430 cout << "Sleeping " << sleepInterval << " seconds." << endl;
431 omni_thread::sleep(sleepInterval);
432 }
433
434 // Not Reached
435 return 0;
436}
437
438static void
439usage(int argc, char **argv)
440{
441 cerr<<
442"\nCreate a PushSupplier to send events to a channel.\n"
443"syntax: "<<(argc?argv[0]:"pushsupp")<<" OPTIONS [CHANNEL_URI]\n"
444"\n"
445"CHANNEL_URI: The event channel may be specified as a URI.\n"
446" This may be an IOR, or a corbaloc::: or corbaname::: URI.\n"
447"\n"
448"OPTIONS: DEFAULT:\n"
449" -d NUM disconnect after sending NUM events [0 - never disconnect]\n"
450" -r connect using a nil reference\n"
451" -s SECS sleep SECS seconds after disconnecting [0]\n"
452" -n NAME channel name (if URI is not specified) [\"EventChannel\"]\n"
453" -h display this help text\n" << endl;
454}
CosNaming::Name str2name(const char *namestr)
Converts stringified name to naming service name.
Definition naming.cc:117
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
CORBA::ORB_ptr orb
Definition eventf.cc:60
int main(int argc, char **argv)
The main process entry point.
Definition pushsupp.cc:174
static void usage(int argc, char **argv)
Definition pushsupp.cc:439
void disconnect_push_supplier()