Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

pullcons.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; -*-
00002 //                            Package   : omniEvents
00003 // pullcons.cc                Created on: 1/4/98
00004 //                            Author    : Paul Nader (pwn)
00005 //
00006 //    Copyright (C) 1998 Paul Nader.
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 //    Pull Model consumer implementation.
00026 //      
00027 
00028 /*
00029   $Log: pullcons.cc,v $
00030   Revision 1.3  2003/11/03 22:20:54  alextingle
00031   Removed all platform specific switches. Now uses autoconf, config.h.
00032   Removed stub header in order to allow makefile dependency checking to work
00033   correctly.
00034   Changed int to bool where appropriate.
00035 
00036   Revision 1.1.1.1.2.1  2002/09/28 22:20:51  shamus13
00037   Added ifdefs to enable omniEvents to compile
00038   with both omniORB3 and omniORB4. If __OMNIORB4__
00039   is defined during compilation, omniORB4 headers
00040   and command line option syntax is used, otherwise
00041   fall back to omniORB3 style.
00042 
00043   Revision 1.1.1.1  2002/09/25 19:00:25  shamus13
00044   Import of OmniEvents source tree from release 2.1.1
00045 
00046   Revision 0.11  2000/10/11 01:16:21  naderp
00047   *** empty log message ***
00048 
00049   Revision 0.10  2000/08/30 04:39:48  naderp
00050   Port to omniORB 3.0.1.
00051 
00052   Revision 0.9  2000/03/16 05:37:27  naderp
00053   Added stdlib.h for getopt.
00054 
00055   Revision 0.8  2000/03/06 13:25:44  naderp
00056   Using util getRootNamingContext function.
00057   Using stub headers.
00058   Fixed error messages.
00059 
00060   Revision 0.7  2000/03/02 02:11:27  naderp
00061   Added -r option to connect using nil reference.
00062   Added retry resiliency for handling COMM_FAUILURE exceptions.
00063 
00064   Revision 0.6  1999/11/02 13:38:57  naderp
00065   Added <signal.h>
00066 
00067   Revision 0.5  1999/11/01 15:55:11  naderp
00068   omniEvents 2.0 Release.
00069   Ignoring SIGPIPE for UNIX platforms.
00070 
00071 Revision 0.4  99/04/23  16:05:38  16:05:38  naderp (Paul Nader)
00072 gcc port.
00073 
00074 Revision 0.3  99/04/23  09:33:40  09:33:40  naderp (Paul Nader)
00075 Windows Port.
00076 
00077 Revision 0.2  99/04/21  18:06:25  18:06:25  naderp (Paul Nader)
00078 *** empty log message ***
00079 
00080 Revision 0.1.1.1  98/11/27  16:59:07  16:59:07  naderp (Paul Nader)
00081 Added -s option to sleep after disconnecting.
00082 
00083 Revision 0.1  98/11/25  14:08:04  14:08:04  naderp (Paul Nader)
00084 Initial Revision
00085 
00086 */
00087 
00088 #ifdef HAVE_CONFIG_H
00089 #  include "config.h"
00090 #endif
00091 
00092 #ifdef HAVE_GETOPT
00093 #  include <unistd.h>
00094 extern char* optarg;
00095 extern int optind;
00096 #else
00097 #  include "getopt.h"
00098 #endif
00099 
00100 #ifdef HAVE_IOSTREAM
00101 #  include <iostream>
00102 #else
00103 #  include <iostream.h>
00104 #endif
00105 
00106 #ifdef HAVE_STD_IOSTREAM
00107 using namespace std;
00108 #endif
00109 
00110 #ifdef HAVE_STDLIB_H
00111 #  include <stdlib.h>
00112 #endif
00113 
00114 #ifdef HAVE_SIGNAL_H
00115 #  include <signal.h>
00116 #endif
00117 
00118 #include "naming.h"
00119 
00120 #include "CosEventComm.hh"
00121 #include "CosEventChannelAdmin.hh"
00122 
00123 static void usage();
00124 
00125 class Consumer_i : virtual public CosEventComm::_sk_PullConsumer {
00126 public:
00127   Consumer_i () {};
00128   void disconnect_pull_consumer ();
00129 };
00130 
00131 void Consumer_i::disconnect_pull_consumer () {
00132   cout << "EventConsumer: disconnected." << endl;
00133 }
00134 
00135 int
00136 main(int argc, char **argv)
00137 {
00138   //
00139   // Start orb and boa.
00140 #if defined(HAVE_OMNIORB4)
00141   CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB4");
00142   CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB4_BOA");
00143 #else
00144   CORBA::ORB_ptr orb = CORBA::ORB_init(argc,argv,"omniORB3");
00145   CORBA::BOA_ptr boa = orb->BOA_init(argc,argv,"omniORB3_BOA");
00146 #endif
00147 
00148   // Process Options
00149   int c;
00150   bool trymode = false;
00151   int discnum = 0;
00152   bool refnil = false;
00153   int sleepInterval = 0;
00154   char *channelName = (char *) "EventChannel";
00155   char *channelKind = (char *) "EventChannel";
00156   while ((c = getopt(argc,argv,"td:rs:n:k:h")) != EOF)
00157   {
00158      switch (c)
00159      {
00160         case 't': trymode = true;
00161                   break;
00162 
00163         case 'd': discnum = atoi(optarg);
00164                   break;
00165 
00166         case 'r': refnil = true;
00167                   break;
00168 
00169         case 's': sleepInterval = atoi(optarg);
00170                   break;
00171 
00172         case 'n': channelName = optarg;
00173                   break;
00174 
00175         case 'k': channelKind = optarg;
00176                   break;
00177 
00178         case 'h':
00179         default : usage();
00180                   exit(-1);
00181                   break;
00182      }
00183   }
00184   
00185 #ifdef HAVE_SIGNAL_H
00186   // Ignore broken pipes
00187   signal(SIGPIPE, SIG_IGN);
00188 #endif
00189 
00190   Consumer_i* consumer = new Consumer_i ();
00191   consumer->_obj_is_ready(boa);
00192 
00193   // A Pull Consumer can be implemented as a pure client or as a mixed
00194   // client-server process, depending on whether it requires and is
00195   // prepared to service disconnect requests from the channel.
00196   // If its is then let the BOA know we are ready without blocking.
00197   if (! refnil)
00198   {
00199      boa->impl_is_ready(0,1);
00200   }
00201 
00202   //
00203   // Obtain and narrow reference to Name Service.
00204   CosNaming::NamingContext_ptr rootContext;
00205   rootContext = getRootNamingContext(orb);
00206 
00207   // Obtain Event Channel Object.
00208   CosNaming::Name name;
00209   name.length (1);
00210   name[0].id = CORBA::string_dup (channelName);
00211   name[0].kind = CORBA::string_dup (channelKind);
00212 
00213   cout << "Looking for EventChannel" << endl;
00214   CosEventChannelAdmin::EventChannel_var channel;
00215   try {
00216     CORBA::Object_var obj = rootContext->resolve(name);
00217     channel = CosEventChannelAdmin::EventChannel::_narrow(obj);
00218     if (CORBA::is_nil(channel))
00219     {
00220        cerr << "Failed to narrow Event Channel reference !" << endl;
00221        exit(1);
00222     }
00223   }
00224   catch (CORBA::ORB::InvalidName& ex) {
00225      cerr << "Service required is invalid [does not exist]. !" << endl;
00226      exit(1);
00227   }
00228   catch (CORBA::COMM_FAILURE& ex) {
00229      cerr << "Caught system exception COMM_FAILURE, unable to contact the "
00230           << "naming service !" << endl;
00231      exit(1);
00232   }
00233   catch (omniORB::fatalException& ex) {
00234      cerr << "Caught Fatal Exception !" << endl;
00235      throw;
00236   }
00237   catch (...) {
00238      cerr << "Cannot find event channel ! [\""
00239           << channelName << "\", \"" << channelKind << "\"]"
00240           << endl;
00241      exit (1);
00242   }
00243 
00244   //
00245   // Get Consumer admin interface - retrying on Comms Failure.
00246   CosEventChannelAdmin::ConsumerAdmin_var consumer_admin;
00247   while (1)
00248   {
00249      try {
00250         consumer_admin = channel->for_consumers ();
00251         if (CORBA::is_nil (consumer_admin))
00252         {
00253            cerr << "Event Channel returned nil Consumer Admin !."
00254                 << endl;
00255            exit (1);
00256         }
00257         break;
00258      }
00259      catch (CORBA::COMM_FAILURE& ex) {
00260         cerr << "Caught COMM_FAILURE Exception "
00261              << "obtaining COnsumer Admin !. Retrying..."
00262              << endl;
00263         continue;
00264      }
00265      catch (...) {
00266         cerr << "Unexpected System Exception. "
00267              << "Failed to obtain Consumer Admin !."
00268              << endl;
00269         exit(1);
00270      }
00271   }
00272   cerr << "Obtained Consumer Admin." << endl;
00273 
00274   while (1)
00275   {
00276      //
00277      // Get proxy supplier - retrying on Comms Failure.
00278      CosEventChannelAdmin::ProxyPullSupplier_var proxy_supplier;
00279      while (1)
00280      {
00281         try {
00282            proxy_supplier = consumer_admin->obtain_pull_supplier ();
00283            if (CORBA::is_nil (proxy_supplier))
00284            {
00285               cerr << "Consumer Admin returned nil Proxy Supplier !."
00286                    << endl;
00287               exit (1);
00288            }
00289            break;
00290         }
00291         catch (CORBA::COMM_FAILURE& ex) {
00292            cerr << "Caught COMM_FAILURE Exception "
00293                 << "obtaining Pull Supplier !. Retrying..."
00294                 << endl;
00295            continue;
00296         }
00297         catch (...) {
00298            cerr << "Unexpected System Exception. "
00299                 << "Failed to obtain Proxy Supplier !"
00300                 << endl;
00301            exit (1);
00302         }
00303      }
00304      cerr << "Obtained ProxyPullSupplier." << endl;
00305    
00306      //
00307      // Connect Pull Consumer - retrying on Comms Failure.
00308      CosEventComm::PullConsumer_ptr cptr;
00309      cptr = consumer->_this();
00310      cptr = (! refnil) ? CosEventComm::PullConsumer::_duplicate(cptr)
00311                        : CosEventComm::PullConsumer::_nil();
00312      while (1)
00313      {
00314         try {
00315            proxy_supplier->connect_pull_consumer(cptr);
00316            break;
00317         }
00318         catch (CORBA::BAD_PARAM& ex) {
00319            cerr << "Caught BAD_PARAM Exception connecting Pull Consumer !"
00320                 << endl;
00321            exit (1);
00322         }
00323         catch (CosEventChannelAdmin::AlreadyConnected& ex) {
00324            cerr << "Pull Consumer already connected !" 
00325                 << endl;
00326            break;
00327         }
00328         catch (CORBA::COMM_FAILURE& ex) {
00329            cerr << "Caught COMM_FAILURE Exception "
00330                 << "connecting Pull Consumer !. Retrying..." 
00331                 << endl;
00332            continue;
00333         }
00334         catch (...) {
00335            cerr << "Unexpected System Exception."
00336                 << "Failed to connect Pull Consumer !"
00337                 << endl;
00338            exit (1);
00339         }
00340      }
00341      cerr << "Connected Pull Consumer." << endl;
00342 
00343      // Pull data.
00344      CORBA::Any *data;
00345      CORBA::ULong l = 0;
00346      for (int i=0; (discnum == 0) || (i < discnum); i++)
00347      {
00348         if (!trymode)
00349         {
00350            try {
00351                cout << "Pull Consumer: pull () called. ";
00352                data = proxy_supplier->pull();
00353                l = 0;
00354                *data >>= l;
00355                cout << "Data : " << l << endl;
00356                delete data;
00357            }
00358            catch (CosEventComm::Disconnected& ex) {
00359               cerr << "Failed. Caught Disconnected Exception !" 
00360                    << endl;
00361            }
00362            catch (CORBA::COMM_FAILURE& ex) {
00363               cerr << "Failed. Caught COMM_FAILURE Exception !" 
00364                    << endl;
00365            }
00366            catch (...)
00367            {
00368                cerr << "Failed. Caught Unknown Exception !" << endl;
00369            }
00370         }
00371         else
00372         {
00373            try {
00374                CORBA::Boolean has_event;
00375                data = proxy_supplier->try_pull(has_event);
00376                cout << "Consumer: try_pull () called. Data : " << flush;
00377                if (has_event)
00378                {
00379                   l = 0;
00380                   *data >>= l;
00381                   cout << l << endl;
00382                   delete data;
00383                }
00384                else
00385                {
00386                   cout << "No Data" << endl;
00387    
00388                }
00389            }
00390            catch (CosEventComm::Disconnected& ex) {
00391               cerr << "Failed. Caught Disconnected Exception !" 
00392                    << endl;
00393            }
00394            catch (CORBA::COMM_FAILURE& ex) {
00395               cerr << "Failed. Caught COMM_FAILURE Exception !" 
00396                    << endl;
00397            }
00398            catch (...)
00399            {
00400                cerr << "Failed. Caught Unknown Exception !" << endl;
00401            }
00402         }
00403      }
00404 
00405      // Disconnect - retrying on Comms Failure.
00406      while (1)
00407      {
00408         try {
00409            proxy_supplier->disconnect_pull_supplier();
00410            break;
00411         }
00412         catch (CORBA::COMM_FAILURE& ex) {
00413            cerr << "Caught COMM_FAILURE exception "
00414                 << "disconnecting Pull Consumer !. Retrying..." 
00415                 << endl;
00416            continue;
00417         }
00418         catch (...) {
00419            cerr << "Unexpected System Exception."
00420                 << "Failed to disconnect Pull Consumer !."
00421                 << endl;
00422            exit(1);
00423         }
00424      }
00425      cerr << "Disconnected Pull Consumer." << endl;
00426 
00427      // Yawn
00428      cerr << "Sleeping " << sleepInterval << " Seconds." << endl;
00429      omni_thread::sleep(sleepInterval);
00430   }
00431 
00432   // Not Reached
00433   return 0;
00434 }
00435 
00436 static void
00437 usage()
00438 {
00439    cerr << "\nusage: pullcons [-t] [-d n [-s n]] [-n name] [-k kind] [-h]\n" << endl;
00440    cerr << "         -t      enable try_pull mode" << endl;
00441    cerr << "         -r      connect using nil reference" << endl;
00442    cerr << "         -d n    disconnect after n pulls" << endl;
00443    cerr << "         -s n    sleep n Seconds after disconnecting " << endl;
00444    cerr << "         -n name specify channel name [\"EventChannel\"]" << endl;
00445    cerr << "         -k kind specify channel kind [\"EventChannel\"]" << endl;
00446    cerr << "         -h     display usage" << endl;
00447    cerr << endl;
00448 }

Generated on Fri Dec 12 10:53:03 2003 for OmniEvents by doxygen1.2.15