Trading_Loader.cpp

Go to the documentation of this file.
00001 // $Id: Trading_Loader.cpp 77001 2007-02-12 07:54:49Z johnnyw $
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, "$Id: Trading_Loader.cpp 77001 2007-02-12 07:54:49Z johnnyw $")
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   try
00084     {
00085       // Copy command line parameter.
00086       ACE_Argv_Type_Converter command_line(argc, argv);
00087 
00088       // Initialize the ORB Manager
00089       this->orb_manager_.init (command_line.get_argc(),
00090                                command_line.get_ASCII_argv());
00091 
00092       CORBA::ORB_var orb =
00093         this->orb_manager_.orb ();
00094 
00095       // Initializes and sets up the Trading Service
00096       CORBA::Object_var object =
00097         this->create_object (orb.in (), command_line.get_argc(), command_line.get_TCHAR_argv());
00098 
00099     }
00100   catch (const CORBA::Exception&)
00101     {
00102       //    @@ Should we log this???
00103       return -1;
00104     }
00105   return 0;
00106 }
00107 
00108 int
00109 TAO_Trading_Loader::fini (void)
00110 {
00111   try
00112     {
00113       if (this->trader_.get () != 0)
00114         {
00115           TAO_Trading_Components_i& trd_comp
00116             = this->trader_->trading_components ();
00117           CosTrading::Link_ptr our_link =
00118             trd_comp.link_if ();
00119 
00120           CosTrading::LinkNameSeq_var link_name_seq =
00121             our_link->list_links ();
00122 
00123           ACE_DEBUG ((LM_DEBUG,
00124                       "*** Unlinking from federated traders.\n"));
00125 
00126           for (CORBA::ULong j = 0;
00127                j != link_name_seq->length ();
00128                ++j)
00129             {
00130               CORBA::ULong i =
00131                 link_name_seq->length () - j - 1;
00132 
00133               ACE_DEBUG ((LM_DEBUG,
00134                           "*** Describing the next link.\n"));
00135               CosTrading::Link::LinkInfo_var link_info =
00136                 our_link->describe_link (link_name_seq[i]);
00137 
00138               ACE_DEBUG ((LM_DEBUG,
00139                           "*** Removing link to %s.\n",
00140                           static_cast<const char *> (link_name_seq[i])));
00141               our_link->remove_link (link_name_seq[i]);
00142 
00143               CosTrading::Lookup_ptr remote_lookup;
00144               remote_lookup =
00145                 link_info->target.in ();
00146 
00147               ACE_DEBUG ((LM_DEBUG,
00148                           "*** Retrieving its link interface.\n"));
00149               CosTrading::Link_var remote_link =
00150                 remote_lookup->link_if ();
00151 
00152               ACE_DEBUG ((LM_DEBUG,
00153                           "*** Removing its link to us.\n"));
00154 
00155               if (this->bootstrapper_)
00156                 {
00157                   remote_link->remove_link ("Bootstrap");
00158                 }
00159               else
00160                 {
00161                   remote_link->remove_link (this->name_.in ());
00162                 }
00163             }
00164         }
00165     }
00166   catch (const CORBA::Exception& ex)
00167     {
00168       ex._tao_print_exception ("Trading Service shutting down");
00169     }
00170 
00171   return 0;
00172 }
00173 
00174 int
00175 TAO_Trading_Loader::run (void)
00176 {
00177   int return_value =
00178     this->orb_manager_.run ();
00179 
00180   return return_value;
00181 }
00182 
00183 CORBA::Object_ptr
00184 TAO_Trading_Loader::create_object (CORBA::ORB_ptr orb_ptr,
00185                                    int argc,
00186                                    ACE_TCHAR *argv[])
00187 {
00188   // Duplicate the ORB
00189   CORBA::ORB_var orb = CORBA::ORB::_duplicate (orb_ptr);
00190 
00191   // Activating the poa manager
00192   this->orb_manager_.activate_poa_manager ();
00193 
00194   // Create a Trader Object and set its Service Type Repository.
00195   auto_ptr<TAO_Trader_Factory::TAO_TRADER> auto_trader (TAO_Trader_Factory::create_trader (argc, argv));
00196 
00197   this->trader_ = auto_trader;
00198 
00199   TAO_Support_Attributes_i &sup_attr =
00200     this->trader_->support_attributes ();
00201 
00202   TAO_Trading_Components_i &trd_comp =
00203     this->trader_->trading_components ();
00204 
00205   sup_attr.type_repos (this->type_repos_._this ());
00206 
00207   // The Spec says: return a reference to the Lookup interface from
00208   // the resolve_initial_references method.
00209   CosTrading::Lookup_ptr lookup =
00210     trd_comp.lookup_if ();
00211 
00212   this->ior_ =
00213     orb->object_to_string (lookup);
00214 
00215   // Parse the args
00216   if (this->parse_args (argc, argv) == -1)
00217     return CORBA::Object::_nil ();
00218 
00219   // Dump the ior to a file.
00220   if (this->ior_output_file_ != 0)
00221     {
00222       ACE_OS::fprintf (this->ior_output_file_,
00223                        "%s",
00224                        this->ior_.in ());
00225       ACE_OS::fclose (this->ior_output_file_);
00226     }
00227 
00228   CORBA::Object_var table_object =
00229     orb->resolve_initial_references ("IORTable");
00230 
00231   IORTable::Table_var adapter =
00232     IORTable::Table::_narrow (table_object.in ());
00233 
00234   if (CORBA::is_nil (adapter.in ()))
00235     {
00236       ACE_ERROR ((LM_ERROR, "Nil IORTable\n"));
00237     }
00238   else
00239     {
00240       adapter->bind ("TradingService",
00241                      this->ior_.in ());
00242     }
00243 
00244   if (this->federate_)
00245     {
00246       // Only become a multicast server if we're the only trader
00247       // on the multicast network.
00248       // @@ Could do other things. For example, every timeout
00249       // period try to federate again, but let's not hardcode that
00250       // policy.
00251       int rc = this->bootstrap_to_federation ();
00252 
00253       if (rc == -1)
00254         this->init_multicast_server ();
00255     }
00256   else
00257     this->init_multicast_server ();
00258 
00259   return CORBA::Object::_nil ();
00260 }
00261 
00262 int
00263 TAO_Trading_Loader::bootstrap_to_federation (void)
00264 {
00265   // If all traders follow this strategy, it creates a complete graph
00266   // of all known traders on a multicast network.
00267   CORBA::ORB_var orb =
00268     this->orb_manager_.orb ();
00269 
00270   ACE_DEBUG ((LM_DEBUG,
00271               "*** Bootstrapping to another Trading Service.\n"));
00272   CORBA::Object_var trading_obj =
00273     orb->resolve_initial_references ("TradingService");
00274 
00275   if (CORBA::is_nil (trading_obj.in ()))
00276     ACE_ERROR_RETURN ((LM_ERROR,
00277                        "We're all alone. "
00278                        "Unable to link to other traders.\n"),
00279                       -1);
00280 
00281   ACE_DEBUG ((LM_DEBUG,
00282               "*** Narrowing the lookup interface.\n"));
00283   CosTrading::Lookup_var lookup_if =
00284     CosTrading::Lookup::_narrow (trading_obj.in ());
00285 
00286   ACE_DEBUG ((LM_DEBUG,
00287               "*** Obtaining the link interface.\n"));
00288   CosTrading::Link_var link_if =
00289     lookup_if->link_if ();
00290 
00291   TAO_Trading_Components_i &trd_comp =
00292     this->trader_->trading_components ();
00293   CosTrading::Lookup_ptr our_lookup =
00294     trd_comp.lookup_if ();
00295   CosTrading::Link_ptr our_link =
00296     trd_comp.link_if ();
00297 
00298   ACE_DEBUG ((LM_DEBUG,
00299               "*** Linking found trader to self.\n"));
00300   link_if->add_link (this->name_.in (),
00301                      our_lookup,
00302                      CosTrading::always,
00303                      CosTrading::always);
00304 
00305   ACE_DEBUG ((LM_DEBUG,
00306               "*** Linking self to found trader.\n"));
00307   our_link->add_link ("Bootstrap",
00308                       lookup_if.in (),
00309                       CosTrading::always,
00310                       CosTrading::always);
00311 
00312   ACE_DEBUG ((LM_DEBUG,
00313               "*** Retrieving list of known linked traders.\n"));
00314   CosTrading::LinkNameSeq_var link_name_seq =
00315     link_if->list_links ();
00316 
00317   ACE_DEBUG ((LM_DEBUG,
00318               "*** Linking self to all linked traders.\n"));
00319   for (CORBA::ULong i = link_name_seq->length () - 1;
00320        i > 0;
00321        i--)
00322     {
00323       // Avoid linking to ourselves.
00324       if (ACE_OS::strcmp (static_cast<const char *> (link_name_seq[i]),
00325                           this->name_.in ()) != 0)
00326         {
00327           ACE_DEBUG ((LM_DEBUG,
00328                       "*** Getting info for link %s.\n",
00329                       static_cast<const char *> (link_name_seq[i])));
00330           CosTrading::Link::LinkInfo_var link_info =
00331             link_if->describe_link (link_name_seq[i]);
00332 
00333           CosTrading::Lookup_ptr remote_lookup;
00334           remote_lookup = link_info->target.in ();
00335 
00336           ACE_DEBUG ((LM_DEBUG,
00337                       "*** Retrieving its link interface.\n"));
00338           CosTrading::Link_var remote_link =
00339             remote_lookup->link_if ();
00340 
00341           ACE_DEBUG ((LM_DEBUG,
00342                       "*** Creating a link to me from it.\n"));
00343           remote_link->add_link (this->name_.in (),
00344                                  our_lookup,
00345                                  CosTrading::always,
00346                                  CosTrading::always);
00347 
00348           ACE_DEBUG ((LM_DEBUG,
00349                       "*** Creating a link to it from me.\n"));
00350           our_link->add_link (link_name_seq[i],
00351                               remote_lookup,
00352                               CosTrading::always,
00353                               CosTrading::always);
00354         }
00355     }
00356 
00357   return 0;
00358 }
00359 
00360 int
00361 TAO_Trading_Loader::init_multicast_server (void)
00362 {
00363 #if defined (ACE_HAS_IP_MULTICAST)
00364   // Get reactor instance from TAO.
00365   ACE_Reactor *reactor = TAO_ORB_Core_instance ()->reactor ();
00366 
00367   // See if the -ORBMulticastDiscoveryEndpoint option was specified.
00368   ACE_CString mde (TAO_ORB_Core_instance ()->orb_params ()
00369                    ->mcast_discovery_endpoint ());
00370 
00371   // First, see if the user has given us a multicast port number for
00372   // the name service on the command-line;
00373   u_short port =
00374     TAO_ORB_Core_instance ()->orb_params ()->service_port (TAO::MCAST_TRADINGSERVICE);
00375 
00376   if (port == 0)
00377     {
00378       const char *port_number =
00379         ACE_OS::getenv ("TradingServicePort");
00380 
00381       if (port_number != 0)
00382         port = static_cast<u_short> (ACE_OS::atoi (port_number));
00383       else
00384         port = TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT;
00385     }
00386 
00387   // Instantiate a server that will receive requests for an ior
00388   if (mde.length () != 0)
00389     {
00390       if (this->ior_multicast_.init ((char *) this->ior_.in (),
00391                                      mde.c_str (),
00392                                      TAO_SERVICEID_TRADINGSERVICE) == -1)
00393         return -1;
00394     }
00395   else
00396     {
00397       if (this->ior_multicast_.init ((char *) this->ior_.in (),
00398                                      port,
00399                                      ACE_DEFAULT_MULTICAST_ADDR,
00400                                      TAO_SERVICEID_TRADINGSERVICE) == -1)
00401         ACE_ERROR_RETURN ((LM_ERROR,
00402                            "Failed to init IOR multicast.\n"),
00403                           -1);
00404     }
00405 
00406   // Register event handler for the ior multicast.
00407   if (reactor->register_handler (&this->ior_multicast_,
00408                                  ACE_Event_Handler::READ_MASK) == -1)
00409     ACE_DEBUG ((LM_DEBUG,
00410                 "cannot register Event handler\n"));
00411   else
00412     ACE_DEBUG ((LM_DEBUG,
00413                 "The multicast server setup is done.\n"));
00414 
00415   // Other trader instances will bootstrap to us.
00416   this->bootstrapper_ = 1;
00417 
00418 #endif /* ACE_HAS_IP_MULTICAST */
00419   return 0;
00420 }
00421 
00422 
00423 int
00424 TAO_Trading_Loader::parse_args (int &argc, ACE_TCHAR *argv [])
00425 {
00426   ACE_Arg_Shifter arg_shifter (argc, argv);
00427 
00428   while (arg_shifter.is_anything_left ())
00429     {
00430       const ACE_TCHAR *current_arg = arg_shifter.get_current ();
00431 
00432       if (ACE_OS::strcmp (current_arg,
00433                           ACE_TEXT("-TSfederate")) == 0)
00434         {
00435           arg_shifter.consume_arg ();
00436           this->federate_ = 1;
00437         }
00438       if (ACE_OS::strcmp (current_arg,
00439                           ACE_TEXT("-TSdumpior")) == 0)
00440         {
00441           arg_shifter.consume_arg ();
00442           if (arg_shifter.is_parameter_next ())
00443             {
00444               const ACE_TCHAR *file_name =
00445                 arg_shifter.get_current ();
00446               this->ior_output_file_ =
00447                 ACE_OS::fopen (file_name, ACE_TEXT("w"));
00448 
00449               if (this->ior_output_file_ == 0)
00450                 ACE_ERROR_RETURN ((LM_ERROR,
00451                                    "Unable to open %s for writing: %p\n",
00452                                    file_name), -1);
00453               arg_shifter.consume_arg ();
00454             }
00455           else
00456             this->ior_output_file_ =
00457               ACE_OS::fdopen (ACE_STDOUT,
00458                               ACE_TEXT("w"));
00459         }
00460 
00461       else
00462         arg_shifter.ignore_arg ();
00463     }
00464 
00465   return 0;
00466 }
00467 
00468 ACE_FACTORY_DEFINE (TAO_Trading_Serv, TAO_Trading_Loader)
00469 

Generated on Tue Feb 2 17:49:26 2010 for TAO_CosTrader by  doxygen 1.4.7