Nigel,
On 2012-03-29, at 15:29, Nigel Deakin wrote:
> On 29/03/2012 12:01, Rüdiger zu Dohna wrote:
>> On 2012-03-29, at 12:27, Nigel Deakin wrote:
>>> You offer two alternatives.
>>>
>>> 1. Binding to CDI events.
>>>
>>> In this, you are defining a listener on a CDI event. How is this related to JMS? Are you suggesting that when a JMS
>>> message is received the JMS provider automatically fires a CDI event containing the message payload?
>>> If not, what are you suggesting?
>>
>> Yes, exactly. The same would work for the sender as well,
>> and the only thing the business code _has_ to care about,
>> is one annotation on the event type.
>> Everything else has useful defaults.
>
> So how would the incoming JMS message be converted into a CDI event? Are you proposing a standard mechanism for doing this?
I think the MDB, that's created for you under the hood to do the actual binding, should be able to convert xml or JSON TextMessage, MapMessages, Serialized objects, and maybe custom conversions. The default encoding for the sender would be xml and could be changed with annotations. But we'd also have to standardize on what to annotate in order to specify JMS custom properties and settings (destination name, ttl, delay, priority, etc.).
>>> 2. Binding to a business interface
>>>
>>> Is this essentially the MessageAPI approach (which you kindly explained to me when we met in Belgium)?
>>
>> Exactly! Only that I've explained it from the receiver side this time.
>
> OK. Initially I'd like to find out whether these are two separate proposals, or whether the first is actually a way to
> express MessageAPI in terms of CDI events.
My implementation supports both (by now), and I think they complement each other quite nicely.
Actually we could also discuss if it would be feasible to allow clients to access *any* remote EJB via JMS... say you have a service like this:
@Remote public interface Service {
void fireAndForget(String payload);
Reply requestReply(Request request);
}
The JEE container could in addition to the EJB end point also provide an MDB for it that forwards incoming messages to this bean. A client could then look something like this:
public class Client {
@JMSBean RemoteService remoteBean;
void localCall(String payload, Request request) {
remoteBean.fireAndForget(payload);
replyTo(this).callback(remoteBean.remoteMethod(request));
}
void callback(Reply reply) {
// handle the asynchronous reply
}
}
Note that if the client needs to keep some state between the localCall and the callback, it would have to be @Stateful, so the reply can be correlated to this specific bean instance.
Or if it uses CDI events to bind the reply, maybe even this would work (but the correlation would have to be done by hand then, I guess):
public class Client {
@JMSBean RemoteService remoteBean;
void localCall(Request request) {
remoteBean.remoteMethod(request));
}
void callback(@Observes Reply reply) {
// handle the asynchronous reply
}
}
Only for more complex communication patterns, the service would have to actually know that it's invoked asynchronously and where it has to send replies to, etc.
What do you think?
Rüdiger