One more reason to move these constants from Sandesha to Axis2 is so I don't need Sandesha in my classpath to write and run code that might one day use RM.

Paul

On 10/28/05, Paul Fremantle <[EMAIL PROTECTED]> wrote:
Ok

I wasn't clear. Sorry. I also agree with Glen's comments :-)

What I'm actually asking is that we move

from: org.apache.sandesha.Constants.ClientProperties
String LAST_MESSAGE = "lastMessage";
String CALL_KEY = "callKey";

into org.apache.axis2.Constants.

I am talking about using the property model, so +1 to Glen absolutely. I was really meaning that unless we can make these part of the core ClientAPI, then we can't support switching RM on later.

As for #3, I agree that Glen's model would work too. I prefer mine, because it seems a basic thing to track how a request is going in the same way the Callback object is a core part of the method signature not a property.

Paul





On 10/28/05, Eran Chinthaka < [EMAIL PROTECTED]> wrote:
A BIG +1 from me for Glen's comments.

As Glen explained the base API should be as simple as possible and it should not depend on any of the things like security/transaction/RM, etc,

Paul, why do you wanna do that (I know you must be having a good reason), when you can do the same thing using call.setProperty(key,value) ? Are you suggesting Axis2 to give integrated or first class support to RM ?

-- Chinthaka


Glen Daniels wrote:
Hi Paul:

Great message! As I read it you're asking for three things:

1. Ability to pass SequenceKey in client API

2. Last message marker in client API

IMO, neither of these needs to be put as first-class concepts into the

Axis2 Call class, because we have easy-to-use mechanisms which allow
this kind of stuff by setting arbitrary properties. We're talking about
the difference between:

call.invokeBlocking("op", omElement, sequenceKey);


and

call.set("myRM.SequenceKey", sequenceKey);
call.invokeBlocking("op", omElement);

It's a little more typing, but it's *much* cleaner architecturally to do
the second style. Let's keep the Axis2 core APIs as simple and

independent of "aspects" like reliability/transactions/security as
possible, and just make sure that it's easy to pass and receive
information to/from Modules via both the client and server APIs. Going

the first route heads down what I fear is a slipperly slope to adding
transactional context, etc., directly to our APIs when the point of
Axis2 is to be able to compose these things arbitrarily.

Note also that the original idea of Modules was to not only deploy

Handlers, but also to do cool stuff like:
- Recognizing particular WSDL extensions (i.e. policies) and activating
appropriately
- Affecting WSDL generation (writing policies/extensions) for services
- Affecting codegen of stubs


We're not there yet with any of this, but that last one would give you
what you're looking for from generated stubs at least. The idea would
be when the RM Module saw that RM was in use for a given WSDL, it would

not only cause the correct handler deployments at runtime, it would also
be able to change the client APIs - so for a non-databound stub you
could have:

interface MyStub {
OMElement someOperation(OMElement input, SequenceKey sequenceKey);

}

3. MessageTracker

I need to think about this a little more, but again I can see doing most
of this without adding more machinery. If you need to pass something to
the RM engine, you can always do it like this:


call.set("RM.messageTracker", myMessageTracker);
call.invokeNonBlocking("op", omElement, callback);

And if you need info at callback time, you've got access to the
MessageContext and the RM engine can put stuff in there for you.


So my preference is not to put this kind of stuff into the base APIs but
use it as a test of how well our base APIs (designed for just this kind
of flexibility) can handle adding arbitrary extra functionality via

extensions.

--Glen

-----Original Message-----
From: Paul Fremantle [mailto:[EMAIL PROTECTED]]
Sent: Friday, October 28, 2005 9:24 AM

To: [email protected];

[email protected]
Subject: [Axis2] Implications of WSRM interfaces on Axis2 ClientAPI

I've been thinking about how Sandesha and Axis 2 should 
interact and how people can code to Axis2 with the idea in 
mind that they might be reliable later. I've just been asked 
a couple of times how can the code find out if a message has 
been delivered. 

