CORBA Event Service used to be the middleware of choice for handling distributed callbacks. Now there's CORBA Notification Service, and it's improved the whole process.
When client/server programs attempt to communicate with different types of computers with various operating systems and programming languages, it's similar to the United Nations in session-not much gets done without the translators. In this article, we demonstrate a new middleware, the CORBA Notification Service, and compare it to the older CORBA Event Service.
In the middle
Developing portable client/server programs that can communicate between different types of computers and programming languages has lately been a goal in the world of computing. Called distributed object or heterogeneous computing, this type of computing requires middleware to facilitate communication between disparate hardware and software. Distributed object computing has three levels: presentation, application, and data storage and retrieval. Middleware services support the application (or middle) level of this type of computing. The purpose of middleware is to stand between diverse applications and handle low-level communications, while eliminating platform and language barriers.[1, 2, 3]
The Common Object Request Broker Architecture (CORBA) is a middleware standard provided by the Object Management Group (OMG), which addresses heterogeneous computing. In addition to alleviating the communication and migration barriers, CORBA provides services and facilities that enhance client/server computing.
CORBA Event Service
Since 1995, CORBA has provided the CORBA Event Service. The CORBA Event Service was intended to ease the problem of handling distributed callbacks. A distributed callback requires a server to call back to a client. Therefore, applications that use distributed callbacks act as both clients and servants. In CORBA, a servant refers to the actual CPU and memory resources chosen to execute an object. When distributed callbacks are employed, a server must keep a list of all callback registrations. When a timeout occurs, the server must deliver the event to all clients with registered callbacks in a timely manner. This process can be difficult to implement efficiently. The CORBA Event Service, however, helps the process along by providing callbacks, while keeping the client and server decoupled. Figure 1 shows a typical CORBA Event Service environment.
Figure 1: CORBA Event Service
In the CORBA Event Service, consumers receive events and suppliers produce events. In Figure 1, the CORBA client is a consumer, and the CORBA server is a supplier. The CORBA Event Service can operate using two different models: the push model and the pull model. With the push model, the supplier pushes an event into the event channel. The event channel then delivers the event to all registered consumers. With the pull model, the consumer requests an event from the event channel, which then requests the event from the supplier. The Event Service can also employ a hybrid push/pull model or a hybrid pull/push model. The environment shown in Figure 1 implies that a push model is being used, with the CORBA server being the event supplier and the CORBA client being the event consumer.
The primary advantage of the CORBA Event Service is that it provides a flexible callback model, while decoupling clients from servers. However, the CORBA Event Service also has several limitations. Among these limitations are the following:
- Event filtering is not supported: Only one type of event can be handled per event channel. To use multiple events requires multiple event channels.
- There is no hierarchical structure for events. Events on their separate event channels are equal (code must be written in the consumer to handle them differently).
- The CORBA Event Service interfaces do not provide different qualities of service (QoS).
CORBA Notification Service
The CORBA Notification Service was developed to address the limitations of the CORBA Event Service. The primary goal of the CORBA Notification Service is to enhance the Event Service by providing event filtering and QoS. Clients of the Notification Service subscribe to events they are interested in by associating filter objects with the proxy objects through which the clients communicate with the Notification Service. With the Notification Service, each channel, each connection, and each message can be configured to support QoS.
We recently performed a study for the United States Army. One of the primary tasks of our study was to create a working CORBA demonstration that employed the CORBA Notification Service in an environment applicable to the army. The army was interested in a real-time, embedded environment that could be used in deployed weapons systems. The army wanted to know if using the CORBA Notification Service would give them sufficient control over event handling. They were also interested in how well the Notification Service performed compared with earlier event handling techniques, distributed callbacks, and the CORBA Event Service.
For this study, we chose The ACE ORB (TAO) and its Notification Service. TAO Notification Service does not currently implement all aspects of the CORBA Notification Service; for example, pull interfaces and typed events are not yet supported. However, it does implement several QoS properties, including per-message event priority, order policy, discard policy, maximum batch size, pacing interval, and maximum events per consumer. It also supports the administration properties maximum queue length, maximum consumers, maximum suppliers, and reject new events. Although the intended ultimate target is an embedded system with a real-time operating system (RTOS), we used TAO Windows NT CORBA ORB version 1.1 in our study.
The CORBA Notification Service is built on top of the CORBA Event Service. CORBA Notification Service interfaces inherit directly from the Event Service interfaces, and have similar names to their corresponding Event Service interfaces. Since each Notification Service version of a particular interface inherits from the Event Service equivalent interface, an instance of the CORBA Notification Service can be widened to become an instance of the CORBA Event Service. The primary reason for this is to support backward compatibility with existing applications using the CORBA Event Service.
The CORBA Notification Service supports multiple instances of each consumer or supplier proxy interface. Additionally, it supports multiple instances of the ConsumerAdmin and SupplierAdmin interfaces. In the CORBA Event Service, only one ConsumerAdmin and one SupplierAdmin is employed per channel. For both the Event Service and the Notification Service, the ConsumerAdmin and SupplierAdmin establish consumer and supplier proxy objects. For example, a consumer would obtain a proxy push supplier object reference by calling obtain_push_supplier . The obtain_push_supplier operation is located within the ConsumerAdmin interface. With the Notification Service, event filtering and QoS operations can also be performed at both the ConsumerAdmin and SupplierAdmin objects.
The CORBA Notification Service supports three types of events:
- Untyped events (contained within an Any data type)
- Typed events, and
- Structured events.
Untyped events and typed events were previously supported by the Event Service, but the typed events in the Event Service were difficult to use. Structured events, which are new with the CORBA Notification Service, fix some problems associated with typed events. They provide a data structure to which many types of events can be mapped, which provides optimized event filtering.
Each structured event contains a combination of fixed data and filterable data. Each event contains a domain name, a type name, and an event name. The domain name specifies the vertical industry domain (for example, telecommunications or finance) in which the event type is defined. The type name contains the event's type within its domain (for example, StockQuote). The event name itself specifies the exact event that has occurred.
Notification Service style proxy objects can be subdivided into three categories based on the types of data sent and received: those that handle Anys, those that handle structured events, and those that handle sequences of structured events. Both push and pull types of each kind of proxy object are supported.
Notification Service style proxy objects have two kinds of filter objects associated with them: forwarding filters and mapping filters. Forwarding filters can be attached to all kinds of proxy objects, and constrain the events that can be forwarded by the proxy object. Mapping filters can only be attached to supplier proxy objects, and affect the lifetime properties of the events received by the supplier proxy object. Both proxy objects and the Admin objects can have filters associated with them. Each can have different filters. The CosNotifyFilter module defines the filter interfaces, CosNotifyFilter::Filter and CosNotifyFilter::MappingFilter .
Both the CosNotifyFilter::Filter interface and the CosNotifyFilter::MappingFilter interface contain three match operations, one to handle Any events, one to handle structured events, and one for typed events. To add, modify, or remove constraints to a forwarding filter, the operations add_mapping_constraints , modify_mapping_constraints , and remove_all_mapping_constraints are employed. To add, modify, or remove constraints to a mapping filter, the operations add_mapping_constraints , modify_mapping_constraints , and remove_all_mapping_constraints are employed. The main difference between the Filter interface and the MappingFilter interface is that mapping filters also associate a value with each constraint. This enables only events with certain ranges of values to be forwarded, whereas the Filter interface looks only at event types and not event values.
Quality of service
The CORBA Notification Service handles the following quality of service properties:
- Reliability (event reliability and connection reliability, with values of best effort or persistent)
- Priority (-32,767 to +32,767)
- Expiry times (such as timeout)
- Earliest delivery time
- Maximum events per consumer
- Order policy (the order in which events are delivered, such as any order, FIFO order, or priority order, among others)
- Discard policy (the order in which events are discarded, similar to order policy)
- Maximum batch size (max number of events allowed in an event sequence)
- Pacing interval (the max amount of time events in a sequence will be collected before being delivered to a consumer)
Certain QoS properties can be set at certain levels. For example, priority and timeout can be set per-message, per-proxy object, per-admin object, or per-channel. None of the other QoS properties, however, applies to all levels, since not all properties make sense at all levels. PacingInterval , for example, is not supported at the per-message level because it doesn't make sense at that level.
Although you can use your own constraint grammar, the default constraint grammar supported by the CORBA Notification Service is an extended version of the constraint grammar previously employed in the CORBA Trading Service, with some modifications to clear up ambiguities in the Trader Constraint Language (TCL), and to provide some new features needed by the Notification Service. Consider the following example constraint:
$.header.fixed_header.event_type.type_name=='SystemAlarm' and $header.fixed_header.event_name=='IllegalSystemOverride' and $header.variable_header(priority) > 50
'$' means the current event (this is an extension to the TCL). Any member of the fixed header or any property in the filterable data can be represented as runtime variables. Note that a shorthand version is also available that accesses the event subfields directly:
$type_name=='SystemAlarm' and $event_name=='IllegalSystemOverride' and $priority > 50
Notification Service example
As we said earlier in the article, we developed an architectural prototype for the U.S. Army using the Notification Service. The prototype is a simulation of environmental quality detection, such as the Environmental Protection Agency might use. Although the application domain is nonmilitary, monitoring and controlling remote sensors using an arbitrary number of clients correlates to the army's application.
Sensors for temperature, water quality, and air quality were located at two lakes, Lake Guntersville and Lake Lanier. They sampled the temperature, water quality, and air quality periodically. We implemented the prototype in stages. Each stage built on the previous stage, and exercised the CORBA Notification Service features in the manner the army team was considering for their application. First we implemented the environmental simulation using sensor values returned on request to the client. Then we implemented a separate, simple example using callbacks, so we could demonstrate the positives and negatives associated with callbacks for the army. Finally, we looked at using the CORBA Notification Service with the environmental example.
The simple callback code we developed is shown in Listings 2 through 9. The callback code shown here implements a simple echo operation. Listing 2 contains the client startup code. This calls the client and the local server (or clientserver, which awaits callbacks) as separate threads. Listing 3 contains the client code. (The show_chunk and list_contest routines are not shown. They are available in Henning and Vinoski, p. 806). We found show_chunk and list_context helpful later in determining whether the CORBA Naming Service, which provides a central place where names can be mapped to specific addresses, had knowledge of the running Notification Service). Listings 4 and 5 contain the interface definition language (IDL) files that describe the interface. Listing 4 describes the “forward” interface, while Listing 5 describes the “callback” interface. Listing 6 contains the basic server code. Listing 7 contains the implementation of the echo interface. Listing 8 contains the server startup code, which calls the server and the local client (called serverclient, which is used to send callbacks) as separate threads. Listing 9 contains the serverclient itself. The serverclient asks for events from the keyboard, which it then sends to the remote.
NOTE: All listings for this article are located at ftp://ftp.embedded.com/pub/2002/CORBA/listings
Several problems can arise when using callbacks in this simple form. The primary problem with this scenario is that all clients that wish to receive callbacks must have a callback interface between that client and the server that sends the callbacks. If 1,000 clients want to receive callbacks, the server must have object references for each of the 1,000 clients and must send a separate message to each in turn. In an embedded environment, this could be an excessive burden both in terms of time taken to send the messages and memory used to store the object references. Particular problems can arise when an arbitrary number of messages (determined at runtime) must be sent quickly enough to meet a hard deadline. Having too many messages could result in missing the deadline.
An example of the code to send a simple echo message is shown in the event loop in Listing 9. This code would have to be within a loop that executed 1,000 times, accessing each client. Other problems relate to the possibility that one or more of the 1,000 clients could potentially have a bug that affects the server. Henning and Vinoski say, “In general, it is difficult to write callback-based applications that scale well. If there are enough callbacks to deliver, the work the server application must do to deliver them eventually outweighs the processing it was originally written to perform. If that were not enough, dealing with uncooperative clients can block or even hang the server.”
The advantage with using distributed callbacks in the past, compared to the CORBA Event Service, is flexibility. Each callback could be handled separately, while each new event required a new version of the Event Service to be running. However, as mentioned above, the CORBA Notification Service removes many of the earlier CORBA Event Service limitations. Additionally, the army had a set of requirements for any service used: portability to many hardware environments, embeddability, and efficiency being the most important.
We initially investigated the Notification Service example provided by TAO. Unfortunately, this code, like most of the code provided by TAO, employed the ACE macros almost exclusively. ACE stands for A Communication Environment, which is the large communication framework on which TAO is based. TAO implementers prefer you to make use of ACE macros, and, in some cases, this does result in improved performance. However, ACE macros make the code unportable to a different ORB, which conflicted with the army's specification. Therefore, we completely rewrote the TAO notification example by removing all ACE macros and replacing them with standard CORBA code. This is usually straightforward, but sometimes the macros have side effects. We went through several iterations with some of the macros before we successfully removed all side effects.
Then we added our Notification example to the sensor example we had already written. Our Notification example uses the push model for event handling. The IDL file for our environmental example is shown in Listing 10. Note that there is a separate Get() operation for each interface. This was used in our original environmental example and was not explicitly removed. To view our entire environmental example, go to ftp://ftp.embedded.com/pub/2002/CORBA. Listing 1 gives the commands required to run the environmental example. Note that we allowed each side to send itself events. If the client is compiled with #define SUPPLIER 1 , then it will generate local events. If it is compiled with #define CONSUMER 1 , then it will expect to receive events from a remote server.
Listing 11 shows the code to create the notification channel using the Notify factory. Here the notification channel is created, and an attempt is made to bind the notification channel to the CORBA Naming Service under the name “myNotifyChannel.” If that channel was already bound to the CORBA Naming Service, then the new notification channel is not used; rather, the existing notification channel is resolved. Note that for this code to work, the Notify factory must have been previously resolved, in a similar manner. The CORBA Naming Service is another CORBA service that provides a central place where names can be mapped to specific addresses.
Listing 12 shows the code to create a SupplierAdmin object, and to append a filter, with constraints, to this object. Note that setting up the ConsumerAdmin is analogous to this example. Filters are created using a filter factory.
Here we have selected constraints that limit a temperature event as follows: 10 < Temperature < 70. The constraint "Temperature > 10″ is set on the SupplierAdmin object, and the constraint “Temperature > 70” is set on the ConsumerAdmin object. We could alternately have set both constraints on a single filter object, located at either the SupplierAdmin or ConsumerAdmin interface. Similarly, we could have set both constraints on a single filter object located on a particular consumer proxy object, or, alternately, on a particular supplier proxy object. We chose these constraints in this manner to illustrate that different constraints can be set on the same event at different locations. This type of flexibility was important to the army's applications.
Listing 13 shows the code to create a consumer proxy object, which you'll notice is similar to the code used to create a supplier proxy object. When running this consumer proxy object code, we had trouble getting some TAO CORBA calls to compile without using the ACE exceptions. Having encountered and reported a similar problem, we believe that for the version of ACE/TAO we used, you must employ some ACE exceptions. As you may know, the ACE environment provides its own exceptions, which ACE usually prefers to native exceptions. We use the ACE exceptions because we occasionally have trouble compiling various TAO CORBA calls without them. We haven't tried our code on more recent versions of ACE/TAO, for which we hope the exception issue is less of a problem. It's also possible we had a problem with our compilation settings when we compiled our version of ACE/TAO. We did not pursue this extensively due to time constraints.
In Listing 14 we show the code to send a series of events. We set the domain type and the type name for all events to the wild card character, which indicates all types of domains and types are supported. We set the event name itself to our particular event name, “myevent.” We did not put any values in the variable header field. Then we sent 30 separate events containing new values for air quality, temperature, and water quality, with all the values for air quality, temperature, and water quality placed in the filterable data field of the structured event. Again, some of TAO calls required ACE exceptions to compile, which then required us to use the ACE macros to catch the ACE exceptions.
Listing 15 shows the implementation of the local consumer. Each received event's filterable data is extracted. Again, in this example, we were unable to compile TAO code without the ACE exceptions.
Sizing up the service
We were able to successfully demonstrate the use of the CORBA Notification Service in TAO in an environment interesting to the army. We showed the army the advantages of the CORBA Notification Service over simple distributed callbacks. We were also able to discuss the advantages provided by the new CORBA Notification Service over the old CORBA Event Service.
The primary concerns we have with the CORBA Notification Service lie in the efficiency of a particular implementation. An implementation's efficiency, in both memory usage and speed in filtering and sending events to clients, could potentially affect its usability in the army's intended task environment. How well an implementation handles large numbers of clients and servers is also an issue. The efficiency of particular CORBA Notification Service implementations using the RTOSes employed by the army requires further study. Although performance is critical in the army's intended task environment, this study was concerned only with architectural features.
Recently, several ORBs have added implementations of the CORBA Notification Service. ORBacus , omniORB, Visibroker, and e*orb all currently have Notification Services; others, such as MICO, have not yet added Notification Services.
Letha Etzkorn is an assistant professor at the University of Alabama in Huntsville, where she has recently worked on two CORBA contracts for the US Army. Prior to returning to academia, she worked in real- time embedded systems for Motorola and Hayes. She has a BSEE and MSEE from the Georgia Institute of Technology, and an MSCS and Ph.D. from the University of Alabama. Her e-mail address is .
Joel Sherrill is director of R&D at OAR. He has 15 years experience in commercial and military real-time embedded applications and related research. He is active in the free software community as the maintainer of the RTEMS RTOS and as a member of the Steering Committee for the Free Software Foundation's GNU Compiler Collection. He received his BS from University of Tennessee and his MS and PhD from University of Alabama. Contact him at .
Ron O'Guin is executive vice president of OAR. He has more than 25 years of experience in the development of real-time applications, visual simulations, and trainers in the video production, telephony, and military domains. He is a principal author of the open-source RTEMS RTOS. He received his BS at the University of Southern Mississippi and MS at University of Alabama. He can be reached at .
1. Siegel, J., “CORBA 3: Fundamentals and Programming,” Object Management Group, 2000.
2. Henning, M, and Vinoski, S., Advanced CORBA Programming with C++, Addison Wesley Longman, 1999.
3. Ironside, E., Etzkorn, L., and Zajac, D., “Examining CORBA Interoperability,” Dr. Dobbs Journal, June, 2001, pp.111-122.
4. “Notification Service,” Object Management Group, 1999.
All listings for this article are located at ftp://ftp.embedded.com/pub/2002/CORBA/listings