We have an application that provides data services to clients. The app has two main parts. The first part, the SPL, provides the contract that other applications code to. The second part, the LIL, provides that actual data retrieval services. LIL components talk to a number of different legacy systems and ultimately return standard Value Objects.
Each LIL component can take up to 3 seconds to return. We now have a new requirement that may make multiple LIL calls necessary to support one request. Normally, I'd have worker threads work with different LIL components and then aggregate the results in the SPL. But the SPL is a stateless session bean.
I was thinking of a Service Activator type design. In situations where multiple LIL calls are necessary, I'd deliver the command to a series of Peer to Peer queues and have MDBs communicate with the LIL. To get the response back, the MDBs would have to put the replies for the LIL components on another reply queue to be picked up by the SPL.
Our environment is a multi-node, multi-app server clustered WAS 5.0 environment. As a result, I don't know of any way to gaurantee that the MDBs are on the same app server as the SPL.
1. Does using MDBs to simulate worker threads in an EJB environment make sense? Any better designs options?
2. I don't like over using JMS and ideally I was hoping to come up with a solution where the command sent to the MDBs could contain a call-back to the SPL. If I create many queues, one for each app-server, and gaurantee that the MDBs are running in the same app server as the SPL, could I create a callback object to collect the results from the MDBs talking to the LIL components?
IMHO that is a good reason to use MDB's. I've used em to do exactly the same time and over. However the most important thing to answer before you go down that approach is how do you want to get to the results after processing. Do you mind going to the DB or do you want it dynamically made available to you.
The DB Choice is nice and simple , when you offload the work create a ID and send it to the Q. Make sure you look up the results using the same ID. if you wish to have the results available dynamically, you can either create a response Q on the fly and use that to get the results either by polling or associating a listener to it ( Classic JMS style ) or you can have a dedicated set of response Q's and you can walk through em in a non destructive manner to get your response.
The Key is when you offload to your worker threads is how you write your MDB's. Dont write the MDB's in such a way that they perform only one task. Generate the MDB's based on a command patter and have them process commands. This way you can limit the number of Q's in the system and the Server will take care of pooling the MDB's for you. But using the Command Pattern is the key here.
Hope this helps.
How do you handle security under this model?
i.e. I authenticate but when my request hits the MDB
it no longer knows it's me.
Communication to the MDB is handled by a stateless session bean. Every request also passes through a security framework. In our business we can't make fine grained authorization decisions until after the VOs have returned.
Bottom line is, the MDBs don't handle security. You can probably have a trusted application domain and only allow messages placed on the queue by trusted apps. You could also us a composite type object which gets sent to the MDB. Part of the composite contains a command type object and the other part contains a security context.