This is an interesting issue. I used to believe it that RM 
shouldn't have any impact on the Axis2 client api in normal 
usage, because I want to be able to turn on or off WSRM 
without having to change my application code. 

But there are some aspects that require some interaction with 
the application. The first one is knowing how to associate 
messages with a particular reliable sequence. For example, I 
may have multiple stubs running in an application server on 
behalf of multiple clients. I could aggregate all the 
requests into a single sequence, which will be more efficient 
in terms of the protocol, and the overhead of managing large 
numbers of sequences. But if the endpoint is doing ordered 
delivery, it now may end up holding up messages from one 
client while messages for another are delivered, which might 
not be the desired behaviour.

Sandesha uses a simple idea called a SequenceKey. The key is 
simply a marker that the application code can use to help 
create the right underlying sequences. If there are multiple 
stubs or Call objects that use the same SequenceKey, then as 
long as they are targeted at the same endpoint, Sandesha will 
aggregate them into the same sequence. On the other hand, if 
you have two stubs with different SequenceKeys going to the 
same endpoint, they will each have their own sequence.

I think this is a great model, it is simple and clean and 
effective. In fact I think it is so good, that we should 
always code this way - even if we aren't using RM yet. If the 
SequenceKey Constant was in the base Axis2 ClientAPI, we 
could code now with this in mind, so when we want RM, just 
flick the switch. Of course if you don't set a SequenceKey, 
the Sandesha can have a default behaviour.

The same applies to the idea of a LastMessage. Sandesha lets 
you mark a message as being the last in a sequence. This is 
something that generally only the application designer can 
know, so again I think it would be great to promote the 
LastMessage constant onto the standard ClientAPI.

The final issue is letting the application know how the RM 
delivery is getting on. In general we would like to trust 
that every message is delivered successfully, but things 
happen. There will be occasions where timeliness is also 
important. I see two potential approaches for this. The first 
is to expose via a management interface a view of the whole 
sequence. So in Java, we could make the sequence manageable 
via JMX. And if we make the SequenceKey part of that 
management, then the application could use it to help map 
from the application logic into the underlying sequence. 

However, there is a more fundamental model, which is when 
I've made a non-blocking call, I want to know whether that 
made it through. And in fact this is something that is useful 
even without RM. Take a simple HTTP case: if the call is 
truly non-blocking, it could execute the initial send on a 
new thread, and then I will want to know whether there was an 
HTTP 202 return or some other. I may also want to know other 
information from a non-blocking call - such as the messageId 
that was allocated to the outbound message.

So this also seems to be a model we could promote to the base 
Call API in Axis2 (and elsewhere).

Currently the Axis2 API is 
void invokeNonBlocking(op, element, callback) 

My suggestion is to add a new return parameter:
MessageTracker invokeNonBlocking(op, element, callback)

The MessageTracker would only track the outgoing message - 
the callback object tracks the response. 

A simple interface might be something like: 
public interface MessageTracker {
     public boolean isAcked();
     public String getMessageID();
     public boolean isReliable();
     public boolean isUndeliverable();
}

The isAcked() is fairly clear. If this was a non-reliable
interaction, this would just indicate that there was a 202
from the server. In the reliable instance this would indicate

the message had been acked.

The isUndeliverable() would indicate that the message will
never be delivered. In the case of non-reliable, this would
be where there was a fault on the send. In the case of

reliable, this would mean the sequence was terminated or
closed before this message was acked.

The isReliable() could be used to find out if some reliable
messaging standard is in use, to help make sense of the ack state.


And as I point out earlier, this could be useful even for
non-reliable requests, because we could make the nonBlocking
call not even wait for the request to be sent, and still
track whether it succeeded.


Paul

PS This is a slightly modified version of a blog entry
http://www.bloglines.com/blog/paulfremantle?id=16



  


Reply via email to