Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

pushsupp.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; -*-
00002 //                            Package   : omniEvents
00003 //   pushsupp.cc              Created on: 1/4/98
00004 //                            Author    : Paul Nader (pwn)
00005 //
00006 //    Copyright (C) 1998 Paul Nader, 2003-2004 Alex Tingle
00007 //
00008 //    This file is part of the omnievents application.
00009 //
00010 //    omniEvents is free software; you can redistribute it and/or
00011 //    modify it under the terms of the GNU Lesser General Public
00012 //    License as published by the Free Software Foundation; either
00013 //    version 2.1 of the License, or (at your option) any later version.
00014 //
00015 //    omniEvents is distributed in the hope that it will be useful,
00016 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 //    Lesser General Public License for more details.
00019 //
00020 //    You should have received a copy of the GNU Lesser General Public
00021 //    License along with this library; if not, write to the Free Software
00022 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // Description:
00025 //    Push Model supplier implementation.
00026 //      
00027 
00028 /*
00029   $Log: pushsupp.cc,v $
00030   Revision 1.10  2004/10/08 09:06:08  alextingle
00031   More robust exception minor code handling.
00032 
00033   Revision 1.9  2004/08/18 17:49:45  alextingle
00034   Added check for SIGPIPE before trying to use it.
00035 
00036   Revision 1.8  2004/08/06 16:19:23  alextingle
00037   -k & -K options removed.
00038   Naming service names may now be as complex as you like.
00039 
00040   Revision 1.7  2004/04/20 16:52:17  alextingle
00041   All examples updated for latest version on omniEvents. Server may now be
00042   specified as a 'corbaloc' string or IOR, instead of as naming service id/kind.
00043 
00044   Revision 1.6  2004/03/23 19:09:26  alextingle
00045   Fixed typos.
00046 
00047   Revision 1.5  2004/02/21 19:07:45  alextingle
00048   Corrected servants to use POA instead of BOA.
00049 
00050   Revision 1.4  2004/02/04 22:29:55  alextingle
00051   Reworked all C++ examples.
00052   Removed catch(...) as it tends to make it harder to see what's going on.
00053   Now uses POA instead of BOA.
00054   Uses omniORB4's Exception name probing.
00055   No longer uses 'naming.h/cc' utility code.
00056 
00057   Revision 1.3  2003/11/03 22:19:25  alextingle
00058   Removed all platform specific switches. Now uses autoconf, config.h.
00059   Removed stub header in order to allow makefile dependency checking to work
00060   correctly.
00061   Changed int to bool where appropriate.
00062 
00063   Revision 1.1.1.1.2.1  2002/09/28 22:20:51  shamus13
00064   Added ifdefs to enable omniEvents to compile
00065   with both omniORB3 and omniORB4. If __OMNIORB4__
00066   is defined during compilation, omniORB4 headers
00067   and command line option syntax is used, otherwise
00068   fall back to omniORB3 style.
00069 
00070   Revision 1.1.1.1  2002/09/25 19:00:26  shamus13
00071   Import of OmniEvents source tree from release 2.1.1
00072 
00073   Revision 0.14  2000/10/11 01:16:21  naderp
00074   *** empty log message ***
00075 
00076   Revision 0.13  2000/08/30 04:39:48  naderp
00077   Port to omniORB 3.0.1.
00078 
00079   Revision 0.12  2000/03/16 05:37:27  naderp
00080   Added stdlib.h for getopt.
00081 
00082   Revision 0.11  2000/03/06 13:27:10  naderp
00083   Using util getRootNamingContext function.
00084   Using stub headers.
00085   Fixed error messages.
00086 
00087   Revision 0.10  2000/03/02 03:21:20  naderp
00088   Added -r option to connect using nil reference.
00089   Added retry resiliency for handling COMM_FAUILURE exceptions.
00090 
00091 Revision 0.9  99/11/02  13:39:17  13:39:17  naderp (Paul Nader)
00092 Added <signal.h>
00093 
00094   Revision 0.8  1999/11/02 07:57:18  naderp
00095   Updated usage.
00096 
00097 Revision 0.7  99/11/01  19:22:43  19:22:43  naderp (Paul Nader)
00098 Added catch for COMM_FAILURE exception in obtain_push_consumer
00099 and disconnect_push_consumer calls.
00100 
00101 Revision 0.6  99/11/01  16:12:03  16:12:03  naderp (Paul Nader)
00102 omniEvents 2.0 Release.
00103 
00104 Revision 0.5  99/10/27  19:42:31  19:42:31  naderp (Paul Nader)
00105 Ignoring Unix SIGPIPE signal.
00106 Reporting sleep beforhand.
00107 
00108 Revision 0.4  99/04/23  16:05:47  16:05:47  naderp (Paul Nader)
00109 gcc port.
00110 
00111 Revision 0.3  99/04/23  09:34:04  09:34:04  naderp (Paul Nader)
00112 Windows Port.
00113 
00114 Revision 0.2  99/04/21  18:06:26  18:06:26  naderp (Paul Nader)
00115 *** empty log message ***
00116 
00117 Revision 0.1.1.1  98/11/27  16:59:40  16:59:40  naderp (Paul Nader)
00118 Added -s option to sleep after disconnecting.
00119 
00120 Revision 0.1  98/11/25  14:08:25  14:08:25  naderp (Paul Nader)
00121 Initial Revision
00122 
00123 */
00124 
00125 #ifdef HAVE_CONFIG_H
00126 #  include "config.h"
00127 #endif
00128 
00129 #ifdef HAVE_GETOPT
00130 #  include <unistd.h>
00131 extern char* optarg;
00132 extern int optind;
00133 #else
00134 #  include "getopt.h"
00135 #endif
00136 
00137 #ifdef HAVE_IOSTREAM
00138 #  include <iostream>
00139 #else
00140 #  include <iostream.h>
00141 #endif
00142 
00143 #ifdef HAVE_STD_IOSTREAM
00144 using namespace std;
00145 #endif
00146 
00147 #ifdef HAVE_STDLIB_H
00148 #  include <stdlib.h>
00149 #endif
00150 
00151 #ifdef HAVE_SIGNAL_H
00152 #  include <signal.h>
00153 #endif
00154 
00155 #include "CosEventComm.hh"
00156 #include "CosEventChannelAdmin.hh"
00157 #include "naming.h"
00158 
00159 static void usage(int argc, char **argv);
00160 
00161 class Supplier_i : virtual public POA_CosEventComm::PushSupplier {
00162 public:
00163   Supplier_i () {};
00164   void disconnect_push_supplier ();
00165 };
00166 
00167 void
00168 Supplier_i::disconnect_push_supplier () {
00169   cout << "Push Supplier: disconnected." << endl;
00170 }
00171 
00172 int main (int argc, char** argv)
00173 {
00174   long l = 0;
00175   CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv);
00176 
00177   // Process Options
00178   int         discnum       =0;
00179   bool        refnil        =false;
00180   int         sleepInterval =0;
00181   const char* channelName   ="EventChannel";
00182 
00183   int c;
00184   while ((c = getopt(argc,argv,"d:rs:n:h")) != EOF)
00185   {
00186      switch (c)
00187      {
00188         case 'd': discnum = atoi(optarg);
00189                   break;
00190 
00191         case 'r': refnil = true;
00192                   break;
00193 
00194         case 's': sleepInterval = atoi(optarg);
00195                   break;
00196 
00197         case 'n': channelName = optarg;
00198                   break;
00199 
00200         case 'h':
00201         default : usage(argc,argv);
00202                   exit(-1);
00203                   break;
00204      }
00205   }
00206 
00207 #if defined(HAVE_SIGNAL_H) && defined(SIGPIPE)
00208   // Ignore broken pipes
00209   signal(SIGPIPE, SIG_IGN);
00210 #endif
00211 
00212   Supplier_i* supplier = NULL;
00213   CosEventChannelAdmin::EventChannel_var channel;
00214 
00215   const char* action=""; // Use this variable to help report errors.
00216   try {
00217     CORBA::Object_var obj;
00218 
00219     // A Push Supplier can be implemented as a pure client or as a mixed
00220     // client-server process, depending on whether it requires and is
00221     // prepared to service disconnect requests from the channel.
00222     // If it is then create the servant object and activate the POA.
00223     if(!refnil)
00224     {
00225       supplier=new Supplier_i();
00226 
00227       action="resolve initial reference 'RootPOA'";
00228       obj=orb->resolve_initial_references("RootPOA");
00229       PortableServer::POA_var rootPoa =PortableServer::POA::_narrow(obj);
00230       if(CORBA::is_nil(rootPoa))
00231           throw CORBA::OBJECT_NOT_EXIST();
00232 
00233       action="activate the RootPOA's POAManager";
00234       PortableServer::POAManager_var pman =rootPoa->the_POAManager();
00235       pman->activate();
00236     }
00237 
00238     //
00239     // Obtain object reference to EventChannel
00240     // (from command-line argument or from the Naming Service).
00241     if(optind<argc)
00242     {
00243       action="convert URI from command line into object reference";
00244       obj=orb->string_to_object(argv[optind]);
00245     }
00246     else
00247     {
00248       action="resolve initial reference 'NameService'";
00249       obj=orb->resolve_initial_references("NameService");
00250       CosNaming::NamingContext_var rootContext=
00251         CosNaming::NamingContext::_narrow(obj);
00252       if(CORBA::is_nil(rootContext))
00253           throw CORBA::OBJECT_NOT_EXIST();
00254 
00255       action="find EventChannel in NameService";
00256       cout << action << endl;
00257       obj=rootContext->resolve(str2name(channelName));
00258     }
00259 
00260     action="narrow object reference to event channel";
00261     channel=CosEventChannelAdmin::EventChannel::_narrow(obj);
00262     if(CORBA::is_nil(channel))
00263     {
00264        cerr << "Failed to narrow Event Channel reference." << endl;
00265        exit(1);
00266     }
00267 
00268   }
00269   catch(CORBA::ORB::InvalidName& ex) { // resolve_initial_references
00270      cerr<<"Failed to "<<action<<". ORB::InvalidName"<<endl;
00271      exit(1);
00272   }
00273   catch(CosNaming::NamingContext::InvalidName& ex) { // resolve
00274      cerr<<"Failed to "<<action<<". NamingContext::InvalidName"<<endl;
00275      exit(1);
00276   }
00277   catch(CosNaming::NamingContext::NotFound& ex) { // resolve
00278      cerr<<"Failed to "<<action<<". NamingContext::NotFound"<<endl;
00279      exit(1);
00280   }
00281   catch(CosNaming::NamingContext::CannotProceed& ex) { // resolve
00282      cerr<<"Failed to "<<action<<". NamingContext::CannotProceed"<<endl;
00283      exit(1);
00284   }
00285   catch(CORBA::TRANSIENT& ex) { // _narrow()
00286      cerr<<"Failed to "<<action<<". TRANSIENT"<<endl;
00287      exit(1);
00288   }
00289   catch(CORBA::OBJECT_NOT_EXIST& ex) { // _narrow()
00290      cerr<<"Failed to "<<action<<". OBJECT_NOT_EXIST"<<endl;
00291      exit(1);
00292   }
00293   catch(CORBA::SystemException& ex) {
00294      cerr<<"Failed to "<<action<<".";
00295 #if defined(HAVE_OMNIORB4)
00296      cerr<<" "<<ex._name();
00297      if(ex.NP_minorString())
00298          cerr<<" ("<<ex.NP_minorString()<<")";
00299 #endif
00300      cerr<<endl;
00301      exit(1);
00302   }
00303   catch(CORBA::Exception& ex) {
00304      cerr<<"Failed to "<<action<<"."
00305 #if defined(HAVE_OMNIORB4)
00306        " "<<ex._name()
00307 #endif
00308        <<endl;
00309      exit(1);
00310   }
00311 
00312   //
00313   // Get Supplier Admin interface - retrying on Comms Failure.
00314   CosEventChannelAdmin::SupplierAdmin_var supplier_admin;
00315   while (1)
00316   {
00317      try {
00318         supplier_admin = channel->for_suppliers ();
00319         if (CORBA::is_nil(supplier_admin))
00320         {
00321            cerr << "Event Channel returned nil Supplier Admin!"
00322                 << endl;
00323            exit(1);
00324         }
00325         break;
00326      }
00327      catch (CORBA::COMM_FAILURE& ex) {
00328         cerr << "Caught COMM_FAILURE Exception "
00329              << "obtaining Supplier Admin! Retrying..."
00330              << endl;
00331         continue;
00332      }
00333   }
00334   cout << "Obtained SupplierAdmin." << endl;
00335 
00336   while (1)
00337   {
00338      //
00339      // Get proxy consumer - retrying on Comms Failure.
00340      CosEventChannelAdmin::ProxyPushConsumer_var proxy_consumer;
00341      while (1)
00342      {
00343         try {
00344            proxy_consumer = supplier_admin->obtain_push_consumer ();
00345            if (CORBA::is_nil(proxy_consumer))
00346            {
00347               cerr << "Supplier Admin returned nil proxy_consumer!"<< endl;
00348               exit(1);
00349            }
00350            break;
00351         }
00352         catch (CORBA::COMM_FAILURE& ex) {
00353            cerr << "Caught COMM_FAILURE Exception "
00354                 << "obtaining Proxy Push Consumer! Retrying..."
00355                 << endl;
00356            continue;
00357         }
00358      }
00359      cout << "Obtained ProxyPushConsumer." << endl;
00360    
00361      //
00362      // Connect Push Supplier - retrying on Comms Failure.
00363      CosEventComm::PushSupplier_var sptr =CosEventComm::PushSupplier::_nil();
00364      if (! refnil) {
00365         sptr = supplier->_this();
00366      }
00367 
00368      while (1)
00369      {
00370         try {
00371            proxy_consumer->connect_push_supplier(sptr.in());
00372            break;
00373         }
00374         catch (CORBA::BAD_PARAM& ex) {
00375            cerr << "Caught BAD_PARAM Exception connecting Push Supplier!"
00376                 << endl;
00377            exit (1);
00378         }
00379         catch (CosEventChannelAdmin::AlreadyConnected& ex) {
00380            cerr << "Proxy Push Consumer already connected!"
00381                 << endl;
00382            break;
00383         }
00384         catch (CORBA::COMM_FAILURE& ex) {
00385            cerr << "Caught COMM_FAILURE Exception "
00386                 << "connecting Push Supplier! Retrying..."
00387                 << endl;
00388            continue;
00389         }
00390      }
00391      cout << "Connected Push Supplier." << endl;
00392    
00393      // Push data.
00394      for (int i=0; (discnum == 0) || (i < discnum); i++)
00395      {
00396         CORBA::Any any;
00397         any <<= (CORBA::ULong) l++;
00398         try {
00399            cout << "Push Supplier: push() called. " << flush;
00400            proxy_consumer->push(any);
00401            cout << "Data : " << l-1 << endl;
00402         }
00403         catch(CosEventComm::Disconnected&) {
00404            cout << "Failed. Caught Disconnected Exception!" << endl;
00405         }
00406         catch(CORBA::COMM_FAILURE&) {
00407            cout << "Failed. Caught COMM_FAILURE Exception!" << endl;
00408         }
00409      }
00410    
00411      // Disconnect - retrying on Comms Failure.
00412      while (1)
00413      {
00414         try {
00415            proxy_consumer->disconnect_push_consumer();
00416            break;
00417         }
00418         catch (CORBA::COMM_FAILURE& ex) {
00419            cerr << "Caught COMM_FAILURE Exception "
00420                 << "disconnecting Push Supplier! Retrying..."
00421                 << endl;
00422            continue;
00423         }
00424      }
00425      cout << "ProxyPushConsumer disconnected." << endl;
00426 
00427      // Yawn.
00428      cout << "Sleeping " << sleepInterval << " seconds." << endl;
00429      omni_thread::sleep(sleepInterval);
00430   }
00431 
00432   // Not Reached
00433   return 0;
00434 }
00435 
00436 static void
00437 usage(int argc, char **argv)
00438 {
00439   cerr<<
00440 "\nCreate a PushSupplier to send events to a channel.\n"
00441 "syntax: "<<(argc?argv[0]:"pushsupp")<<" OPTIONS [CHANNEL_URI]\n"
00442 "\n"
00443 "CHANNEL_URI: The event channel may be specified as a URI.\n"
00444 " This may be an IOR, or a corbaloc::: or corbaname::: URI.\n"
00445 "\n"
00446 "OPTIONS:                                         DEFAULT:\n"
00447 " -d NUM   disconnect after sending NUM events     [0 - never disconnect]\n"
00448 " -r       connect using a nil reference\n"
00449 " -s SECS  sleep SECS seconds after disconnecting  [0]\n"
00450 " -n NAME  channel name (if URI is not specified)  [\"EventChannel\"]\n"
00451 " -h       display this help text\n" << endl;
00452 }

Generated on Fri Aug 26 20:56:14 2005 for OmniEvents by  doxygen 1.4.3-20050530