hi ajith,

Once again thanks for your reply. Although we are now not in a position to
change the
architecture, I would like to add comments to your answer since this
discussion
actually helped me to learn a lot.

On 5/31/07, Ajith Ranabahu <[EMAIL PROTECTED]> wrote:

Hi all,
Forgive me for the delayed answer - I was hoping to write a detailed
answer yesterday but other things kept me busy. I'm sure a voice
conversation would be much faster and comprehensive but all of us are
in different timezones that makes it quite difficult to find a
convenient time slot. Also I see that after all this is settled we can
condense the material in this mail thread and make it into a document
in the Axis2 site which should be a nice architecture reference :)

1. I'm very sure that we considered this pattern (one handler calling
the other handler) vs the engine based method in the early days of
Axis2. I'm not so sure what were the reasons then but here are a few
cases that may prove problamatic


I believe it is not the reason which deepal has mentioned earlier.

I . What will happen if a handler throws up an exception ? Right now
the Axis engine can catch it and deal with it accordingly. If the
handlers are to be called from one another this exception would return
back through all the executed handlers (by looking at the code sample)
which in my opinion makes it somewhat ugly and difficult to debug. At
least in this case exceptions that rise in any handler will jump out
of the first handler


That's correct. that is what I have thought. Isn't is the case for the
current Axis2 Engine?
But if each handler needs to handle the exceptions then we can have some
thing like this.

try{
   this.nextHandler.next(messageContext);
} catch(AxisFault fault){
  // deal with it and throw it back. or stop it
 in a situation like sandesha.
}

Remember ajith what you now have is some thing design by many people
over the years with the experience they have time to time. So I can not give
give you and in detail design on the first place.
What I am basically telling is if you think in the way I have explained
earlier
you would have find easier solutions than given in this solution.

II. Things that are deemed very important and inherent part of a SOAP
engine are not put in handlers but implemented as part of the engine
(e.g mustundertand checking) Having a centralized controller makes it
easier for us to handle such things


that is your perception. and that is what we are talking about.
for me I would suggest to put these to the final handler.
which could be a default handler for all messages and which calls to the TS.


One point that became obvious to me is that it would not make a
difference if each handler called the next or an external controller
called the next handler (provided that the next handler is provided
using the same source - i.e. the handler chain). This wasn't obvious
in our early days since we did not have anything to compare.


Ajith I think you have come to the point.  This is what I am tyring to say.
In the earlier
designs people have not thought about  how to handle RM with this
architecture. So at that
time this would be the perfect architecture. I agree. (I honestly agree that
even I were at
that team I would also have come up with such a thing since there is only
few things to think)

As I know earlier the invoke method did not have any Return type and later a
return value
has introduced to control the flow. (please correct me if I wrong.)
This clearly proves the earlier architecture has not designed in a flexible
way to handle
every thing.  As a result of this people have put many variables and now it
has become more
complex. See how many if statements are the in the invoke methods. I believe
this was the
point you would have change the architecture.


I'm  not sure about what you've meant about each handler knowing what
to invoke next. What I understood initially was that each handler will
call the next handler by consulting the handler chain. In contrast if
we are to keep a reference to the next handler we run into further
problems.


I think I explained this earlier. This is what I mean.
Lets say we have a class called Handler and it has an property called
nextHandler which is handler
type. and Handler class have an next method (don't worry about the method
name).

