OmniEvents
|
00001 // -*- Mode: C++; -*- 00002 // Package : omniEvents 00003 // eventc.cc Created : 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 // Client to the event channel factory. Requests creation of an event 00026 // channel and registers it with the Naming service. 00027 // 00028 00029 /* 00030 $Log: eventc.cc,v $ 00031 Revision 1.4.2.2 2005/04/27 20:49:32 alextingle 00032 Merge across changes from HEAD branch (see CHANGES_262. Change version number ready for release 2.6.2. 00033 00034 Revision 1.4.2.1 2004/11/01 12:27:12 alextingle 00035 New EventChannel parameter `PullRetryPeriod_ms' supercedes `PullRetryPeriod'. 00036 The new parameter is set by `eventc -R'. The old parameter and its `-r' 00037 option still work as before, for backwards compatibility. 00038 00039 Revision 1.4 2004/10/08 09:06:19 alextingle 00040 More robust exception minor code handling. 00041 00042 Revision 1.3 2004/08/06 16:16:40 alextingle 00043 Simplified call to ORB_init(). 00044 00045 Revision 1.2 2004/08/04 21:52:52 alextingle 00046 'n' & 'N' options now take a full name path. No more 'k' or 'K' options. 00047 00048 Revision 1.1 2004/05/31 10:29:37 alextingle 00049 New 'tools' directory. Contains useful command line tools that previously lived in the 'examples' directory. 00050 00051 Revision 1.14 2004/05/28 10:38:23 alextingle 00052 Now uses new omniEvents.idl header. Properly this time! 00053 00054 Revision 1.13 2004/05/28 10:16:54 alextingle 00055 Now uses new omniEvents.idl header. 00056 00057 Revision 1.12 2004/04/30 17:48:02 alextingle 00058 New 'real time push' feature: -t option. 00059 00060 Revision 1.11 2004/04/21 10:23:46 alextingle 00061 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. 00062 00063 Revision 1.10 2004/04/20 16:51:59 alextingle 00064 All examples updated for latest version on omniEvents. Server may now be 00065 specified as a 'corbaloc' string or IOR, instead of as naming service id/kind. 00066 00067 Revision 1.9 2004/03/28 00:58:05 alextingle 00068 New options. -c sets CyclePeriod_ns. -i sets the Channel's InsName. 00069 00070 Revision 1.8 2004/03/26 16:06:30 alextingle 00071 Added verbose (-v) option that prints the new channel's IOR to standard out. 00072 00073 Revision 1.7 2004/02/20 17:41:40 alextingle 00074 Moved 'endl;' to the actual end!! 00075 00076 Revision 1.6 2004/02/20 14:01:54 alextingle 00077 New param: -p sets MaxNumProxies for omniEvents 2.5+. 00078 No longer sends parameters that are not explicitly set on 00079 the command line. This leaves the server to decide upon 00080 default values. 00081 00082 Revision 1.5 2004/02/04 22:29:55 alextingle 00083 Reworked all C++ examples. 00084 Removed catch(...) as it tends to make it harder to see what's going on. 00085 Now uses POA instead of BOA. 00086 Uses omniORB4's Exception name probing. 00087 No longer uses 'naming.h/cc' utility code. 00088 00089 Revision 1.4 2003/12/21 11:12:01 alextingle 00090 Most exceptions are now caught by a unified catch block. 00091 00092 Revision 1.3 2003/11/03 22:21:21 alextingle 00093 Removed all platform specific switches. Now uses autoconf, config.h. 00094 Removed stub header in order to allow makefile dependency checking to work 00095 correctly. 00096 00097 Revision 1.1.1.1.2.1 2002/09/28 22:20:51 shamus13 00098 Added ifdefs to enable omniEvents to compile 00099 with both omniORB3 and omniORB4. If __OMNIORB4__ 00100 is defined during compilation, omniORB4 headers 00101 and command line option syntax is used, otherwise 00102 fall back to omniORB3 style. 00103 00104 Revision 1.1.1.1 2002/09/25 19:00:25 shamus13 00105 Import of OmniEvents source tree from release 2.1.1 00106 00107 Revision 1.6 2000/09/05 01:05:38 naderp 00108 Added MaxQueueLength QOS. 00109 00110 Revision 1.5 2000/08/30 04:39:20 naderp 00111 Port to omniORB 3.0.1. 00112 00113 Revision 1.4 2000/03/16 05:34:30 naderp 00114 Added stdlib.h for solaris getopt() 00115 00116 Revision 1.3 2000/03/16 02:44:13 naderp 00117 Added iostream and signal headers. 00118 00119 Revision 1.2 2000/03/06 13:23:50 naderp 00120 Using util getRootNamingContext function. 00121 Using stub headers. 00122 00123 Revision 1.1 1999/11/01 20:37:42 naderp 00124 Updated usage statement. 00125 00126 Revision 1.0 99/11/01 17:05:13 17:05:13 naderp (Paul Nader) 00127 omniEvents 2.0. 00128 Added -m switch to support MaxEventsPerConsumer criteria. 00129 00130 Revision 0.6 99/08/27 11:48:22 11:48:22 naderp (Paul Nader) 00131 Partitioned EventChannelFactory_i from CosEvent_i. 00132 00133 Revision 0.5 99/05/10 11:27:50 11:27:50 naderp (Paul Nader) 00134 Initialised rootContext. 00135 00136 Revision 0.4 99/04/23 16:02:22 16:02:22 naderp (Paul Nader) 00137 gcc port. 00138 00139 Revision 0.3 99/04/23 09:32:58 09:32:58 naderp (Paul Nader) 00140 Windows Port. 00141 00142 Revision 0.2 99/04/21 18:06:23 18:06:23 naderp (Paul Nader) 00143 *** empty log message *** 00144 00145 Revision 0.1.1.1 98/11/27 17:01:51 17:01:51 naderp (Paul Nader) 00146 Enclosed supports call in try block to avoid core dump. 00147 Added information messages for exceptions. 00148 00149 Revision 0.1 98/11/25 14:07:22 14:07:22 naderp (Paul Nader) 00150 Initial Revision 00151 00152 */ 00153 00154 // 00155 // 00156 00157 #ifdef HAVE_CONFIG_H 00158 # include "config.h" 00159 #endif 00160 00161 #ifdef HAVE_GETOPT 00162 # include <unistd.h> 00163 extern char* optarg; 00164 extern int optind; 00165 #else 00166 # include "getopt.h" 00167 #endif 00168 00169 #ifdef HAVE_IOSTREAM 00170 # include <iostream> 00171 #else 00172 # include <iostream.h> 00173 #endif 00174 00175 #ifdef HAVE_STD_IOSTREAM 00176 using namespace std; 00177 #endif 00178 00179 #ifdef HAVE_STDLIB_H 00180 # include <stdlib.h> 00181 #endif 00182 00183 #ifdef HAVE_SIGNAL_H 00184 # include <signal.h> 00185 #endif 00186 00187 #include <cstdio> 00188 00189 #include "omniEvents.hh" 00190 #include "naming.h" 00191 00192 static void usage(int argc, char **argv); 00193 static void appendCriterion( CosLifeCycle::Criteria&,const char*,const char*); 00194 static void appendCriterionStr(CosLifeCycle::Criteria&,const char*,const char*); 00195 00196 int 00197 main(int argc, char **argv) 00198 { 00199 int result =1; 00200 00201 // 00202 // Start orb. 00203 CORBA::ORB_var orb = CORBA::ORB_init(argc,argv); 00204 00205 // Process Options 00206 bool verbose =false; 00207 bool needNameService =false; 00208 const char* channelName ="EventChannel"; 00209 const char* factoryName ="EventChannelFactory"; 00210 CosLifeCycle::Criteria criteria; 00211 00212 int c; 00213 while ((c = getopt(argc,argv,"n:N:m:c:i:p:q:R:r:t:vh")) != EOF) 00214 { 00215 switch (c) 00216 { 00217 case 'n': 00218 channelName=optarg; 00219 needNameService=true; 00220 break; 00221 00222 case 'N': 00223 factoryName=optarg; 00224 break; 00225 00226 case 'm': // OLD OPTION 00227 appendCriterion(criteria,"MaxEventsPerConsumer",optarg); 00228 break; 00229 00230 case 'c': 00231 appendCriterion(criteria,"CyclePeriod_ns",optarg); 00232 break; 00233 00234 case 'i': 00235 appendCriterionStr(criteria,"InsName",optarg); 00236 break; 00237 00238 case 'p': 00239 appendCriterion(criteria,"MaxNumProxies",optarg); 00240 break; 00241 00242 case 'q': 00243 appendCriterion(criteria,"MaxQueueLength",optarg); 00244 break; 00245 00246 case 'R': 00247 appendCriterion(criteria,"PullRetryPeriod_ms",optarg); 00248 break; 00249 00250 case 'r': // This option is deprecated in favour of -R: 00251 appendCriterion(criteria,"PullRetryPeriod",optarg); 00252 break; 00253 00254 case 't': 00255 appendCriterionStr(criteria,"FilterId",optarg); 00256 break; 00257 00258 case 'v': 00259 verbose=true; 00260 break; 00261 00262 case 'h': 00263 usage(argc,argv); 00264 exit(0); 00265 00266 default : 00267 usage(argc,argv); 00268 exit(-1); 00269 } 00270 } 00271 // Need the naming service to find the factory if there is no URI argument. 00272 needNameService=(needNameService || optind>=argc); 00273 00274 // 00275 // Use one big try...catch block. 00276 // 'action' variable keeps track of what we're doing. 00277 const char* action ="start"; 00278 try 00279 { 00280 CORBA::Object_var obj; 00281 00282 // 00283 // Get Name Service root context.(we can carry on without it though) 00284 CosNaming::NamingContext_var rootContext=CosNaming::NamingContext::_nil(); 00285 try { 00286 action="resolve initial reference 'NameService'"; 00287 obj=orb->resolve_initial_references("NameService"); 00288 rootContext=CosNaming::NamingContext::_narrow(obj); 00289 if(CORBA::is_nil(rootContext)) 00290 throw CORBA::OBJECT_NOT_EXIST(); 00291 } 00292 catch (CORBA::Exception& ex) { 00293 if(needNameService) 00294 throw; 00295 else 00296 cerr<<"Warning - failed to "<<action<<"."<<endl; 00297 } 00298 00299 // 00300 // Obtain reference to the Event Channel Factory implementation. 00301 // (from command-line argument or from the Naming Service). 00302 if(optind<argc) 00303 { 00304 action="convert URI from command line into object reference"; 00305 obj=orb->string_to_object(argv[optind]); 00306 } 00307 else 00308 { 00309 action="find Event Channel Factory in naming service"; 00310 obj=rootContext->resolve(str2name(factoryName)); 00311 } 00312 00313 action="narrow object reference to event channel factory"; 00314 omniEvents::EventChannelFactory_var factory = 00315 omniEvents::EventChannelFactory::_narrow(obj); 00316 if(CORBA::is_nil(factory)) 00317 { 00318 cerr << "Failed to narrow Event Channel Factory reference." << endl; 00319 exit(1); 00320 } 00321 00322 // Check that the factory is of the right type 00323 action="check factory supports EventChannel object interface"; 00324 CosLifeCycle::Key key; 00325 key.length (1); 00326 key[0].id = CORBA::string_dup("EventChannel"); 00327 key[0].kind = CORBA::string_dup("object interface"); 00328 00329 if(!factory->supports(key)) 00330 { 00331 cerr << "Factory does not support Event Channel Interface! [\"" 00332 << factoryName << "\"]" << endl; 00333 exit(1); 00334 } 00335 00336 // 00337 // Create Event Channel Object. 00338 action="create EventChannel object"; 00339 CORBA::Object_var channelObj =factory->create_object(key, criteria); 00340 if (CORBA::is_nil(channelObj)) 00341 { 00342 cerr << "Channel Factory returned nil reference! [\"" 00343 << channelName << "\"]" << endl; 00344 exit(1); 00345 } 00346 00347 // Narrow object returned to an Event Channel 00348 CosEventChannelAdmin::EventChannel_var channel = 00349 CosEventChannelAdmin::EventChannel::_narrow(channelObj); 00350 if (CORBA::is_nil(channel)) 00351 { 00352 cerr << "Failed to narrow Event Channel! [\"" 00353 << channelName << "\"]" << endl; 00354 exit(1); 00355 } 00356 00357 // Print the new EventChannel's IOR to standard output. 00358 if(verbose) 00359 { 00360 CORBA::String_var sior =orb->object_to_string(channel); 00361 cout<<sior.in()<<endl; 00362 } 00363 00364 // 00365 // Register event channel with naming service 00366 if(!CORBA::is_nil(rootContext)) 00367 { 00368 CosNaming::Name name =str2name(channelName); 00369 try{ 00370 action="register (bind) EventChannel with the naming service"; 00371 rootContext->bind(name,channel.in()); 00372 } 00373 catch(CosNaming::NamingContext::AlreadyBound& ex) { 00374 action="register (rebind) EventChannel with the naming service"; 00375 rootContext->rebind(name,channel.in()); 00376 } 00377 } 00378 00379 // 00380 // Clean up nicely. 00381 action="destroy orb"; 00382 orb->destroy(); 00383 00384 // 00385 // If we get here, then everything has worked OK. 00386 result=0; 00387 00388 } 00389 catch (CosLifeCycle::NoFactory& ex) /* create_object() */ { 00390 cerr<<"Failed to create Event Channel: NoFactory" 00391 " (interface not supported) "<<endl; 00392 } 00393 catch (CosLifeCycle::CannotMeetCriteria& ex) /* create_object() */ { 00394 cerr<<"Failed to create Event Channel: CannotMeetCriteria "<<endl; 00395 } 00396 catch (CosLifeCycle::InvalidCriteria& ex) /* create_object() */ { 00397 cerr<<"Failed to create Event Channel: InvalidCriteria "<<endl; 00398 } 00399 catch (CORBA::COMM_FAILURE& ex) { 00400 cerr<<"System exception, unable to "<<action<<": COMM_FAILURE"<<endl; 00401 } 00402 catch (CORBA::SystemException& ex) { 00403 cerr<<"System exception, unable to "<<action; 00404 #if defined(HAVE_OMNIORB4) 00405 cerr<<" "<<ex._name(); 00406 if(ex.NP_minorString()) 00407 cerr<<" ("<<ex.NP_minorString()<<")"; 00408 #endif 00409 cerr<<endl; 00410 } 00411 catch (CORBA::Exception& ex) { 00412 cerr<<"CORBA exception, unable to "<<action 00413 #ifdef HAVE_OMNIORB4 00414 <<": "<<ex._name() 00415 #endif 00416 << endl; 00417 } 00418 catch (omniORB::fatalException& ex) { 00419 cerr<<"Fatal Exception, unable to "<<action<<endl; 00420 } 00421 00422 return result; 00423 } 00424 00425 static void 00426 usage(int argc, char **argv) 00427 { 00428 cerr<< 00429 "\nCreate an EventChannel and register it in the naming service.\n" 00430 "syntax: "<<(argc?argv[0]:"eventc")<<" OPTIONS [FACTORY_URI]\n" 00431 "\n" 00432 "FACTORY_URI: The factory may be specified as a URI.\n" 00433 " This may be an IOR, or a corbaloc::: or corbaname::: URI.\n" 00434 " For example: corbaloc::localhost:11169/omniEvents\n" 00435 "\n" 00436 "OPTIONS: DEFAULT:\n" 00437 " -n channel name [\"EventChannel\"]\n" 00438 " -N factory name (if URI is not specified) [\"EventChannelFactory\"]\n" 00439 " -c override default CyclePeriod_ns of new channel (nanoseconds)\n" 00440 " -i set the InsName of new channel, to enable access via corbaloc\n" 00441 " -p override default MaxNumProxies of new channel\n" 00442 " -q override default MaxQueueLength of new channel\n" 00443 " -R override default PullRetryPeriod_ms for new channel (milliseconds)\n" 00444 " -t set an event type filter, FilterId=<RepositoryId>\n" 00445 " -v print the IOR of the new EventChannel to standard output.\n" 00446 " -h display this help text\n" 00447 "OLD OPTIONS: (only used by omniEvents v2.4 and earlier)\n" 00448 " -m override default MaxEventsPerConsumer for new channel\n" << endl; 00449 } 00450 00451 static void appendCriterion( 00452 CosLifeCycle::Criteria& criteria, 00453 const char* name, 00454 const char* value 00455 ) 00456 { 00457 CORBA::ULong criteriaLen =criteria.length(); 00458 ++criteriaLen; 00459 criteria.length(criteriaLen); 00460 criteria[criteriaLen-1].name=CORBA::string_dup(name); 00461 criteria[criteriaLen-1].value<<=CORBA::ULong(atol(value)); 00462 } 00463 00464 static void appendCriterionStr( 00465 CosLifeCycle::Criteria& criteria, 00466 const char* name, 00467 const char* value 00468 ) 00469 { 00470 CORBA::ULong criteriaLen =criteria.length(); 00471 ++criteriaLen; 00472 criteria.length(criteriaLen); 00473 criteria[criteriaLen-1].name=CORBA::string_dup(name); 00474 criteria[criteriaLen-1].value<<=value; 00475 }