• Basic Time Service: provides an interface to create objects representing time (a time stamp, for example) and intervals of time.
• Timer Event Service: provides an interface to manage Timer Event Handler objects. These objects are used to generate time based events based on user defined time settings.The OMG Time Service Specification defines time using the Universal Time Coordinated (UTC) representation. The UTC representation uses hundreds of nanoseconds (10-7 seconds) as its basic unit of time, with its base time set at 15 October 1582 00:00:00 GMT. A range of approximately 30,000 years A.D. is supported by the UTC representation.Similarly, the UTC representation defines a intervals of time or “relative time”. Like regular time, the basic unit of a relative time is 10-7 seconds. Ranges can span approximately plus-or-minus 30,000 years.
• Get the current time with associated inaccuracy in a UTO object via the universal_time operation.
• Get the current time and associated inaccuracy in a UTO object if the criteria for a secure time source can be met via the secure_universal_time operation.
• Create a UTO object to represent arbitrary time called a new_universal_time object.
• Create a UTO object from UtcT structure, via the uto_from_utc operation.
• Create a TIO from the new_interval operation.The Timer Event Service provides a mechanism by which you can receive notifications when an event gets triggered. In other words, Timer Event Service provides a kind of alarm service. Your programs can register a CosEventComm::PushConsumer callback object with the Timer Event Service and obtain a special event handler object that provides operations to set and cancel alarms. When an alarm goes off, the Timer Event Service sends a notification to the callback object.A Timer Event Handler object holds information about an event that is to be triggered at a specific time and the action to be taken when the event is triggered. The action taken is basically a call on the push method on the CosEventComm::PushConsumer object registered as the event handler. This method takes a CORBA::Any which contains the data to be pushed (the data is also specified when the event handler is registered with the event service).
• Querying whether an event has been triggered with the time_set method.
• Querying the status of the Timer Event Handler with the status method.
• Setting the time for an event to trigger an alarm with the set_timer method.
• Canceling a trigger that has yet to go off with the cancel_timer method.
• Setting the data to be pushed when the event is triggered with the set_data method.
•
• Un-registering a previously registered event handler with the unregister method.
• Getting the time at which an event was triggered with the event_time method.Only administrators authorized by the system security policy may set the time and specify the source of time. Once this is guaranteed the administrator can configure the Time Service to return secured time. With this in place it can be safely assumed that the underlying time source is secured and calling a secure_universal_time operation on the Time Service interface will return a secured time. If the underlying time source is not secured, a CosTime::TimeUnavailable exception will be raised upon invocation of the secure_universal_time operation on the Time Service interface.The VisiTime Service can be started by using the timeserv launcher located in the bin directory of your VisiBroker installation. Running this command starts both the VisiTime Service and “Timer Event Service”. The command syntax is:
The general driver options are also available for both UNIX and Windows. See the VisiBroker for C++ Developer’s Guide or VisiBroker for Java Developer’s Guide for more information.
When the underlying time source is secure and follows the guidelines given in Appendix A of the OMG Time Service specification, then the VisiTime Service can be started as a secure Time Service. Calls to TimeService::secure_universal_time would succeed in this case. Note that here security only refers to the security of the underlying time source. To start a secured VisiTime Service:
• Using the ORBInitRef command-line option.
• Using the ORBDefaultInitRef command-line option.When using either of the command-line options, client applications can make use of the ORB's resolve_initial_references method to obtain the Time Service or the Timer Event Service. For example:The most common usage scenario for ORBInitRef is to use a corbaloc URL to specify the initial reference. Other URL schemes are also possible. For example, using the IOR string or the file URL (Java only) to specify the name of the file containing Time Service IOR. The following commands bootstrap the Time Service and Timer Event Service running on port 5566 to the client application:Like ORBInitRef, ORBDefaultInitRef commonly uses corbaloc URLs to specify initial references. Other URL schemes are valid as well, depending on your implementation. The following command bootstraps both the Time Service and the Timer Event Service to the client application, using ORBDefaultInitRef:You can also specify the ORBDefaultInitRef as a property with the vbj command starting the client application. The following command also bootstraps the Time Service, but specifies ORBDefaultInitRef as a property:Client applications can also make use of the VisiBroker bind method to get the initial reference to the Time Service and the Timer Event Service from the SmartAgent. In Java the TimeServiceHelper and TimerEventServiceHelper classes are used to perform the bind. When executing the method, you specify the name of the Time Service and Timer Event Service to which you're connecting (and in Java, the ORB hosting them). For example:CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
// Get reference to Time Service
CosTime::TimeService_var time_svc = CosTime::TimeService::_bind("VBTimeService");
// Get reference to Timer Event Service
CosTimerEvent::TimerEventService_var timer_svc =
CosTimerEvent::TimerEventService::_bind
("VBTimerEventService");org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Get reference to Time Service
org.omg.CosTime.TimeService timeSvc =
org.omg.CosTime.TimeServiceHelper.bind(orb,
"VBTimeService");
// Get reference to Timer Event Service
org.omg.CosTimerEvent.TimerEventService timerSvc =
org.omg.CosTimerEvent.TimerEventServiceHelper.bind(orb,
"VBTimerEventService");Regardless of whether the Time Service is using in-process or out-of-process execution mode, user applications will use orb.resolve_initial_references("CosTimeService") and orb.resolve_initial_references("CosTimerEventService") to obtain initial references to the Time Service and Timer Event Service respectively. There would be a difference in the bootstrapping mechanism for in-process and remote Time Service respectively. User applications should not specify the ORBInitRef property with in-process Time Service. Instead, they must enable the VisiBroker property vbroker.time.enableInProc=true. If ORBInitRef is used together with vbroker.time.enableInProc=true, only ORBInitRef will take effect.The value for the vbroker.time.ntp.addr can be one or a sequence of comma-separated strings representing the NTP Server addresses. Both IPv4 and IPv6 format addresses can be specified as well. For example, consider three NTP server addresses given here:The first address, foo.com, relies on the internal DNS lookup. Since no port is specified, the default NTP port 123 is used. The second entry, [fe220::103:baaa:fbbb:fedf]:123, is an IPv6 format address enclosed in square brackets. Here, the port is defined specifically as 123. The final entry, 101.121.145.100:124 is the familiar IPv4 format, with the port number 124 specified as well.The VisiTime Service will first try to contact the first NTP Server in the sequence. If the address is valid and the server is available, the time of the NTP Server will be returned to the caller. Assuming that the first server in the list was not available, the implementation will transparently fail over to the second in the list and so on until it retrieves the required time value from one of the Server in the list. If all of the Servers are unreachable, VisiTime Service will throw an exception to the caller. Depending on the method called, the exception can be either CosTime::TimeUnavailable or a CORBA system exception such as COMM_FAILURE.
The listener port for the Time Service. The default value of 0 means any random port will be picked. This property does not take effect if the listener port is set through the Server Manager's vbroker.se.iiop_tp.scm.iiop_tp.listener.port property.
Tells the Time Service that the Time Source is a secured one. When this property is true, a call to secure_universal_time will always succeed. Otherwise, it throws the TimeUnavailable exception.
Where addr is the host name such as myhost.com or an IP address. Both IPv4 and IPv6 addresses are supported. IPv6 addresses must be enclosed in square brackets. The port is optional. If not specified, the default Time Service port 123 is used. When multiple addresses are specified, then NTP server failover happens if communication with one of the servers fails. The Time Service will try all the servers before throwing a TimeUnavailable exception. The VisiTime Service interface TimeService provides methods for creating UTOs and TIOs, but doesn't provide any methods to deactivate/destroy these Objects. VisiBroker's TimeService implementation uses the default servant-based dispatch mechanism limiting the number of these objects, meaning that for any number of these references the real servant processing the request is only one. You will not, therefore, need to be concerned with a large number of Time Service objects--UTOs and TIOs--being created. You use the TimeService interface to create UTOs and TIOs. Before creating these objects, you must resolve to the Time Service and narrow it (using the TimeServiceHelper in Java). The following code samples explain how to do this://Initialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
//Resolve the TimeService interface
CORBA::Object_var obj_t = orb->resolve_initial_references("CosTimeService");
//Narrow the TimeService interface
CosTime::TimeService_var time_svc = CosTime::TimeService::_narrow (obj_t.in());import org.omg.CORBA.ORB;
import org.omg.CosTime.*;
...
//Initialize the ORB
ORB orb = ORB.init(args, null);
//Resolve the TimeService interface
org.omg.CORBA.Object obj = orb.resolve_initial_references("CosTimeService");
//Narrow it properly using the Helper
TimeService timeService = TimeServiceHelper.narrow(obj);Once you have resolved to and narrowed the TimeService interface, you can use it to create UTOs and TIOs.Use the TimeService method universal_time() to create a Universal Time Object containing the current time. For example,creates a Universal Time Object uto whose time value is the current time at the execution of the method.You can also create a UTO containing a relative time of your choosing (not obtained using a Time Source) using the new_universal_time method. You provide three arguments to this method:
• the 64-bit time value. This is the number of hundreds of nanoseconds that have elapsed since base time and is a C++ CORBA::ULongLong or Java long data type.
• the time displacement factor value (in the form of minutes of displacement from the Greenwich Meridian), a C++ CORBA::Short or Java short data type.CosTime::UTO_var uto = time_svc-> new_universal_time
((CORBA::ULongLong)10000000,0,(CORBA::Short)0);You can create TIOs using the TimeService interface. The new_interval method takes two arguments of type CORBA::ULongLong (C++) or long (Java), which are the bounds of the time interval expressed as hundreds of nanoseconds since base time. For example://Create a TIO that represents a specific interval
CosTime::TIO_var tio =
time_svc->new_interval((CORBA::ULongLong)10000000,
(CORBA::ULongLong)20000000);//Create a TIO that represents a interval TIO tio
= _timeService.new_interval(10000000L, 20000000L);This section explains how to resolve to a Timer Event Service, obtain TimerEventHandlers, set alarms using the TimerEventHandlers, cancel an alarm that was previously set, and unregister a TimerEventHandler.Before creating and utilizing TimerEventHandlers, you must resolve to the Timer Event Service itself, as well as the ORB's standard Event Service providing the PushConsumer object. For example://Initialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
//Resolve the TimerEventService
CORBA::Object_var obj_t = orb->resolve_initial_references("CosTimerEventService");
CosTime::TimerEventService_var time_evsvc =
CosTime:: TimerEventService::_narrow (obj_t.in());
//Resolve to the EventService
CORBA::Object_var obj_ev = orb->resolve_initial_references("EventService");
CosEventChannelAdmin::EventChannel_var channel =
CosEventChannelAdmin::EventChannel::_narrow(obj_ev.in());import org.omg.CORBA.*;
import org.omg.CosEventComm.*;
import org.omg.CosEventChannelAdmin.*;
import org.omg.CosTime.*;
import org.omg.CosTimerEvent.*;
import org.omg.TimeBase.*;
...
//Initialize the ORB
ORB orb = ORB.init(args, null);
//Resolve the TimerEventService
TimerEventService timerEventService=TimerEventServiceHelper.narrow(
_orb.resolve_initial_references("CosTimerEventService"));
//Resolve to the EventService
EventChannel channel =
EventChannelHelper.narrow(_orb.resolve_initial_references("EventService"));The Timer Event Service provides an operation to register a CosEventComm::PushConsumer together with a CORBA::Any that provides event data. Internally, an instance of TimerEventHandler is created, with which the event data and PushConsumer are associated. You can at any point change the event data, but the PushConsumer is immutably associated with the TimerEventHandler and cannot be changed.
1 Create a ProxyPushSupplier object to push the event data to the consumer.
2 Create a PushConsumer object to receive the event data.
3
4 Obtain a ProxyPushConsumer object from the event channel. This is the object that will be registered with the Timer Event Service.
5 Create the event data with a new CORBA::Any.
6 Create the event handler by executing the Timer Event Service's register method, using the ProxyPushConsumer and the CORBA::Any objects as arguments.
In order to use your newly-created TimerEventHandler, you set alarms using the EventTimer interface. The set_timer method is used to set an alarm. It takes two arguments: the type of alarm and a UTO object. Three types of alarms are available:
• TTAbsolute: the alarm is triggered at an absolute time specified by the UTO.
• TTRelative: the alarm is triggered at the UTO relative to the current time (the UTO represents time from the current absolute time, not the time base).
• TTPeriodic: the alarm occurs periodically, repeating at each relative time specified by the UTO.
1
3 Use the Event Handler's set_timer method to set the alarm.To cancel an event handler's timer, simply execute the handler's cancel_timer method:To unregister an event handler entirely, call the event service's unregister method:This is an object with a friendly interface to convert the 64-bit time representation to human readable components like year, month, day etc and vice versa: the TimeI object. The TimeI object can be viewed as a representation conversion object. The general technique for using it is to create one using the operation FriendlyTime::TimeService::time(). This creates a TimeI object with time set to zero in it. Then the _set operations can be used to set the values of the various attributes. Finally, the attribute time can be used to get the corresponding TimeT value.Conversely, one can set any TimeT value in the time attribute and then get the year, month, and so forth. from the appropriate attributes.