diff options
Diffstat (limited to 'trunk/TAO/orbsvcs/Time_Service/Clerk_i.cpp')
-rw-r--r-- | trunk/TAO/orbsvcs/Time_Service/Clerk_i.cpp | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/trunk/TAO/orbsvcs/Time_Service/Clerk_i.cpp b/trunk/TAO/orbsvcs/Time_Service/Clerk_i.cpp new file mode 100644 index 00000000000..ab42e2787f7 --- /dev/null +++ b/trunk/TAO/orbsvcs/Time_Service/Clerk_i.cpp @@ -0,0 +1,562 @@ +// $Id$ + +#include "Clerk_i.h" +#include "tao/debug.h" +#include "ace/Read_Buffer.h" +#include "ace/Get_Opt.h" +#include "ace/Argv_Type_Converter.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/os_include/os_netdb.h" + +ACE_RCSID(Time_Service, Clerk_i, "$Id$") + +// Constructor. + +Clerk_i::Clerk_i (void) + : ior_output_file_ (0), + timer_value_ (3), + timer_value_usecs_ (0), + server_ (Clerk_i::DEFAULT_SERVER_COUNT), + ior_fp_ (0) +{ + // no-op. +} + +// Destructor. + +Clerk_i::~Clerk_i (void) +{ + // no-op. +} + +// Reads the Time Service Server iors from a file instead of using a +// naming service. + +int +Clerk_i::read_ior (const ACE_TCHAR* filename) +{ + // Open the file for reading. + ACE_HANDLE f_handle = ACE_OS::open (filename, 0); + + if (f_handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[CLIENT] Process/Thread Id : (%P/%t) Unable to open %s for writing: %p\n"), + filename), + -1); + else + this->ior_fp_ = 1; + + ACE_Read_Buffer ior_buffer (f_handle); + + char *data = ior_buffer.read (EOF,'\n','\n'); + if (data == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[CLIENT] Process/Thread Id : (%P/%t) Unable to read ior: %p\n")), + -1); + + int result = 0; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + for (char *str = ACE_OS::strtok (data, "\n"); + str != 0 ; + str = ACE_OS::strtok (0, "\n")) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("iors -> |%s|\n"), + ACE_TEXT_CHAR_TO_TCHAR(str))); + + CORBA::Object_var objref = + this->orb_->string_to_object (str + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Return if the server reference is nil. + if (CORBA::is_nil (objref.in ())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("IOR for the server is Null\n"))); + result = -1; + break; + } + + CosTime::TimeService_ptr server = + CosTime::TimeService::_narrow (objref.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->insert_server (server); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, ACE_TEXT("Exception")); + } + ACE_ENDTRY; + + ACE_OS::close (f_handle); + ior_buffer.alloc ()->free (data); + + return result; +} + +// Parse the command-line arguments and set options. + +int +Clerk_i::parse_args (int argc, + ACE_TCHAR* argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("dt:u:f:o:")); + + int c, result; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'd': // debug flag. + TAO_debug_level++; + break; + + case 't': // time in secs after which the clerk should update time. + this->timer_value_ = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case 'u': + // time in usecs after which the clerk should update time. + // Continues the precision of the -t option. + this->timer_value_usecs_ = ACE_OS::atoi (get_opts.opt_arg ()); + break; + + case 'f': // read the server IORs from a file. + result = this->read_ior (get_opts.opt_arg ()); + + if (result < 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[CLERK] Process/Thread Id : (%P/%t) Unable to read ior from %s : %p\n"), + get_opts.opt_arg ()), + -1); + break; + + case 'o': // output the Clerk IOR to a file. + this->ior_output_file_ = + ACE_OS::fopen (get_opts.opt_arg (), ACE_TEXT("w")); + + if (this->ior_output_file_ == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t)Unable to open %s for writing: %\n"), + get_opts.opt_arg ()), -1); + break; + + case '?': // display help for use of the server. + /* FALLTHRU */ + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t)") + ACE_TEXT("usage: %s") + ACE_TEXT(" [-d]") + ACE_TEXT(" [-t] <Timer value inn Secs>") + ACE_TEXT(" [-u] <Timer value in uSecs>") + ACE_TEXT(" [-f] <ior_input_file>") + ACE_TEXT(" [-o] <ior_output_file>") + ACE_TEXT("\n"), + argv[0]), + 1); + } + + // Indicates successful parsing of command line. + return 0; +} + +// Get a reference to the Server Naming context and the first IOR. +// The iterator returned from this is used to get the next n IORs. + +int +Clerk_i::get_first_IOR (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + char host_name[MAXHOSTNAMELEN]; + + ACE_OS::hostname (host_name, + MAXHOSTNAMELEN); + CosNaming::BindingList_var bindings_list; + CosNaming::BindingIterator_var iter; + + // Construct the server context name. + CosNaming::Name server_context_name; + server_context_name.length (1); + server_context_name[0].id = CORBA::string_dup ("ServerContext"); + + // Resolve name. + CORBA::Object_var temp_object = + this->naming_client_->resolve (server_context_name + ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + + CosNaming::NamingContext_var server_context = + CosNaming::NamingContext::_narrow (temp_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (server_context.in ())) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO_Time_Service_Clerk::get_server_IORs:") + ACE_TEXT("No Active Servers in the Network\n"))); + + // Get the first element and an iterator over the other + // elements. + server_context->list (1, + bindings_list.out (), + iter.out ()); + CosNaming::Name server_name; + server_name.length (1); + server_name[0].id = bindings_list[0u].binding_name[0].id; + + temp_object = + server_context->resolve (server_name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosTime::TimeService_var obj = + CosTime::TimeService::_narrow (temp_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (obj.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[CLERK] Process/Thread Id : (%P/%t) Unable to Resolve ") + ACE_TEXT("Server Reference\n")), + -1); + + // Insert the first server IOR into the unbounded set of server + // IORs. + + this->insert_server (obj.in ()); + + // Iterate over the server context to get the next N IORs. + if (next_n_IORs (iter, + server_context) != 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[CLERK] Process/Thread Id : (%P/%t) Unable to get next N IORs ")), + -1);; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, ACE_TEXT("Exception")); + return -1; + } + ACE_ENDTRY; + + return 0; +} + +// Get the next n IORs of the time servers active in the Network and +// registered with the Naming Service. This is done by iterating over +// the naming context. + +int +Clerk_i::next_n_IORs (CosNaming::BindingIterator_var iter, + CosNaming::NamingContext_var server_context) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CosNaming::Binding_var binding; + + if (!CORBA::is_nil (iter.in ())) + { + while (iter->next_one (binding.out () + ACE_ENV_ARG_PARAMETER)) + { + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("Getting IOR of the server: %s\n\n"), + ACE_TEXT_CHAR_TO_TCHAR(binding->binding_name[0].id.in ()))); + + CosNaming::Name server_name; + server_name.length (1); + server_name[0].id = binding->binding_name[0].id; + + CORBA::Object_var temp_object = + server_context->resolve (server_name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosTime::TimeService_ptr server = + CosTime::TimeService::_narrow (temp_object.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->insert_server (server); + } + + ACE_TRY_CHECK; + } + + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT("Unexpected exception in next_n_IORs\n")); + return -1; + } + ACE_ENDTRY; + + return 0; +} + +// Initialise the Naming Service. + +int +Clerk_i::init_naming_service () +{ + // Initialize the Naming Client. + return (this->naming_client_.init (this->orb_.in ())); +} + +// Create an instance of the clerk with appropriate parameters. + +int +Clerk_i::create_clerk (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + + // Create a new clerk object. Pass it the timer value, the set + // of server IORs and the no. of servers. + ACE_NEW_RETURN (this->time_service_clerk_impl_, + TAO_Time_Service_Clerk (this->timer_value_, + this->timer_value_usecs_, + this->server_), + 0); + + // Generate IOR of the Clerk and register with POA. + this->time_service_clerk_ = + this->time_service_clerk_impl_->_this (); + + // Convert the clerk reference to a string. + CORBA::String_var objref_clerk = + this->orb_->object_to_string (this->time_service_clerk_.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Print the clerk IOR on the console. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) The Time Service CLERK IOR is: <%s>\n"), + ACE_TEXT_CHAR_TO_TCHAR(objref_clerk.in ()))); + + // Print the Time Service clerk IOR to a file. + if (this->ior_output_file_) + { + ACE_OS::fprintf (this->ior_output_file_, + "%s", + objref_clerk.in ()); + ACE_OS::fclose (this->ior_output_file_); + } + + // Register the clerk implementation with the Interface + // Repository. init_IR(); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, ACE_TEXT("Exception")); + return -1; + } + ACE_ENDTRY; + + return 0; +} + +// Binds the clerk in the context ClerkContext with the name +// Clerk:<hostname>. + +int +Clerk_i::register_clerk (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // Bind the Clerk in its appropriate Context. + + CosNaming::Name clerk_context_name; + clerk_context_name.length (1); + clerk_context_name[0].id = CORBA::string_dup ("ClerkContext"); + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY_EX(bind_new_context) + { + CosNaming::NamingContext_var clerk_context = + this->naming_client_->bind_new_context(clerk_context_name); + ACE_TRY_CHECK_EX(bind_new_context); + } + ACE_CATCH(CosNaming::NamingContext::AlreadyBound, ex) + { + // OK, naming context already exists. + } + ACE_ENDTRY; + + char host_name[MAXHOSTNAMELEN]; + char clerk_mc_name[MAXHOSTNAMELEN]; + ACE_OS::hostname (host_name, MAXHOSTNAMELEN); + + //CosNaming::Name clerk_name (clerk_context_name); + CosNaming::Name clerk_name; + clerk_name.length (2); + + ACE_OS::strcpy (clerk_mc_name, "Clerk:"); + ACE_OS::strcat (clerk_mc_name, host_name); + + clerk_name[0].id = CORBA::string_dup ("ClerkContext"); + clerk_name[1].id = CORBA::string_dup (clerk_mc_name); + + this->naming_client_->rebind (clerk_name, + this->time_service_clerk_.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT("(%P|%t) Exception from init_naming_service ()\n")); + } + ACE_ENDTRY; + + return 0; +} + +// Initialize the Clerk. + +int +Clerk_i::init (int argc, + ACE_TCHAR *argv[] + ACE_ENV_ARG_DECL) +{ + ACE_TRY + { + // Make a copy of command line parameter. + ACE_Argv_Type_Converter command(argc, argv); + + // Set the size of the Server IOR Array. + this->server_.max_size (10); + this->server_.size (0); + + // Call the init of <TAO_ORB_Manager> to initialize the ORB and + // create a child POA under the root POA. + + + this->orb_manager_.init (command.get_argc(), + command.get_ASCII_argv() + ACE_ENV_ARG_PARAMETER); + + ACE_TRY_CHECK; + + if (this->orb_manager_.init_child_poa (command.get_argc(), + command.get_ASCII_argv(), + "child_poa" + ACE_ENV_ARG_PARAMETER) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("%p\n"), + ACE_TEXT("init_child_poa")), + -1); + ACE_TRY_CHECK; + + // Get the ORB. + this->orb_ = this->orb_manager_.orb (); + + // Parse commandline arguments. + if (this->parse_args (command.get_argc(), command.get_TCHAR_argv()) !=0 ) + return -1; + + // If IOR file has not been specified then try the Naming + // Service. + + if (!this->ior_fp_) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("IOR file not specified. Using the Naming Service instead\n"))); + + // Initialize the Naming Service. + if (this->init_naming_service () !=0 ) + return -1; + + // Get a reference to the Server Naming context and the + // first IOR. + if (this->get_first_IOR () != 0) + return -1; + + } + + // Create an instance of the Clerk. + if (this->create_clerk () != 0) + return -1; + + + // Register the clerk with the Naming Service. + if (this->ior_fp_ == 0) + { + if (this->register_clerk () != 0) + return -1; + } + + // Close the open file handler. + // ACE_OS::fclose (this->ior_fp_); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT("(%P|%t) Exception in Clerk_i::init ()\n")); + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +Clerk_i::run (ACE_ENV_SINGLE_ARG_DECL) +{ + ACE_TRY + { + // Run the main event loop for the ORB. + int r = this->orb_manager_.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (r == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) Clerk_i::run")), + -1); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT("(%P|%t) Exception in Clerk_i::run ()\n")); + } + ACE_ENDTRY; + + return 0; +} + +void +Clerk_i::insert_server (CosTime::TimeService_ptr server) +{ + // We duplicate the capacity of the Array. + size_t s = this->server_.size (); + + if (this->server_.max_size () == s) + this->server_.max_size (2 * s); + + this->server_[s] = + CosTime::TimeService::_duplicate (server); + + this->server_.size (s + 1); +} |