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"
14 Clerk_i::Clerk_i (void)
15 : ior_output_file_ (0),
17 timer_value_usecs_ (0),
18 server_ (Clerk_i::DEFAULT_SERVER_COUNT
),
24 Clerk_i::~Clerk_i (void)
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 (void)
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 ()))
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"));
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_
,
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_
,
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"));
341 // Binds the clerk in the context ClerkContext with the name
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"));
392 // Initialize the Clerk.
395 Clerk_i::init (int argc
,
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(),
415 ORBSVCS_ERROR_RETURN ((LM_ERROR
,
417 ACE_TEXT("init_child_poa")),
421 this->orb_
= this->orb_manager_
.orb ();
423 // Parse commandline arguments.
424 if (this->parse_args (command
.get_argc(), command
.get_TCHAR_argv()) !=0 )
427 // If IOR file has not been specified then try the Naming
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 )
439 // Get a reference to the Server Naming context and the
441 if (this->get_first_IOR () != 0)
446 // Create an instance of the Clerk.
447 if (this->create_clerk () != 0)
451 // Register the clerk with the Naming Service.
452 if (this->ior_fp_
== 0)
454 if (this->register_clerk () != 0)
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"));
476 // Run the main event loop for the ORB.
477 int r
= this->orb_manager_
.run ();
480 ORBSVCS_ERROR_RETURN ((LM_ERROR
,
481 ACE_TEXT("[SERVER] Process/Thread Id : (%P/%t) Clerk_i::run")),
484 catch (const CORBA::Exception
& ex
)
486 ex
._tao_print_exception (
487 ACE_TEXT ("(%P|%t) Exception in Clerk_i::run ()\n"));
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
);
503 CosTime::TimeService::_duplicate (server
);
505 this->server_
.size (s
+ 1);