class Handler{

Handler nextHandler;
public void next(MessageContext msg){
    // process message context
     nextHandler.next();
}

When we write the logic in the next method we do not know any thing about
the next handler.
and after processing we call the next handler. (any way you have the
flexibility do what ever)
So who set this next Handler?
At the deployment time Deployment process should set the next handler of
each handler So that
every message passing through it should get invoked by the correct handler
set.
I have explained this in detail in earlier mail.


There are very practical scenarios where the same handler is called
several times repeatedly, sometimes consecutively , sometimes with
different handlers in between  (e.g. security - Ruchith will be the
best person to actually verify whether this is still the case).


No problem there are plenty of options. I did not say one handler should be
used
one time in the hander chain. See the example I have given I deliberately
use
that type of scenario
H1 H2 H3 H1 H4 H3
you can have any order.


Hence
such handlers will have to keep track of where it is in the chain and
how many times it has been called etc. IMHO this is way too
complicated.


hmm. you are talking about the statefull handlers. isn't it?
How they work when invoke with multiple threads?

As you can see each handler knowing which operation should it be
active for (the registered operations you've mentioned) does not
matter here at all since we've no clue *how many times* that handler
will be invoked even if we know which operation it belongs to.  Even
if we manage to do it it will become complicated with invocation
counters etc.


see my solution . is it complicated?

If we are after a smaller footprint what I can think of as the best to
do is to make all handlers singleton. i.e. we make sure that if a
handler is used within the engine, there is exactly one instance of
it. This shouldn't make a difference since handler are all logic and
no state!


earlier it is state full. this also give and indication that this
architecture
is not flexible.

This is the same thing done in servlets (well in a much
more sophisticated way) but it proves the concept :)


exactly. this is what I meant by Axis2 Engine (set of handlers ) which do
not change the state when processing the messages. So multiple threads
can invoke without any problem.

2. Why should the control be returned to the operation client ? well
for the simple reason that operation client is the only guy who knows
what to do next. The idea of the operation client is that operation
client is the only MEP specific component which know how to proceed.
This way we can support multiple MEPs without touching the rest of the
system.
Note that in this case operation client is the ultimate controller. It
has to have that power to completely handle a MEP.


yes agree. As I explained earlier it is about changing the handler flow. How
it affects
to the MEP? The only  question (with the current Axis2) I have is  when we
get a request back
why it directly goes to the Operational client and invoke receive than doing
this at the
Transport Receiver. Which we do at the server side.

have a look at this jira
https://issues.apache.org/jira/browse/AXIS2-2703
when we receive messages at the server we do not know the operation. So do
not know the
operational level handler chain to invoke. So what we does is we first
invoke global handlers and after dispatching operational handlers. but we
can't mix them. (please correct me if I wrong).

if I understood correctl (again please correct me if I wrong) this is the
reason why we have some
constrains for placing handlers.

But when we think about the later way we don't need such limitations. only
thing is when it comes to operational
handlers operation must have been dispatched (this is a constraint for now
as well). So this is not a special scenario to think about as well. In this
way we assume that the Axis2 engine is a set of handlers, which can be
configured using axis2.xml and service.xml files in any order. (of course
one have to place them
in the correct order so that the proper excecution take place)



3. As for the SOAP fault detection , yes we can use a property in the
message context. However I'm not sure whether we can guarantee that
property to be set before coming to the OutInOperation (which is part
of the client API. Since it is the user who provides a message context
he can choose what to do with it) and the only reliable way to do that
would be to look at the first child of the SOAP body. I'm hoping we
can find a better way to do this but right now I don't see a better
way. (we can do that nicely in the receive path though. we can look at
the transport information (in most cases) to determine whether to call
the fault flow or the normal in flow)
I should say its not as easy as putting an *if* statement in a single
handler. This if would have to be in *all* the handlers (regardless
they do anything significant during a fault) since we have only that
flow ( for a given direction). It is very sensible to put it in a
different flow to make the code nicer and also to make the process
efficient since the number of fault flow handlers can be significantly
lesser than the number of handlers in the conventional flow.


yes  I can agree with you. the exception I see is that the getting body
encrypted
message which can not determine with the transport properties. Any way
having a
different fault flow is a possibility in the design I am saying as well.

Before concluding I should say the blame falls on us for not
documenting these facts properly. If it was difficult for a code-savvy
guy like Amila, it would be a nightmare for a complete newbie who
wants get his feet wet. IMHO we should have a few documents that
explain these architectural decisions (and the thinking behind them)
and include them in Axis2 documentation.


very good idea.

Finally - can we please keep the subject intact when discussing these
topics ? I've had a hard time tracking the relevant messages since
there was substantial amount of discussion in a thread with slightly
different subject !

Ajith

On 5/30/07, Amila Suriarachchi <[EMAIL PROTECTED]> wrote:
> hi deepl,
>
> I agree with you that we have already release the 1.2 and there is no
way to
> do any changes (even every one agrees as well).
>
> this is a solution came to my mind which would adreess the two issues
you
> have
> raise.
>
> public void next(MessageContext messageContext) throws AxisFault {
>         InvocationResponse responese = this.invoke(messageContext);
>         if (responese == InvocationResponse.CONTINUE){
>             this.nextHandler.next(messageContext);
>         }else if (responese == InvocationResponse.SUSPEND){
>             // do nothing
>         }
>     }
>
> if we put this method to AbstractHandler we can preserve the
> API and enforce to return a value.
>
> thanks,
>



--
Ajith Ranabahu

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




--
Amila Suriarachchi,
WSO2 Inc.

Reply via email to