1 #include "orbsvcs/Log_Macros.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"
15 : ior_output_file_ (0),
17 timer_value_usecs_ (0),
18 server_ (Clerk_i::DEFAULT_SERVER_COUNT
),
28 // Reads the Time Service Server iors from a file instead of using a
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"),
44 ACE_Read_Buffer
ior_buffer (f_handle
);
46 char *data
= ior_buffer
.read (EOF
,'\n','\n');
48 ORBSVCS_ERROR_RETURN ((LM_ERROR
,
49 ACE_TEXT("[CLIENT] Process/Thread Id : (%P/%t) Unable to read ior: %p\n")),
56 for (char *str
= ACE_OS::strtok (data
, "\n");
58 str
= ACE_OS::strtok (0, "\n"))
60 ORBSVCS_DEBUG ((LM_DEBUG
,
61 ACE_TEXT("iors -> |%C|\n"),
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")));
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
);
93 // Parse the command-line arguments and set options.
96 Clerk_i::parse_args (int argc
,
99 ACE_Get_Opt
get_opts (argc
, argv
, ACE_TEXT("dt:u:f:o:"));
103 while ((c
= get_opts ()) != -1)
106 case 'd': // debug flag.
110 case 't': // time in secs after which the clerk should update time.
111 this->timer_value_
= ACE_OS::atoi (get_opts
.opt_arg ());
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 ());
120 case 'f': // read the server IORs from a file.
121 result
= this->read_ior (get_opts
.opt_arg ());
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 ()),
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);
140 case '?': // display help for use of the server.
143 ORBSVCS_ERROR_RETURN ((LM_ERROR
,
144 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t)")
145 ACE_TEXT("usage: %s")
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>")
156 // Indicates successful parsing of command line.
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
,
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");
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
195 server_context
->list (1,
196 bindings_list
.out (),
198 CosNaming::Name server_name
;
199 server_name
.length (1);
200 server_name
[0].id
= bindings_list
[0u].binding_name
[0].id
;
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")),
214 // Insert the first server IOR into the unbounded set of server
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 ")),
226 catch (const CORBA::Exception
& ex
)
228 ex
._tao_print_exception (ACE_TEXT("Exception"));
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"));
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_
,
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_
,
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"));
339 // Binds the clerk in the context ClerkContext with the name
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"));
389 // Initialize the Clerk.
392 Clerk_i::init (int argc
,
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(),
412 ORBSVCS_ERROR_RETURN ((LM_ERROR
,
414 ACE_TEXT("init_child_poa")),
418 this->orb_
= this->orb_manager_
.orb ();
420 // Parse commandline arguments.
421 if (this->parse_args (command
.get_argc(), command
.get_TCHAR_argv()) !=0 )
424 // If IOR file has not been specified then try the Naming
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 )
436 // Get a reference to the Server Naming context and the
438 if (this->get_first_IOR () != 0)
442 // Create an instance of the Clerk.
443 if (this->create_clerk () != 0)
447 // Register the clerk with the Naming Service.
448 if (this->ior_fp_
== 0)
450 if (this->register_clerk () != 0)
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"));
472 // Run the main event loop for the ORB.
473 int r
= this->orb_manager_
.run ();
476 ORBSVCS_ERROR_RETURN ((LM_ERROR
,
477 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) Clerk_i::run")),
480 catch (const CORBA::Exception
& ex
)
482 ex
._tao_print_exception (
483 ACE_TEXT ("(%P|%t) Exception in Clerk_i::run ()\n"));
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
);
499 CosTime::TimeService::_duplicate (server
);
501 this->server_
.size (s
+ 1);