Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / orbsvcs / Time_Service / Clerk_i.cpp
blob2c4f4a1f46b103ed433dcd662858cfdca7bc7f31
1 #include "orbsvcs/Log_Macros.h"
2 #include "Clerk_i.h"
3 #include "tao/debug.h"
4 #include "ace/Read_Buffer.h"
5 #include "ace/Get_Opt.h"
6 #include "ace/Argv_Type_Converter.h"
7 #include "ace/OS_NS_stdio.h"
8 #include "ace/OS_NS_unistd.h"
9 #include "ace/OS_NS_string.h"
10 #include "ace/OS_NS_fcntl.h"
11 #include "ace/os_include/os_netdb.h"
13 // Constructor.
14 Clerk_i::Clerk_i (void)
15 : ior_output_file_ (0),
16 timer_value_ (3),
17 timer_value_usecs_ (0),
18 server_ (Clerk_i::DEFAULT_SERVER_COUNT),
19 ior_fp_ (0)
23 // Destructor.
24 Clerk_i::~Clerk_i (void)
28 // Reads the Time Service Server iors from a file instead of using a
29 // naming service.
30 int
31 Clerk_i::read_ior (const ACE_TCHAR* filename)
33 // Open the file for reading.
34 ACE_HANDLE f_handle = ACE_OS::open (filename, 0);
36 if (f_handle == ACE_INVALID_HANDLE)
37 ORBSVCS_ERROR_RETURN ((LM_ERROR,
38 ACE_TEXT("[CLIENT] Process/Thread Id : (%P/%t) Unable to open %s for writing: %p\n"),
39 filename),
40 -1);
41 else
42 this->ior_fp_ = 1;
44 ACE_Read_Buffer ior_buffer (f_handle);
46 char *data = ior_buffer.read (EOF,'\n','\n');
47 if (data == 0)
48 ORBSVCS_ERROR_RETURN ((LM_ERROR,
49 ACE_TEXT("[CLIENT] Process/Thread Id : (%P/%t) Unable to read ior: %p\n")),
50 -1);
52 int result = 0;
54 try
56 for (char *str = ACE_OS::strtok (data, "\n");
57 str != 0 ;
58 str = ACE_OS::strtok (0, "\n"))
60 ORBSVCS_DEBUG ((LM_DEBUG,
61 ACE_TEXT("iors -> |%C|\n"),
62 str));
64 CORBA::Object_var objref =
65 this->orb_->string_to_object (str);
67 // Return if the server reference is nil.
68 if (CORBA::is_nil (objref.in ()))
70 ORBSVCS_ERROR ((LM_ERROR,
71 ACE_TEXT("IOR for the server is Null\n")));
72 result = -1;
73 break;
76 CosTime::TimeService_ptr server =
77 CosTime::TimeService::_narrow (objref.in ());
79 this->insert_server (server);
82 catch (const CORBA::Exception& ex)
84 ex._tao_print_exception (ACE_TEXT("Exception"));
87 ACE_OS::close (f_handle);
88 ior_buffer.alloc ()->free (data);
90 return result;
93 // Parse the command-line arguments and set options.
95 int
96 Clerk_i::parse_args (int argc,
97 ACE_TCHAR* argv[])
99 ACE_Get_Opt get_opts (argc, argv, ACE_TEXT("dt:u:f:o:"));
101 int c, result;
103 while ((c = get_opts ()) != -1)
104 switch (c)
106 case 'd': // debug flag.
107 TAO_debug_level++;
108 break;
110 case 't': // time in secs after which the clerk should update time.
111 this->timer_value_ = ACE_OS::atoi (get_opts.opt_arg ());
112 break;
114 case 'u':
115 // time in usecs after which the clerk should update time.
116 // Continues the precision of the -t option.
117 this->timer_value_usecs_ = ACE_OS::atoi (get_opts.opt_arg ());
118 break;
120 case 'f': // read the server IORs from a file.
121 result = this->read_ior (get_opts.opt_arg ());
123 if (result < 0)
124 ORBSVCS_ERROR_RETURN ((LM_ERROR,
125 ACE_TEXT("[CLERK] Process/Thread Id : (%P/%t) Unable to read ior from %s : %p\n"),
126 get_opts.opt_arg ()),
127 -1);
128 break;
130 case 'o': // output the Clerk IOR to a file.
131 this->ior_output_file_ =
132 ACE_OS::fopen (get_opts.opt_arg (), ACE_TEXT("w"));
134 if (this->ior_output_file_ == 0)
135 ORBSVCS_ERROR_RETURN ((LM_ERROR,
136 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t)Unable to open %s for writing: %\n"),
137 get_opts.opt_arg ()), -1);
138 break;
140 case '?': // display help for use of the server.
141 /* FALLTHRU */
142 default:
143 ORBSVCS_ERROR_RETURN ((LM_ERROR,
144 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t)")
145 ACE_TEXT("usage: %s")
146 ACE_TEXT(" [-d]")
147 ACE_TEXT(" [-t] <Timer value inn Secs>")
148 ACE_TEXT(" [-u] <Timer value in uSecs>")
149 ACE_TEXT(" [-f] <ior_input_file>")
150 ACE_TEXT(" [-o] <ior_output_file>")
151 ACE_TEXT("\n"),
152 argv[0]),
156 // Indicates successful parsing of command line.
157 return 0;
160 // Get a reference to the Server Naming context and the first IOR.
161 // The iterator returned from this is used to get the next n IORs.
164 Clerk_i::get_first_IOR (void)
168 char host_name[MAXHOSTNAMELEN];
170 ACE_OS::hostname (host_name,
171 MAXHOSTNAMELEN);
172 CosNaming::BindingList_var bindings_list;
173 CosNaming::BindingIterator_var iter;
175 // Construct the server context name.
176 CosNaming::Name server_context_name;
177 server_context_name.length (1);
178 server_context_name[0].id = CORBA::string_dup ("ServerContext");
180 // Resolve name.
181 CORBA::Object_var temp_object =
182 this->naming_client_->resolve (server_context_name);
185 CosNaming::NamingContext_var server_context =
186 CosNaming::NamingContext::_narrow (temp_object.in ());
188 if (CORBA::is_nil (server_context.in ()))
189 ORBSVCS_DEBUG ((LM_DEBUG,
190 ACE_TEXT("TAO_Time_Service_Clerk::get_server_IORs:")
191 ACE_TEXT("No Active Servers in the Network\n")));
193 // Get the first element and an iterator over the other
194 // elements.
195 server_context->list (1,
196 bindings_list.out (),
197 iter.out ());
198 CosNaming::Name server_name;
199 server_name.length (1);
200 server_name[0].id = bindings_list[0u].binding_name[0].id;
202 temp_object =
203 server_context->resolve (server_name);
205 CosTime::TimeService_var obj =
206 CosTime::TimeService::_narrow (temp_object.in ());
208 if (CORBA::is_nil (obj.in ()))
209 ORBSVCS_ERROR_RETURN ((LM_ERROR,
210 ACE_TEXT("[CLERK] Process/Thread Id : (%P/%t) Unable to Resolve ")
211 ACE_TEXT("Server Reference\n")),
212 -1);
214 // Insert the first server IOR into the unbounded set of server
215 // IORs.
217 this->insert_server (obj.in ());
219 // Iterate over the server context to get the next N IORs.
220 if (next_n_IORs (iter,
221 server_context) != 0)
222 ORBSVCS_ERROR_RETURN ((LM_ERROR,
223 ACE_TEXT("[CLERK] Process/Thread Id : (%P/%t) Unable to get next N IORs ")),
224 -1);;
226 catch (const CORBA::Exception& ex)
228 ex._tao_print_exception (ACE_TEXT("Exception"));
229 return -1;
232 return 0;
235 // Get the next n IORs of the time servers active in the Network and
236 // registered with the Naming Service. This is done by iterating over
237 // the naming context.
240 Clerk_i::next_n_IORs (CosNaming::BindingIterator_var iter,
241 CosNaming::NamingContext_var server_context)
245 CosNaming::Binding_var binding;
247 if (!CORBA::is_nil (iter.in ()))
249 while (iter->next_one (binding.out ()))
252 ORBSVCS_DEBUG ((LM_DEBUG,
253 ACE_TEXT("Getting IOR of the server: %C\n\n"),
254 binding->binding_name[0].id.in ()));
256 CosNaming::Name server_name;
257 server_name.length (1);
258 server_name[0].id = binding->binding_name[0].id;
260 CORBA::Object_var temp_object =
261 server_context->resolve (server_name);
263 CosTime::TimeService_ptr server =
264 CosTime::TimeService::_narrow (temp_object.in ());
266 this->insert_server (server);
272 catch (const CORBA::Exception& ex)
274 ex._tao_print_exception (
275 ACE_TEXT ("Unexpected exception in next_n_IORs\n"));
276 return -1;
279 return 0;
282 // Initialise the Naming Service.
285 Clerk_i::init_naming_service ()
287 // Initialize the Naming Client.
288 return (this->naming_client_.init (this->orb_.in ()));
291 // Create an instance of the clerk with appropriate parameters.
294 Clerk_i::create_clerk (void)
299 // Create a new clerk object. Pass it the timer value, the set
300 // of server IORs and the no. of servers.
301 ACE_NEW_RETURN (this->time_service_clerk_impl_,
302 TAO_Time_Service_Clerk (this->timer_value_,
303 this->timer_value_usecs_,
304 this->server_),
307 // Generate IOR of the Clerk and register with POA.
308 this->time_service_clerk_ =
309 this->time_service_clerk_impl_->_this ();
311 // Convert the clerk reference to a string.
312 CORBA::String_var objref_clerk =
313 this->orb_->object_to_string (this->time_service_clerk_.in ());
315 // Print the clerk IOR on the console.
316 ORBSVCS_DEBUG ((LM_DEBUG,
317 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) The Time Service CLERK IOR is: <%C>\n"),
318 objref_clerk.in ()));
320 // Print the Time Service clerk IOR to a file.
321 if (this->ior_output_file_)
323 ACE_OS::fprintf (this->ior_output_file_,
324 "%s",
325 objref_clerk.in ());
326 ACE_OS::fclose (this->ior_output_file_);
329 // Register the clerk implementation with the Interface
330 // Repository. init_IR();
332 catch (const CORBA::Exception& ex)
334 ex._tao_print_exception (ACE_TEXT("Exception"));
335 return -1;
338 return 0;
341 // Binds the clerk in the context ClerkContext with the name
342 // Clerk:<hostname>.
345 Clerk_i::register_clerk (void)
349 // Bind the Clerk in its appropriate Context.
351 CosNaming::Name clerk_context_name;
352 clerk_context_name.length (1);
353 clerk_context_name[0].id = CORBA::string_dup ("ClerkContext");
357 CosNaming::NamingContext_var clerk_context =
358 this->naming_client_->bind_new_context(clerk_context_name);
360 catch (const CosNaming::NamingContext::AlreadyBound& )
362 // OK, naming context already exists.
365 char host_name[MAXHOSTNAMELEN];
366 char clerk_mc_name[MAXHOSTNAMELEN];
367 ACE_OS::hostname (host_name, MAXHOSTNAMELEN);
369 //CosNaming::Name clerk_name (clerk_context_name);
370 CosNaming::Name clerk_name;
371 clerk_name.length (2);
373 ACE_OS::strcpy (clerk_mc_name, "Clerk:");
374 ACE_OS::strcat (clerk_mc_name, host_name);
376 clerk_name[0].id = CORBA::string_dup ("ClerkContext");
377 clerk_name[1].id = CORBA::string_dup (clerk_mc_name);
379 this->naming_client_->rebind (clerk_name,
380 this->time_service_clerk_.in ());
383 catch (const CORBA::Exception& ex)
385 ex._tao_print_exception (
386 ACE_TEXT ("(%P|%t) Exception from init_naming_service ()\n"));
389 return 0;
392 // Initialize the Clerk.
395 Clerk_i::init (int argc,
396 ACE_TCHAR *argv[])
400 // Make a copy of command line parameter.
401 ACE_Argv_Type_Converter command(argc, argv);
403 // Set the size of the Server IOR Array.
404 this->server_.max_size (10);
405 this->server_.size (0);
407 // Call the init of <TAO_ORB_Manager> to initialize the ORB and
408 // create a child POA under the root POA.
409 this->orb_manager_.init (command.get_argc(),
410 command.get_TCHAR_argv());
412 if (this->orb_manager_.init_child_poa (command.get_argc(),
413 command.get_TCHAR_argv(),
414 "child_poa") == -1)
415 ORBSVCS_ERROR_RETURN ((LM_ERROR,
416 ACE_TEXT("%p\n"),
417 ACE_TEXT("init_child_poa")),
418 -1);
420 // Get the ORB.
421 this->orb_ = this->orb_manager_.orb ();
423 // Parse commandline arguments.
424 if (this->parse_args (command.get_argc(), command.get_TCHAR_argv()) !=0 )
425 return -1;
427 // If IOR file has not been specified then try the Naming
428 // Service.
430 if (!this->ior_fp_)
432 ORBSVCS_DEBUG ((LM_DEBUG,
433 ACE_TEXT("IOR file not specified. Using the Naming Service instead\n")));
435 // Initialize the Naming Service.
436 if (this->init_naming_service () !=0 )
437 return -1;
439 // Get a reference to the Server Naming context and the
440 // first IOR.
441 if (this->get_first_IOR () != 0)
442 return -1;
446 // Create an instance of the Clerk.
447 if (this->create_clerk () != 0)
448 return -1;
451 // Register the clerk with the Naming Service.
452 if (this->ior_fp_ == 0)
454 if (this->register_clerk () != 0)
455 return -1;
458 // Close the open file handler.
459 // ACE_OS::fclose (this->ior_fp_);
461 catch (const CORBA::Exception& ex)
463 ex._tao_print_exception (
464 ACE_TEXT ("(%P|%t) Exception in Clerk_i::init ()\n"));
465 return -1;
468 return 0;
472 Clerk_i::run (void)
476 // Run the main event loop for the ORB.
477 int r = this->orb_manager_.run ();
479 if (r == -1)
480 ORBSVCS_ERROR_RETURN ((LM_ERROR,
481 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) Clerk_i::run")),
482 -1);
484 catch (const CORBA::Exception& ex)
486 ex._tao_print_exception (
487 ACE_TEXT ("(%P|%t) Exception in Clerk_i::run ()\n"));
490 return 0;
493 void
494 Clerk_i::insert_server (CosTime::TimeService_ptr server)
496 // We duplicate the capacity of the Array.
497 size_t s = this->server_.size ();
499 if (this->server_.max_size () == s)
500 this->server_.max_size (2 * s);
502 this->server_[s] =
503 CosTime::TimeService::_duplicate (server);
505 this->server_.size (s + 1);