CORBA and EJB Interfaces to the ACS

by Rob Mayoff

ACS Documentation : Systems Integrator's Guide to the ACS : CORBA and EJB Interfaces to the ACS


ACS4: Work In Progress

Introduction: Why Remote Procedure Call Interfaces?

The ArsDigita Community System already provides two interfaces: a web interface (HTML over HTTP), and a database schema. Why would you want a remote procedure call interface, either CORBA or EJB? Using a web interface programmatically is difficult because web interfaces are designed for humans. Using the database directly is difficult because you must install Oracle client software wherever you wish to run your client. Also, ...

<More introductory information here, e.g., the distinction between ACS acting as a CORBA/EJB server and ACS acting as a CORBA/EJB client>

Client Scenarios

The following scenarios describe how you might take advantage of the EJB interface for various purposes. The CORBA interface provides the same features.

Scenario: ACS User Management

You are adding an ACS to your network and you want to load it up with users from your other systems. First, you'll want to look up a user by name or e-mail address to see if he already has an ACS user id:
// First try his e-mail address.
UserRecord acs_user = acs_user_home.get_user_by_email(
    "mayoff@arsdigita.com");

if (acs_user == null) {
    // Not found; try his name.
    acs_user = acs_user_home.get_user_by_name("Rob",
	"Mayoff");
}

if (acs_user != null) {
    // Found him.
    System.out.println("Rob Mayoff has user_id "
	+ acs_user.user_id);
}
If you could not find the user, then you'll want to create him:
if (acs_user == null) {
    acs_user = new UserRecord();
    acs_user.first_names = "Rob";
    acs_user.last_name = "Mayoff";
    acs_user.email = "mayoff@arsdigita.com";
    acs_user.password = "dqd";
    acs_user = acs_user_home.create_user(acs_user);
    System.out.println("Rob Mayoff has user_id "
	+ acs_user.user_id);
}
Later on, when you want to come back to the user, you can access him by ACS user id:
UserRecord acs_user = acs_user_home.get_user_by_id(123);

Scenario: Ticket Summary

You use the ACS ticket tracker as part of your customer support operation and you want to produce a report that includes statistics about tickets.

...

Scenario: Authorization

You want to use the ACS permissions system to control the actions of users on another system.

...


Notes from 2000-6-5 Conference


Package Names

The Java interfaces for the ACS/CORBA interface are in the Java package com.arsdigita.CORBA.ACS. The Java interfaces for the ACS/EJB interface are in com.arsdigita.EJB.ACS.

We can't just use com.arsdigita.ACS for both, because we might reasonably want a User class in each interface, but the class must be defined differently under the two frameworks.

Object References

Although the CORBA and EJB specifications support object-based designs, Oracle's implementations (as of 8.1.6) are somewhat deficient. Oracle lacks the ability to create persistent object references (in either framework) that span client and server lifetimes. This means that once a client has obtained a reference to some remote Oracle object, it has no way of saving that reference such that some possibly different client can use it at an arbitrary time in the future to access the remote object.

Concretely, here's what you'd like:

This all seems logical and reasonable. Since the ClassifiedAd object is backed by Oracle, it shouldn't matter if, during the "time passes" step, you take Oracle down, move the database to new hardware, give it the old IP address, and fire up Oracle again.

There are CORBA implementations that allow this sort of behavior, by encoding the object's type and primary key in the object reference. Alas, Oracle's isn't one of them. When the client exits after its first run, all the remote objects it had accessed are destroyed. When you get to the last step, and Oracle is your server, you get an OBJECT_NOT_EXIST exception. Oracle's ORB is too primitive to recreate objects from object references.

Instead, the client must do this:

Admittedly, the sequence doesn't look all that different. But now the client can't just use the object reference directly in its second run. It must look up the factory object in the namespace when it might otherwise not need to, and it must call get_ad_by_id instead of string_to_object. Both of these are extra round-trips to the server (string_to_object does not require a trip to the server). The client also needs to tell the server how to recreate the object by using a class-specific method, get_ad_by_id.

Similar arguments apply for Oracle's EJB implementation. The EJB specification defines the concept of "entity beans", which would be persistent across runs, etc. But Oracle doesn't implement entity beans as of 8.1.6.

Authentication

Since we don't require each user to have a separate Oracle identity, we can't use the Oracle CORBA security features for authentication and authorization. Instead, after the client has authenticated itself to Oracle using some shared identity, it looks up the ACS login object in the namespace and calls its login method, in an e-mail address and password. The login method raises an exception on authentication failure. On success, it returns a new object that knows the user's identity and provides methods for accessing the ACS.

Dates

CORBA does not define a standard way of representing dates and times. (In the EJB interface we can just use java.util.Date, which is serializable.) There are basically three possibilities:
  1. Pass dates as strings in 'YYYY-MM-DD HH24:MI:SS' format.
  2. Pass dates in a structure containing separate fields for year, month, day, etc. This basically means parsing the format from #1 on the server side instead of the client side.
  3. Pass dates as seconds since the UNIX epoch. This style sends the least data on the wire and has direct support in the Java and C standard libraries.

mayoff@ardigita.com