Trading_Loader.cpp

Go to the documentation of this file.
00001 // Trading_Loader.cpp,v 1.35 2006/03/16 15:53:36 sjiang Exp
00002 
00003 //===========================================================================
00004 
00005 // LIBRARY
00006 //   libTAO_CosTrading.so
00007 //
00008 // DESCRIPTION
00009 //   This class allows for dynamically loading
00010 //   the Trading Service.
00011 //
00012 // AUTHORS
00013 //   Priyanka Gontla <pgontla@ece.uci.edu>
00014 
00015 //===========================================================================
00016 
00017 #include "orbsvcs/Trader/Trading_Loader.h"
00018 
00019 #include "tao/ORB_Core.h"
00020 #include "tao/default_ports.h"
00021 #include "tao/IORTable/IORTable.h"
00022 
00023 #include "ace/Dynamic_Service.h"
00024 #include "ace/Arg_Shifter.h"
00025 #include "ace/Argv_Type_Converter.h"
00026 #include "ace/OS_NS_unistd.h"
00027 #include "ace/os_include/os_netdb.h"
00028 
00029 ACE_RCSID (Trader, Trading_Loader, "Trading_Loader.cpp,v 1.35 2006/03/16 15:53:36 sjiang Exp")
00030 
00031 TAO_Trading_Loader::TAO_Trading_Loader (void)
00032   : federate_ (0),
00033     ior_output_file_ (0),
00034     bootstrapper_ (0)
00035 {
00036   char *trader_name = CORBA::string_alloc (MAXHOSTNAMELEN + 10);
00037 
00038   if (trader_name != 0)
00039     {
00040       // The trader name is the concatenation of the local host name
00041       // and the server's process id.
00042       char host_name[MAXHOSTNAMELEN + 1];
00043       ACE_INET_Addr localhost ((u_short) 0);
00044       if (localhost.get_host_name (host_name, sizeof (host_name)) != 0)
00045         {
00046           const char *tmp = localhost.get_host_addr ();
00047           if (tmp == 0)
00048             ACE_DEBUG ((LM_DEBUG,
00049                         ACE_TEXT ("\n\nTAO Trading Service (%P|%t) ")
00050                         ACE_TEXT ("TAO_Trading_Loader ")
00051                         ACE_TEXT ("- %p\n\n"),
00052                         ACE_TEXT ("cannot determine hostname")));
00053           else
00054             ACE_OS::strcpy (host_name, tmp);
00055         }
00056 
00057       ACE_OS::sprintf (trader_name,
00058                        "%s_%ld",
00059                        host_name,
00060                        static_cast<long> (ACE_OS::getpid ()));
00061 
00062       for (char *dot = 0;
00063            (dot = ACE_OS::strchr (trader_name, '.')) != 0;
00064            *dot = '_')
00065         continue;
00066 
00067       ACE_DEBUG ((LM_DEBUG,
00068                   "*** Trading Service %s initializing.\n",
00069                   trader_name));
00070 
00071       this->name_ = trader_name;
00072     }
00073 }
00074 
00075 TAO_Trading_Loader::~TAO_Trading_Loader (void)
00076 {
00077   // Destructor
00078 }
00079 
00080 int
00081 TAO_Trading_Loader::init (int argc, ACE_TCHAR *argv[])
00082 {
00083   ACE_DECLARE_NEW_CORBA_ENV;
00084   ACE_TRY
00085     {
00086       // Copy command line parameter.
00087       ACE_Argv_Type_Converter command_line(argc, argv);
00088 
00089       // Initialize the ORB Manager
00090       this->orb_manager_.init (command_line.get_argc(),
00091                                command_line.get_ASCII_argv()
00092                                ACE_ENV_ARG_PARAMETER);
00093       ACE_TRY_CHECK;
00094 
00095       CORBA::ORB_var orb =
00096         this->orb_manager_.orb ();
00097 
00098       // Initializes and sets up the Trading Service
00099       CORBA::Object_var object =
00100         this->create_object (orb.in (), command_line.get_argc(), command_line.get_TCHAR_argv() ACE_ENV_ARG_PARAMETER);
00101       ACE_TRY_CHECK;
00102 
00103     }
00104   ACE_CATCHANY
00105     {
00106       //    @@ Should we log this???
00107       return -1;
00108     }
00109   ACE_ENDTRY;
00110   return 0;
00111 }
00112 
00113 int
00114 TAO_Trading_Loader::fini (void)
00115 {
00116   ACE_TRY_NEW_ENV
00117     {
00118       if (this->trader_.get () != 0)
00119         {
00120           TAO_Trading_Components_i& trd_comp
00121             = this->trader_->trading_components ();
00122           CosTrading::Link_ptr our_link =
00123             trd_comp.link_if ();
00124 
00125           CosTrading::LinkNameSeq_var link_name_seq =
00126             our_link->list_links (ACE_ENV_SINGLE_ARG_PARAMETER);
00127           ACE_TRY_CHECK;
00128 
00129           ACE_DEBUG ((LM_DEBUG,
00130                       "*** Unlinking from federated traders.\n"));
00131 
00132           for (CORBA::ULong j = 0;
00133                j != link_name_seq->length ();
00134                ++j)
00135             {
00136               CORBA::ULong i =
00137                 link_name_seq->length () - j - 1;
00138 
00139               ACE_DEBUG ((LM_DEBUG,
00140                           "*** Describing the next link.\n"));
00141               CosTrading::Link::LinkInfo_var link_info =
00142                 our_link->describe_link (link_name_seq[i]
00143                                          ACE_ENV_ARG_PARAMETER);
00144               ACE_TRY_CHECK;
00145 
00146               ACE_DEBUG ((LM_DEBUG,
00147                           "*** Removing link to %s.\n",
00148                           static_cast<const char *> (link_name_seq[i])));
00149               our_link->remove_link (link_name_seq[i]
00150                                      ACE_ENV_ARG_PARAMETER);
00151               ACE_TRY_CHECK;
00152 
00153               CosTrading::Lookup_ptr remote_lookup;
00154               remote_lookup =
00155                 link_info->target.in ();
00156 
00157               ACE_DEBUG ((LM_DEBUG,
00158                           "*** Retrieving its link interface.\n"));
00159               CosTrading::Link_var remote_link =
00160                 remote_lookup->link_if (ACE_ENV_SINGLE_ARG_PARAMETER);
00161               ACE_TRY_CHECK;
00162 
00163               ACE_DEBUG ((LM_DEBUG,
00164                           "*** Removing its link to us.\n"));
00165 
00166               if (this->bootstrapper_)
00167                 {
00168                   remote_link->remove_link ("Bootstrap"
00169                                             ACE_ENV_ARG_PARAMETER);
00170                   ACE_TRY_CHECK;
00171                 }
00172               else
00173                 {
00174                   remote_link->remove_link (this->name_.in ()
00175                                             ACE_ENV_ARG_PARAMETER);
00176                   ACE_TRY_CHECK;
00177                 }
00178             }
00179         }
00180     }
00181   ACE_CATCHANY
00182     {
00183       ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, "Trading Service shutting down");
00184     }
00185   ACE_ENDTRY;
00186 
00187   return 0;
00188 }
00189 
00190 int
00191 TAO_Trading_Loader::run (ACE_ENV_SINGLE_ARG_DECL)
00192 {
00193   int return_value =
00194     this->orb_manager_.run (ACE_ENV_SINGLE_ARG_PARAMETER);
00195   ACE_CHECK_RETURN (-1);
00196 
00197   return return_value;
00198 }
00199 
00200 CORBA::Object_ptr
00201 TAO_Trading_Loader::create_object (CORBA::ORB_ptr orb_ptr,
00202                                    int argc,
00203                                    ACE_TCHAR *argv[]
00204                                    ACE_ENV_ARG_DECL)
00205   ACE_THROW_SPEC ((CORBA::SystemException))
00206 {
00207   // Duplicate the ORB
00208   CORBA::ORB_var orb = CORBA::ORB::_duplicate (orb_ptr);
00209 
00210   // Activating the poa manager
00211   this->orb_manager_.activate_poa_manager (ACE_ENV_SINGLE_ARG_PARAMETER);
00212   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00213 
00214   // Create a Trader Object and set its Service Type Repository.
00215   auto_ptr<TAO_Trader_Factory::TAO_TRADER> auto_trader (TAO_Trader_Factory::create_trader (argc, argv));
00216 
00217   this->trader_ = auto_trader;
00218 
00219   TAO_Support_Attributes_i &sup_attr =
00220     this->trader_->support_attributes ();
00221 
00222   TAO_Trading_Components_i &trd_comp =
00223     this->trader_->trading_components ();
00224 
00225   sup_attr.type_repos (this->type_repos_._this (ACE_ENV_SINGLE_ARG_PARAMETER));
00226   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00227 
00228   // The Spec says: return a reference to the Lookup interface from
00229   // the resolve_initial_references method.
00230   CosTrading::Lookup_ptr lookup =
00231     trd_comp.lookup_if ();
00232 
00233   this->ior_ =
00234     orb->object_to_string (lookup
00235                            ACE_ENV_ARG_PARAMETER);
00236   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00237 
00238   // Parse the args
00239   if (this->parse_args (argc, argv) == -1)
00240     return CORBA::Object::_nil ();
00241 
00242   // Dump the ior to a file.
00243   if (this->ior_output_file_ != 0)
00244     {
00245       ACE_OS::fprintf (this->ior_output_file_,
00246                        "%s",
00247                        this->ior_.in ());
00248       ACE_OS::fclose (this->ior_output_file_);
00249     }
00250 
00251   CORBA::Object_var table_object =
00252     orb->resolve_initial_references ("IORTable" ACE_ENV_ARG_PARAMETER);
00253   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00254 
00255   IORTable::Table_var adapter =
00256     IORTable::Table::_narrow (table_object.in () ACE_ENV_ARG_PARAMETER);
00257   ACE_CHECK_RETURN (CORBA::Object::_nil ());
00258 
00259   if (CORBA::is_nil (adapter.in ()))
00260     {
00261       ACE_ERROR ((LM_ERROR, "Nil IORTable\n"));
00262     } 
00263   else
00264     {
00265       adapter->bind ("TradingService",
00266                      this->ior_.in () ACE_ENV_ARG_PARAMETER);
00267       ACE_CHECK_RETURN (CORBA::Object::_nil ());
00268     }
00269 
00270   if (this->federate_)
00271     {
00272       // Only become a multicast server if we're the only trader
00273       // on the multicast network.
00274       // @@ Could do other things. For example, every timeout
00275       // period try to federate again, but let's not hardcode that
00276       // policy.
00277       int rc = this->bootstrap_to_federation (ACE_ENV_SINGLE_ARG_PARAMETER);
00278       ACE_CHECK_RETURN (CORBA::Object::_nil ());
00279 
00280       if (rc == -1)
00281         this->init_multicast_server ();
00282     }
00283   else
00284     this->init_multicast_server ();
00285 
00286   return CORBA::Object::_nil ();
00287 }
00288 
00289 int
00290 TAO_Trading_Loader::bootstrap_to_federation (ACE_ENV_SINGLE_ARG_DECL)
00291 {
00292   // If all traders follow this strategy, it creates a complete graph
00293   // of all known traders on a multicast network.
00294   CORBA::ORB_var orb =
00295     this->orb_manager_.orb ();
00296 
00297   ACE_DEBUG ((LM_DEBUG,
00298               "*** Bootstrapping to another Trading Service.\n"));
00299   CORBA::Object_var trading_obj =
00300     orb->resolve_initial_references ("TradingService" ACE_ENV_ARG_PARAMETER);
00301   ACE_CHECK_RETURN (-1);
00302 
00303   if (CORBA::is_nil (trading_obj.in ()))
00304     ACE_ERROR_RETURN ((LM_ERROR,
00305                        "We're all alone. "
00306                        "Unable to link to other traders.\n"),
00307                       -1);
00308 
00309   ACE_DEBUG ((LM_DEBUG,
00310               "*** Narrowing the lookup interface.\n"));
00311   CosTrading::Lookup_var lookup_if =
00312     CosTrading::Lookup::_narrow (trading_obj.in ()
00313                                  ACE_ENV_ARG_PARAMETER);
00314   ACE_CHECK_RETURN (-1);
00315 
00316   ACE_DEBUG ((LM_DEBUG,
00317               "*** Obtaining the link interface.\n"));
00318   CosTrading::Link_var link_if =
00319     lookup_if->link_if (ACE_ENV_SINGLE_ARG_PARAMETER);
00320   ACE_CHECK_RETURN (-1);
00321 
00322   TAO_Trading_Components_i &trd_comp =
00323     this->trader_->trading_components ();
00324   CosTrading::Lookup_ptr our_lookup =
00325     trd_comp.lookup_if ();
00326   CosTrading::Link_ptr our_link =
00327     trd_comp.link_if ();
00328 
00329   ACE_DEBUG ((LM_DEBUG,
00330               "*** Linking found trader to self.\n"));
00331   link_if->add_link (this->name_.in (),
00332                      our_lookup,
00333                      CosTrading::always,
00334                      CosTrading::always
00335                      ACE_ENV_ARG_PARAMETER);
00336   ACE_CHECK_RETURN (-1);
00337 
00338   ACE_DEBUG ((LM_DEBUG,
00339               "*** Linking self to found trader.\n"));
00340   our_link->add_link ("Bootstrap",
00341                       lookup_if.in (),
00342                       CosTrading::always,
00343                       CosTrading::always
00344                       ACE_ENV_ARG_PARAMETER);
00345   ACE_CHECK_RETURN (-1);
00346 
00347   ACE_DEBUG ((LM_DEBUG,
00348               "*** Retrieving list of known linked traders.\n"));
00349   CosTrading::LinkNameSeq_var link_name_seq =
00350     link_if->list_links (ACE_ENV_SINGLE_ARG_PARAMETER);
00351   ACE_CHECK_RETURN (-1);
00352 
00353   ACE_DEBUG ((LM_DEBUG,
00354               "*** Linking self to all linked traders.\n"));
00355   for (CORBA::ULong i = link_name_seq->length () - 1;
00356        i > 0;
00357        i--)
00358     {
00359       // Avoid linking to ourselves.
00360       if (ACE_OS::strcmp (static_cast<const char *> (link_name_seq[i]),
00361                           this->name_.in ()) != 0)
00362         {
00363           ACE_DEBUG ((LM_DEBUG,
00364                       "*** Getting info for link %s.\n",
00365                       static_cast<const char *> (link_name_seq[i])));
00366           CosTrading::Link::LinkInfo_var link_info =
00367             link_if->describe_link (link_name_seq[i]
00368                                     ACE_ENV_ARG_PARAMETER);
00369           ACE_CHECK_RETURN (-1);
00370 
00371           CosTrading::Lookup_ptr remote_lookup;
00372           remote_lookup = link_info->target.in ();
00373 
00374           ACE_DEBUG ((LM_DEBUG,
00375                       "*** Retrieving its link interface.\n"));
00376           CosTrading::Link_var remote_link =
00377             remote_lookup->link_if (ACE_ENV_SINGLE_ARG_PARAMETER);
00378           ACE_CHECK_RETURN (-1);
00379 
00380           ACE_DEBUG ((LM_DEBUG,
00381                       "*** Creating a link to me from it.\n"));
00382           remote_link->add_link (this->name_.in (),
00383                                  our_lookup,
00384                                  CosTrading::always,
00385                                  CosTrading::always
00386                                  ACE_ENV_ARG_PARAMETER);
00387           ACE_CHECK_RETURN (-1);
00388 
00389           ACE_DEBUG ((LM_DEBUG,
00390                       "*** Creating a link to it from me.\n"));
00391           our_link->add_link (link_name_seq[i],
00392                               remote_lookup,
00393                               CosTrading::always,
00394                               CosTrading::always
00395                               ACE_ENV_ARG_PARAMETER);
00396           ACE_CHECK_RETURN (-1);
00397         }
00398     }
00399 
00400   return 0;
00401 }
00402 
00403 int
00404 TAO_Trading_Loader::init_multicast_server (void)
00405 {
00406 #if defined (ACE_HAS_IP_MULTICAST)
00407   // Get reactor instance from TAO.
00408   ACE_Reactor *reactor = TAO_ORB_Core_instance ()->reactor ();
00409 
00410   // See if the -ORBMulticastDiscoveryEndpoint option was specified.
00411   ACE_CString mde (TAO_ORB_Core_instance ()->orb_params ()
00412                    ->mcast_discovery_endpoint ());
00413 
00414   // First, see if the user has given us a multicast port number for
00415   // the name service on the command-line;
00416   u_short port =
00417     TAO_ORB_Core_instance ()->orb_params ()->service_port (TAO::MCAST_TRADINGSERVICE);
00418 
00419   if (port == 0)
00420     {
00421       const char *port_number =
00422         ACE_OS::getenv ("TradingServicePort");
00423 
00424       if (port_number != 0)
00425         port = static_cast<u_short> (ACE_OS::atoi (port_number));
00426       else
00427         port = TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT;
00428     }
00429 
00430   // Instantiate a server that will receive requests for an ior
00431   if (mde.length () != 0)
00432     {
00433       if (this->ior_multicast_.init ((char *) this->ior_.in (),
00434                                      mde.c_str (),
00435                                      TAO_SERVICEID_TRADINGSERVICE) == -1)
00436         return -1;
00437     }
00438   else
00439     {
00440       if (this->ior_multicast_.init ((char *) this->ior_.in (),
00441                                      port,
00442                                      ACE_DEFAULT_MULTICAST_ADDR,
00443                                      TAO_SERVICEID_TRADINGSERVICE) == -1)
00444         ACE_ERROR_RETURN ((LM_ERROR,
00445                            "Failed to init IOR multicast.\n"),
00446                           -1);
00447     }
00448 
00449   // Register event handler for the ior multicast.
00450   if (reactor->register_handler (&this->ior_multicast_,
00451                                  ACE_Event_Handler::READ_MASK) == -1)
00452     ACE_DEBUG ((LM_DEBUG,
00453                 "cannot register Event handler\n"));
00454   else
00455     ACE_DEBUG ((LM_DEBUG,
00456                 "The multicast server setup is done.\n"));
00457 
00458   // Other trader instances will bootstrap to us.
00459   this->bootstrapper_ = 1;
00460 
00461 #endif /* ACE_HAS_IP_MULTICAST */
00462   return 0;
00463 }
00464 
00465 
00466 int
00467 TAO_Trading_Loader::parse_args (int &argc, ACE_TCHAR *argv [])
00468 {
00469   ACE_Arg_Shifter arg_shifter (argc, argv);
00470 
00471   while (arg_shifter.is_anything_left ())
00472     {
00473       const ACE_TCHAR *current_arg = arg_shifter.get_current ();
00474 
00475       if (ACE_OS::strcmp (current_arg,
00476                           ACE_TEXT("-TSfederate")) == 0)
00477         {
00478           arg_shifter.consume_arg ();
00479           this->federate_ = 1;
00480         }
00481       if (ACE_OS::strcmp (current_arg,
00482                           ACE_TEXT("-TSdumpior")) == 0)
00483         {
00484           arg_shifter.consume_arg ();
00485           if (arg_shifter.is_parameter_next ())
00486             {
00487               const ACE_TCHAR *file_name =
00488                 arg_shifter.get_current ();
00489               this->ior_output_file_ =
00490                 ACE_OS::fopen (file_name, ACE_TEXT("w"));
00491 
00492               if (this->ior_output_file_ == 0)
00493                 ACE_ERROR_RETURN ((LM_ERROR,
00494                                    "Unable to open %s for writing: %p\n",
00495                                    file_name), -1);
00496               arg_shifter.consume_arg ();
00497             }
00498           else
00499             this->ior_output_file_ =
00500               ACE_OS::fdopen (ACE_STDOUT,
00501                               ACE_TEXT("w"));
00502         }
00503 
00504       else
00505         arg_shifter.ignore_arg ();
00506     }
00507 
00508   return 0;
00509 }
00510 
00511 ACE_FACTORY_DEFINE (TAO_Trading_Serv, TAO_Trading_Loader)
00512 

Generated on Thu Nov 9 13:59:59 2006 for TAO_CosTrader by doxygen 1.3.6