Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / TAO / orbsvcs / Time_Service / Clerk_i.cpp
blob48ed6b7a58c23dc811ba4c73ac6c3eaebc2aea6d
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 ()
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 ()
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 ACE_FALLTHROUGH;
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 ()
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 ()))
251 ORBSVCS_DEBUG ((LM_DEBUG,
252 ACE_TEXT("Getting IOR of the server: %C\n\n"),
253 binding->binding_name[0].id.in ()));
255 CosNaming::Name server_name;
256 server_name.length (1);
257 server_name[0].id = binding->binding_name[0].id;
259 CORBA::Object_var temp_object =
260 server_context->resolve (server_name);
262 CosTime::TimeService_ptr server =
263 CosTime::TimeService::_narrow (temp_object.in ());
265 this->insert_server (server);
271 catch (const CORBA::Exception& ex)
273 ex._tao_print_exception (
274 ACE_TEXT ("Unexpected exception in next_n_IORs\n"));
275 return -1;
278 return 0;
281 // Initialise the Naming Service.
284 Clerk_i::init_naming_service ()
286 // Initialize the Naming Client.
287 return (this->naming_client_.init (this->orb_.in ()));
290 // Create an instance of the clerk with appropriate parameters.
293 Clerk_i::create_clerk ()
297 // Create a new clerk object. Pass it the timer value, the set
298 // of server IORs and the no. of servers.
299 ACE_NEW_RETURN (this->time_service_clerk_impl_,
300 TAO_Time_Service_Clerk (this->timer_value_,
301 this->timer_value_usecs_,
302 this->server_),
305 // Generate IOR of the Clerk and register with POA.
306 this->time_service_clerk_ =
307 this->time_service_clerk_impl_->_this ();
309 // Convert the clerk reference to a string.
310 CORBA::String_var objref_clerk =
311 this->orb_->object_to_string (this->time_service_clerk_.in ());
313 // Print the clerk IOR on the console.
314 ORBSVCS_DEBUG ((LM_DEBUG,
315 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) The Time Service CLERK IOR is: <%C>\n"),
316 objref_clerk.in ()));
318 // Print the Time Service clerk IOR to a file.
319 if (this->ior_output_file_)
321 ACE_OS::fprintf (this->ior_output_file_,
322 "%s",
323 objref_clerk.in ());
324 ACE_OS::fclose (this->ior_output_file_);
327 // Register the clerk implementation with the Interface
328 // Repository. init_IR();
330 catch (const CORBA::Exception& ex)
332 ex._tao_print_exception (ACE_TEXT("Exception"));
333 return -1;
336 return 0;
339 // Binds the clerk in the context ClerkContext with the name
340 // Clerk:<hostname>.
343 Clerk_i::register_clerk ()
347 // Bind the Clerk in its appropriate Context.
349 CosNaming::Name clerk_context_name;
350 clerk_context_name.length (1);
351 clerk_context_name[0].id = CORBA::string_dup ("ClerkContext");
355 CosNaming::NamingContext_var clerk_context =
356 this->naming_client_->bind_new_context(clerk_context_name);
358 catch (const CosNaming::NamingContext::AlreadyBound& )
360 // OK, naming context already exists.
363 char host_name[MAXHOSTNAMELEN];
364 char clerk_mc_name[MAXHOSTNAMELEN];
365 ACE_OS::hostname (host_name, MAXHOSTNAMELEN);
367 //CosNaming::Name clerk_name (clerk_context_name);
368 CosNaming::Name clerk_name;
369 clerk_name.length (2);
371 ACE_OS::strcpy (clerk_mc_name, "Clerk:");
372 ACE_OS::strcat (clerk_mc_name, host_name);
374 clerk_name[0].id = CORBA::string_dup ("ClerkContext");
375 clerk_name[1].id = CORBA::string_dup (clerk_mc_name);
377 this->naming_client_->rebind (clerk_name,
378 this->time_service_clerk_.in ());
380 catch (const CORBA::Exception& ex)
382 ex._tao_print_exception (
383 ACE_TEXT ("(%P|%t) Exception from init_naming_service ()\n"));
386 return 0;
389 // Initialize the Clerk.
392 Clerk_i::init (int argc,
393 ACE_TCHAR *argv[])
397 // Make a copy of command line parameter.
398 ACE_Argv_Type_Converter command(argc, argv);
400 // Set the size of the Server IOR Array.
401 this->server_.max_size (10);
402 this->server_.size (0);
404 // Call the init of <TAO_ORB_Manager> to initialize the ORB and
405 // create a child POA under the root POA.
406 this->orb_manager_.init (command.get_argc(),
407 command.get_TCHAR_argv());
409 if (this->orb_manager_.init_child_poa (command.get_argc(),
410 command.get_TCHAR_argv(),
411 "child_poa") == -1)
412 ORBSVCS_ERROR_RETURN ((LM_ERROR,
413 ACE_TEXT("%p\n"),
414 ACE_TEXT("init_child_poa")),
415 -1);
417 // Get the ORB.
418 this->orb_ = this->orb_manager_.orb ();
420 // Parse commandline arguments.
421 if (this->parse_args (command.get_argc(), command.get_TCHAR_argv()) !=0 )
422 return -1;
424 // If IOR file has not been specified then try the Naming
425 // Service.
427 if (!this->ior_fp_)
429 ORBSVCS_DEBUG ((LM_DEBUG,
430 ACE_TEXT("IOR file not specified. Using the Naming Service instead\n")));
432 // Initialize the Naming Service.
433 if (this->init_naming_service () !=0 )
434 return -1;
436 // Get a reference to the Server Naming context and the
437 // first IOR.
438 if (this->get_first_IOR () != 0)
439 return -1;
442 // Create an instance of the Clerk.
443 if (this->create_clerk () != 0)
444 return -1;
447 // Register the clerk with the Naming Service.
448 if (this->ior_fp_ == 0)
450 if (this->register_clerk () != 0)
451 return -1;
454 // Close the open file handler.
455 // ACE_OS::fclose (this->ior_fp_);
457 catch (const CORBA::Exception& ex)
459 ex._tao_print_exception (
460 ACE_TEXT ("(%P|%t) Exception in Clerk_i::init ()\n"));
461 return -1;
464 return 0;
468 Clerk_i::run ()
472 // Run the main event loop for the ORB.
473 int r = this->orb_manager_.run ();
475 if (r == -1)
476 ORBSVCS_ERROR_RETURN ((LM_ERROR,
477 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) Clerk_i::run")),
478 -1);
480 catch (const CORBA::Exception& ex)
482 ex._tao_print_exception (
483 ACE_TEXT ("(%P|%t) Exception in Clerk_i::run ()\n"));
486 return 0;
489 void
490 Clerk_i::insert_server (CosTime::TimeService_ptr server)
492 // We duplicate the capacity of the Array.
493 size_t s = this->server_.size ();
495 if (this->server_.max_size () == s)
496 this->server_.max_size (2 * s);
498 this->server_[s] =
499 CosTime::TimeService::_duplicate (server);
501 this->server_.size (s + 1);