summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Trader/Trading_Loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Trader/Trading_Loader.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/Trader/Trading_Loader.cpp469
1 files changed, 469 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Trader/Trading_Loader.cpp b/TAO/orbsvcs/orbsvcs/Trader/Trading_Loader.cpp
new file mode 100644
index 00000000000..6e3bd4780d3
--- /dev/null
+++ b/TAO/orbsvcs/orbsvcs/Trader/Trading_Loader.cpp
@@ -0,0 +1,469 @@
+// $Id$
+
+//===========================================================================
+
+// LIBRARY
+// libTAO_CosTrading.so
+//
+// DESCRIPTION
+// This class allows for dynamically loading
+// the Trading Service.
+//
+// AUTHORS
+// Priyanka Gontla <pgontla@ece.uci.edu>
+
+//===========================================================================
+
+#include "orbsvcs/Trader/Trading_Loader.h"
+
+#include "tao/ORB_Core.h"
+#include "tao/default_ports.h"
+#include "tao/IORTable/IORTable.h"
+
+#include "ace/Dynamic_Service.h"
+#include "ace/Arg_Shifter.h"
+#include "ace/Argv_Type_Converter.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/os_include/os_netdb.h"
+
+ACE_RCSID (Trader, Trading_Loader, "$Id$")
+
+TAO_Trading_Loader::TAO_Trading_Loader (void)
+ : federate_ (0),
+ ior_output_file_ (0),
+ bootstrapper_ (0)
+{
+ char *trader_name = CORBA::string_alloc (MAXHOSTNAMELEN + 10);
+
+ if (trader_name != 0)
+ {
+ // The trader name is the concatenation of the local host name
+ // and the server's process id.
+ char host_name[MAXHOSTNAMELEN + 1];
+ ACE_INET_Addr localhost ((u_short) 0);
+ if (localhost.get_host_name (host_name, sizeof (host_name)) != 0)
+ {
+ const char *tmp = localhost.get_host_addr ();
+ if (tmp == 0)
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("\n\nTAO Trading Service (%P|%t) ")
+ ACE_TEXT ("TAO_Trading_Loader ")
+ ACE_TEXT ("- %p\n\n"),
+ ACE_TEXT ("cannot determine hostname")));
+ else
+ ACE_OS::strcpy (host_name, tmp);
+ }
+
+ ACE_OS::sprintf (trader_name,
+ "%s_%ld",
+ host_name,
+ static_cast<long> (ACE_OS::getpid ()));
+
+ for (char *dot = 0;
+ (dot = ACE_OS::strchr (trader_name, '.')) != 0;
+ *dot = '_')
+ continue;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Trading Service %s initializing.\n",
+ trader_name));
+
+ this->name_ = trader_name;
+ }
+}
+
+TAO_Trading_Loader::~TAO_Trading_Loader (void)
+{
+ // Destructor
+}
+
+int
+TAO_Trading_Loader::init (int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ // Copy command line parameter.
+ ACE_Argv_Type_Converter command_line(argc, argv);
+
+ // Initialize the ORB Manager
+ this->orb_manager_.init (command_line.get_argc(),
+ command_line.get_ASCII_argv());
+
+ CORBA::ORB_var orb =
+ this->orb_manager_.orb ();
+
+ // Initializes and sets up the Trading Service
+ CORBA::Object_var object =
+ this->create_object (orb.in (), command_line.get_argc(), command_line.get_TCHAR_argv());
+
+ }
+ catch (const CORBA::Exception&)
+ {
+ // @@ Should we log this???
+ return -1;
+ }
+ return 0;
+}
+
+int
+TAO_Trading_Loader::fini (void)
+{
+ try
+ {
+ if (this->trader_.get () != 0)
+ {
+ TAO_Trading_Components_i& trd_comp
+ = this->trader_->trading_components ();
+ CosTrading::Link_ptr our_link =
+ trd_comp.link_if ();
+
+ CosTrading::LinkNameSeq_var link_name_seq =
+ our_link->list_links ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Unlinking from federated traders.\n"));
+
+ for (CORBA::ULong j = 0;
+ j != link_name_seq->length ();
+ ++j)
+ {
+ CORBA::ULong i =
+ link_name_seq->length () - j - 1;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Describing the next link.\n"));
+ CosTrading::Link::LinkInfo_var link_info =
+ our_link->describe_link (link_name_seq[i]);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Removing link to %s.\n",
+ static_cast<const char *> (link_name_seq[i])));
+ our_link->remove_link (link_name_seq[i]);
+
+ CosTrading::Lookup_ptr remote_lookup;
+ remote_lookup =
+ link_info->target.in ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Retrieving its link interface.\n"));
+ CosTrading::Link_var remote_link =
+ remote_lookup->link_if ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Removing its link to us.\n"));
+
+ if (this->bootstrapper_)
+ {
+ remote_link->remove_link ("Bootstrap");
+ }
+ else
+ {
+ remote_link->remove_link (this->name_.in ());
+ }
+ }
+ }
+ }
+ catch (const CORBA::Exception& ex)
+ {
+ ex._tao_print_exception ("Trading Service shutting down");
+ }
+
+ return 0;
+}
+
+int
+TAO_Trading_Loader::run (void)
+{
+ int return_value =
+ this->orb_manager_.run ();
+
+ return return_value;
+}
+
+CORBA::Object_ptr
+TAO_Trading_Loader::create_object (CORBA::ORB_ptr orb_ptr,
+ int argc,
+ ACE_TCHAR *argv[])
+{
+ // Duplicate the ORB
+ CORBA::ORB_var orb = CORBA::ORB::_duplicate (orb_ptr);
+
+ // Activating the poa manager
+ this->orb_manager_.activate_poa_manager ();
+
+ // Create a Trader Object and set its Service Type Repository.
+ auto_ptr<TAO_Trader_Factory::TAO_TRADER> auto_trader (TAO_Trader_Factory::create_trader (argc, argv));
+
+ this->trader_ = auto_trader;
+
+ TAO_Support_Attributes_i &sup_attr =
+ this->trader_->support_attributes ();
+
+ TAO_Trading_Components_i &trd_comp =
+ this->trader_->trading_components ();
+
+ sup_attr.type_repos (this->type_repos_._this ());
+
+ // The Spec says: return a reference to the Lookup interface from
+ // the resolve_initial_references method.
+ CosTrading::Lookup_ptr lookup =
+ trd_comp.lookup_if ();
+
+ this->ior_ =
+ orb->object_to_string (lookup);
+
+ // Parse the args
+ if (this->parse_args (argc, argv) == -1)
+ return CORBA::Object::_nil ();
+
+ // Dump the ior to a file.
+ if (this->ior_output_file_ != 0)
+ {
+ ACE_OS::fprintf (this->ior_output_file_,
+ "%s",
+ this->ior_.in ());
+ ACE_OS::fclose (this->ior_output_file_);
+ }
+
+ CORBA::Object_var table_object =
+ orb->resolve_initial_references ("IORTable");
+
+ IORTable::Table_var adapter =
+ IORTable::Table::_narrow (table_object.in ());
+
+ if (CORBA::is_nil (adapter.in ()))
+ {
+ ACE_ERROR ((LM_ERROR, "Nil IORTable\n"));
+ }
+ else
+ {
+ adapter->bind ("TradingService",
+ this->ior_.in ());
+ }
+
+ if (this->federate_)
+ {
+ // Only become a multicast server if we're the only trader
+ // on the multicast network.
+ // @@ Could do other things. For example, every timeout
+ // period try to federate again, but let's not hardcode that
+ // policy.
+ int rc = this->bootstrap_to_federation ();
+
+ if (rc == -1)
+ this->init_multicast_server ();
+ }
+ else
+ this->init_multicast_server ();
+
+ return CORBA::Object::_nil ();
+}
+
+int
+TAO_Trading_Loader::bootstrap_to_federation (void)
+{
+ // If all traders follow this strategy, it creates a complete graph
+ // of all known traders on a multicast network.
+ CORBA::ORB_var orb =
+ this->orb_manager_.orb ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Bootstrapping to another Trading Service.\n"));
+ CORBA::Object_var trading_obj =
+ orb->resolve_initial_references ("TradingService");
+
+ if (CORBA::is_nil (trading_obj.in ()))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "We're all alone. "
+ "Unable to link to other traders.\n"),
+ -1);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Narrowing the lookup interface.\n"));
+ CosTrading::Lookup_var lookup_if =
+ CosTrading::Lookup::_narrow (trading_obj.in ());
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Obtaining the link interface.\n"));
+ CosTrading::Link_var link_if =
+ lookup_if->link_if ();
+
+ TAO_Trading_Components_i &trd_comp =
+ this->trader_->trading_components ();
+ CosTrading::Lookup_ptr our_lookup =
+ trd_comp.lookup_if ();
+ CosTrading::Link_ptr our_link =
+ trd_comp.link_if ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Linking found trader to self.\n"));
+ link_if->add_link (this->name_.in (),
+ our_lookup,
+ CosTrading::always,
+ CosTrading::always);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Linking self to found trader.\n"));
+ our_link->add_link ("Bootstrap",
+ lookup_if.in (),
+ CosTrading::always,
+ CosTrading::always);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Retrieving list of known linked traders.\n"));
+ CosTrading::LinkNameSeq_var link_name_seq =
+ link_if->list_links ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Linking self to all linked traders.\n"));
+ for (CORBA::ULong i = link_name_seq->length () - 1;
+ i > 0;
+ i--)
+ {
+ // Avoid linking to ourselves.
+ if (ACE_OS::strcmp (static_cast<const char *> (link_name_seq[i]),
+ this->name_.in ()) != 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Getting info for link %s.\n",
+ static_cast<const char *> (link_name_seq[i])));
+ CosTrading::Link::LinkInfo_var link_info =
+ link_if->describe_link (link_name_seq[i]);
+
+ CosTrading::Lookup_ptr remote_lookup;
+ remote_lookup = link_info->target.in ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Retrieving its link interface.\n"));
+ CosTrading::Link_var remote_link =
+ remote_lookup->link_if ();
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Creating a link to me from it.\n"));
+ remote_link->add_link (this->name_.in (),
+ our_lookup,
+ CosTrading::always,
+ CosTrading::always);
+
+ ACE_DEBUG ((LM_DEBUG,
+ "*** Creating a link to it from me.\n"));
+ our_link->add_link (link_name_seq[i],
+ remote_lookup,
+ CosTrading::always,
+ CosTrading::always);
+ }
+ }
+
+ return 0;
+}
+
+int
+TAO_Trading_Loader::init_multicast_server (void)
+{
+#if defined (ACE_HAS_IP_MULTICAST)
+ // Get reactor instance from TAO.
+ ACE_Reactor *reactor = TAO_ORB_Core_instance ()->reactor ();
+
+ // See if the -ORBMulticastDiscoveryEndpoint option was specified.
+ ACE_CString mde (TAO_ORB_Core_instance ()->orb_params ()
+ ->mcast_discovery_endpoint ());
+
+ // First, see if the user has given us a multicast port number for
+ // the name service on the command-line;
+ u_short port =
+ TAO_ORB_Core_instance ()->orb_params ()->service_port (TAO::MCAST_TRADINGSERVICE);
+
+ if (port == 0)
+ {
+ const char *port_number =
+ ACE_OS::getenv ("TradingServicePort");
+
+ if (port_number != 0)
+ port = static_cast<u_short> (ACE_OS::atoi (port_number));
+ else
+ port = TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT;
+ }
+
+ // Instantiate a server that will receive requests for an ior
+ if (mde.length () != 0)
+ {
+ if (this->ior_multicast_.init ((char *) this->ior_.in (),
+ mde.c_str (),
+ TAO_SERVICEID_TRADINGSERVICE) == -1)
+ return -1;
+ }
+ else
+ {
+ if (this->ior_multicast_.init ((char *) this->ior_.in (),
+ port,
+ ACE_DEFAULT_MULTICAST_ADDR,
+ TAO_SERVICEID_TRADINGSERVICE) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Failed to init IOR multicast.\n"),
+ -1);
+ }
+
+ // Register event handler for the ior multicast.
+ if (reactor->register_handler (&this->ior_multicast_,
+ ACE_Event_Handler::READ_MASK) == -1)
+ ACE_DEBUG ((LM_DEBUG,
+ "cannot register Event handler\n"));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "The multicast server setup is done.\n"));
+
+ // Other trader instances will bootstrap to us.
+ this->bootstrapper_ = 1;
+
+#endif /* ACE_HAS_IP_MULTICAST */
+ return 0;
+}
+
+
+int
+TAO_Trading_Loader::parse_args (int &argc, ACE_TCHAR *argv [])
+{
+ ACE_Arg_Shifter arg_shifter (argc, argv);
+
+ while (arg_shifter.is_anything_left ())
+ {
+ const ACE_TCHAR *current_arg = arg_shifter.get_current ();
+
+ if (ACE_OS::strcmp (current_arg,
+ ACE_TEXT("-TSfederate")) == 0)
+ {
+ arg_shifter.consume_arg ();
+ this->federate_ = 1;
+ }
+ if (ACE_OS::strcmp (current_arg,
+ ACE_TEXT("-TSdumpior")) == 0)
+ {
+ arg_shifter.consume_arg ();
+ if (arg_shifter.is_parameter_next ())
+ {
+ const ACE_TCHAR *file_name =
+ arg_shifter.get_current ();
+ this->ior_output_file_ =
+ ACE_OS::fopen (file_name, ACE_TEXT("w"));
+
+ if (this->ior_output_file_ == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Unable to open %s for writing: %p\n",
+ file_name), -1);
+ arg_shifter.consume_arg ();
+ }
+ else
+ this->ior_output_file_ =
+ ACE_OS::fdopen (ACE_STDOUT,
+ ACE_TEXT("w"));
+ }
+
+ else
+ arg_shifter.ignore_arg ();
+ }
+
+ return 0;
+}
+
+ACE_FACTORY_DEFINE (TAO_Trading_Serv, TAO_Trading_Loader)
+