|
SYS-CON.TV Webcasts
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Top Links You Must Click On
General Java The Java-CORBA Way to Large-Scale Software Design
The Java-CORBA Way to Large-Scale Software Design
By: E Ming Tan
Aug. 1, 1999 12:00 AM
In the CORBA-based, service broker framework, the data that's required and shared among various heterogeneous systems is coordinated in a synchronized manner by a server process, yet maintained locally by each participating system. Although lots of articles mention how to design a large-scale system, they often lack implementation details, due partly to the complexity of the issues involved. In this article I'll provide an example of a simple, generic and yet useful implementation of a large-scale system based on Java-CORBA architecture.
Background
CORBA-Based Service Broker
Technically speaking, each local application will instantiate its own copy of a client service broker (SBroker), which acts as a local proxy object for the remote object of the service broker. The SBroker proxy object can also become a factory object for each application, if there is such a need. This would reduce the overhead for naming service lookups from the CORBA client application. The remote service broker server is implemented as a normal CORBA server. A client service broker can communicate via IIOP with a component that's a reachable CORBA object, called a service broker moniter, hosted by the service broker server. If you look at the SBroker code in Listing 1, you'll notice the getMonitor method and mon object of type monitor. This is the method that returns a CORBA object reference of the remote service broker server object, which is mon in this case. Referring to Listing 2, the service broker monitor basically allows a client to:
In this design I've chosen a pure Java-based ORB, JacORB (version 0.9f2) courtesy of Gerald Brose (brose@inf.fu-berlin.de) since it's a free open source with more features than the Java IDL of Java 2 (JDK 1.2) from Sun Microsystems. It allows you to test the example in this article without a commercial ORB product. However, the design should work with other commercial ORBs as well with minimal modification. JacORB is used in the CORBA-enabled service-broker framework in the following areas:
The service broker server architecture depicted in Figure 1 consists of a monitor CORBA object that has an event manager running as a separate thread, an optional Object Design, an ObjectStore ODBMS database for persistency and an ORB server, which is JacORB in this case, running a naming service as well as an Interface Repository (IR) daemon. Because broadcast events in this environment are asynchronous, I've used ObjectSpace's JGL 3.0 class library to maintain the events; it's popular and has many standard Java generic classes, plus I'm using JDK 1.1.6 to compile the framework. By the time this article is published, the JGL class library should be part of Java 2 and known as the Collection API. JGL's Queue class is used in the following manner (see Listing 2):
The next JGL class used is HashMap. It's used to keep the object reference of the listeners to facilitate the event-manager thread to call back the listeners. In this design example (see Listing 2) the listeners are associated with their unique application ID as the key. Alternatively, one can try out Object Manager JGL version 3.1 for ObjectStore, available free from Object Design's Web site. The modified version of the JGL library, which directly supports persistency via a scalable ObjectStore database, is known as dJGL. According to Object Design, ObjectStore PSE Pro 3.0 can recover from an application failure or system crash. If an application (in this case the service broker server) fails during a transaction, when you restart it, it'll return to the way the database was prior to the transaction. If an application fails during a transaction commit, when you restart it, the database will be either the same as it was before the transaction or it will reflect all of the transaction's changes. It depends on how far along in the commit process the application was when it terminated. ObjectStore ODBMS is a full-blown enterprise object database. It's also compatible with JDK1.2 Collection API, but the details aren't covered in this article.
The Assumptions
If you need to broadcast more than one event at any time, a slight modification of the service broker server codes is needed. A more involved change is necessary if you wish to broadcast a specific event to more than one listening application. Some may argue that the word broadcast itself is a misnomer, since broadcast often means the target is more than one entity. Remember, the example given here is an oversimplified implementation. If there's a need to broadcast to more than one listening application using the same event, the event manager has to call back all the applications that are interested in the event before removing the event from the queue. Multiple sources broadcasting to a listener with the same event is also not advisable, though it's possible with some modifications.
A Typical Scenario When the service broker starts up, it will bootstrap its CORBA object and make it available to all source and listener applications (see Figure 2a). In this case the server registers its monitor object with the COSS naming service. After the server is ready, the framework is ready for virtually any source application to broadcast an event as well as any listening application to process it. Assume that Application 2 needed to send data to Application 1. Typically, Application 1 will have to register itself with the service broker server. Remember, in this framework every application will have a local service broker proxy called SBroker. That's why you see a D-shaped capsule-like structure on top of each application. SBroker encapsulates the CORBA implementations from all participating applications in this framework. In other words, a source application that needs to broadcast an event (publish an event via the service broker server) to a listening application has to instantiate an SBroker object. The listening application has to do the same thing in order to subscribe to the event (pushed by the server once it's available). This is done by registering itself as a listener with the server (see Figure 2b). The following code snippet shows you how to instantiate the monitor object from an application and obtain the remote object reference: monitor mon = (new SBroker()).getMonitor(); Once the remote instance of a service broker object is obtained, registering listeners or broadcasting an event are straightforward steps. To register as a listener (see Listing 3 for a sample listerner code), an application invokes addRadioBroadcastListener of the monitor object. The following code snippet shows you how to do that:
//=== instantiate a copy of the listening application If you need to remove an application from listening, the application invokes the removeRadioBroadcastListener method of the monitor object as follows:
//=== remove itself from listening if there is a need How does a source broadcast an event? By notifying the service broker (see Figure 2c), which is done by invoking the notifyRadioBroadcastListeners method of the monitor object. The following code snippets show you that:
//=== instantiate a copy of the source application As you've noticed by now, to broadcast an event via the service broker server by sending a notification message involves more steps than becoming a listener. In line 2, we're basically creating an event object to be sent to the listener. In this case it's assumed the event ID is the application ID (which is 800). An application ID is just a unique number assigned manually by the application developer. If the same ID has already been allocated to another registered application, registration of the new listener with the monitor will fail (see line 1). Next (in line 3), we set the type of the event, since an application can have multiple data that needs to be processed in different ways. Each event type may be associated with one or more data. The real pushing of an event to the service broker is done in line 4. Nevertheless, if the previous event (which has an ID of 800) is still not processed by the listener, this method call would fail with a return status of false. The role of the service broker server is to receive events from the source and push them to the listener by calling back the broadcastPerformed method of the listener. In our scenario the service broker will call back Application 1 (shown in Figure 3a). Thus a listener must be a type of org.omg.CORBA.CORBject object too (see Listing 4). What follows is the most critical step as far as the business environment is concerned - the exchange of data between applications. Application 1 (listener application) retrieves the data from Application 2 (source application) via a peer-to-peer communication (see Figure 3b). Surprisingly, this framework makes no assumption of any method to achieve that. You may ask why. A simple answer is because it's meant to be generic! Nevertheless, one may find getDataRetrieveMethod and getDataStoreMethod methods of the RbEvent class useful (see Listing 5). They're the placeholders where you can specify how to retrieve the data from the source application and/or how to store the data in the listening application (e.g., if the data format is different). It may include properties like a host name, FTP server name, data server name, user name and password, or even jdbc strings. It can even be the data itself, e.g., the XML data. It's up to you to decide which methods you're most comfortable with or are most suitable for your specific environment. The following code snippet shows you an example of the inside of a listening application:
public String getDataRetrieveMethod() { In the example above, the source application happened to be a legacy system with no other means of communication except FTP protocol. You'll notice that the getDataRetrieveMethod returns enough information for retrieval purposes. In this case the listening application is a UNIX box and the downloaded file is local as far as the listener is concerned. Therefore it doesn't need to include much information in the getDataStoreMethod method. Of course, a proper way to set all these properties is via setter methods such as setDataRetrieveMethod and setDataStoreMethod. Last, as soon as the data is fully transferred from Application 2 to Application 1, the callback returns control to the event manager of the service broker. When this happens, the event manager removes the event object from the queue and continues with the next event, if there's any in the queue (see Figure 3c). The whole process repeats itself relentlessly (from Figures 2b to 3c), and now we have a new service broker framework based on CORBA.
What Did I Miss?
The event manager is very simple too. Currently, a listener's object reference isn't purged from the HashMap even if the listener crashed or died, resulting in an error when the listener restarted and tried to register itself again with the same application ID. If this happens, the easiest way to work around it is to restart the service broker server and all applications involved in the framework. Due to a similar problem, if a source tries to broadcast an event to an invalid listener (crashed/died or not running for whatever reason), the listener-bound event isn't processed and other subsequent events (if any) are blocked. The event should have been discarded if its associated application ID is no longer valid and the source application should be informed about the status of the event. Another way of overcoming this is to set a certain timeout period for each event processed so that if the corresponding listening application is unreachable, the event will be rendered invalid. Once the event is made invalid, the source application will realize this just before it's about to generate a new event for the listener.
Other Considerations
The following code snippet shows how minimal additions (in blue) into the service broker server codes (see Listing 2) will provide the transactional support commonly required in business environments:
...
public class monitorImpl extends Thread implements monitor
Database db = null;
queue = new Queue();
private static Database create(String dbName) {
...
tx = Transaction.begin(ObjectStore.UPDATE);
if ( !queue.isEmpty() ) {
tx.commit();
}
Besides the transactions, you should consider the security issues as well. A mechanism needs to be in place so that only valid or authorized sources or listeners can broadcast events or register and receive the events, respectively. Other enhancements may include cross-system exceptions mapping and a centralized logging facility.
Conclusion
Reference
Reader Feedback: Page 1 of 1
Enterprise Open Source Magazine Latest Stories . . .
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||