Application Interop
So, thinking about really low level application interoperation you get back to wonderful CORBA like services. My current problem relates to the previously stated lordaeron.com ideas. I want the user interface layer to be shared across applications. Weird one to want to interop, I figure. Most focus on making the business logic, or persistence layer interoperable. Ferget that, I want the user interface to be. The idea is to do a web style typical Unix type app. Lots of little ones playing nicely with each other.
Typical example - request from client hits a Squid sprayer that passes it to an HTTPD instance on some app server. HTTPD, as always, decodes the URI and [serves up the static content if Squid hasn't already | passes it to mod_ruby | passes it to mod_jk]. Following the mod_jk route it gets passed to Resin (or Tomcat, whatever) and into a Struts controller. Let's say this URI is for logging in. Stuts adds a [ "current-user" -> User { org.skife.common.User: name => 'Joe Foo' login= > 'joe_foo' email => 'joe@foo.org' role => 'User' } ] to the session and forwards it to Velocity to render said user's welcom page (home.vm).
Client sends another request. Repeat process except this time it gets passed to mod_ruby instead of mod_jk. Ruby needs access to the "current-user" object. Fsck, it is a sericalized Java object.
Okay, so first step is to externalize session handling to a session service. This needs to be A) machine readble and B) portable across Ruby and Java. Therefore (ick) XML seems like a good answer. We now have a session that stores thingies:
in xml. Nifty. We have to access this session service instead of using the default HttpSession, which isn't going to play especially nice with rendering of vm's from Java using the default kit, but hey, we can work on that later.<session id="joe_foo" created="#timestamp" accessed="#timestamp"> <entry name="current-user" type="User" name="Joe Foo" login="joe_foo" email="joe@foo.org" role="User" /> </session>
This session is basically a fully encapsulated XML document which is accessed in a single-threaded manner (1 user per session). While this is somewhat untrue (multiple browser windows, etc) it is true enough that we can get away with a lot of caching (optimistic locking will play nicely). Hmm, whole sets of API's exist for accessing this stuff, it becomes a Web Service (ack! I hate buzzwords). We could do it that way and be buzzword compliant, but this is a service only used on an internal trusted network so we can make a simple protocol over a normal TCP socket and cut down on buttloads of overhead in terms of network chatter and envelopes. Up to you.
Cool, now Ruby can get the session info, chunks along and fiddles bits in a database or something, and then forwards control to a renderer using eruby. Crap, now we have a look and feel to make basically identical.
This has been solved before many times with templating systems. You have a top, left, body, bottom and you use includes for all but body. Works pretty well. Problem here is that the includes are in Velocimacros. Well, write a ruby Velocimacro interpreter. Ick.
Okay, back up again, we can get around this. What we need is to substitute out the actual rendering to a rendering service. The rendering service can be written however you want. It can be a macro jobbie, xslt, whatever. It needs input. It needs input from Ruby and from Java. We already found one thing that works pretty nicely for communicating across application boundaries - said xml. So, we wrap up the info we want to include in the body portion of the page in xml and send it to the rendering service.
Rendering service renders it. Spiffy. This is the classic two-stage renderer pattern, it is just applied across application boundaries instead of as an interceptor.
This, however, is a tricky bit. HTTPD ultimately sends the response back to the user. HTTPD gave control to mod_ruby or mod_jk and expects to get the renderable stuff back out of it. It has no clue how to get the renderable stuff back from a rendering service.
This is where my knowledge of how to do it breaks down. I suspect it will involve writing a wrapper around mod_ruby and mod_jk respectively, but then it may as well be one, and it in turn manages things. Maybe I need to talk to the HTTPD people.
This is beginning to sound a lot like the Portal/Portlet system (a la JetSpeed). Maybe I need to look into that too. Anyway, ramblings and musings done for now.