Hi Toshi,
This is exactly what i wanted to configure, index of the handler user wants
to start in case of 'return false'. You got me. Instead of storing class name,
index makes things lot easier. Ofcourse wsdd gives more flexibility. I am not
sure if we need to support '-1' option you mentioned. I think we have to move
this thread to developer list so that we can take the opinion of other axis
handler developers. Ultimately we have to fill this gap of non conference with
spec completely (WSDD, handlerchainimpl ... ).
Regards,
Sreekant
Toshiyuki Kimura wrote:
> Hi, Sreekant:
>
> You did a good job for our common problems, Sreekant!
> I anticipated you would cover it, and you did covering.
> Thanks a lot!!
>
> The current version of "our collaborated solution"
> would be enough to follow the spec. If you hope that
> you would like immediately to start implementations of
> the jax-rpc handlers, it'll be the easiest way.
> However, if a moment's delay is acceptable to you,
> I'd like to propose the other way which is more elegant
> approaches to handle the jax-rpc scenario.
>
> As you know, the architecture of jax-rpc handler gives
> very high level adaptability and portability to users.
> In addition in the AXIS implementations, if we want to
> configure (i.e. add and/or remove handler components,
> or change the order), we have to do is just one thing;
> editing "*.wsdd" (and re-deploy it).
> OTOH, your posted implementation has a risk to reduce
> the advantages for the jax-rpc handler users, therefore,
> I'd like to recommend the following approach.
>
> ***** The rule of the new flow definition *****
> .........*.........*.........*.........*.........*.........*
> a)I define a special parameter for "*.wsdd" to setting up
> a user specific response flow in case of return "false".
> b)The parameter's name is "OnReturnFalseRestartAt".
> c)It can *optionally* appear under the "<handlerInfoChain>"
> as the child node of the "<handlerInfo>".
> d)The appropriate value is an integer value (-1, 0, 1, 2..)
> to indicate the starting point index of response flow.
> (Exceptionally, the "-1" indicates the runtime doesn't
> invoke any handleResponse methods and directly sends back
> the response message from handleRequest to the client.)
> .........*.........*.........*.........*.........*.........*
>
> ***** A sample definition of deploy.wsdd *****
> (--- How to use "OnReturnFalseRestartAt" parameter ---)
> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> -----
> <deployment xmlns="http://xml.apache.org/axis/wsdd/"
> xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
>
> <service name="testWebService" provider="java:RPC">
> <parameter name="className" value="webservices.testWebService"/>
> <parameter name="allowedMethods" value="*"/>
>
> <handlerInfoChain>
> <handlerInfo classname="samples.jaxrpc.hello.ServerHandlerA">
> <parameter name="OnReturnFalseRestartAt" value="0"/>
> </handlerInfo>
>
> <handlerInfo classname="samples.jaxrpc.hello.ServerHandlerB">
> <parameter name="OnReturnFalseRestartAt" value="-1"/>
> </handlerInfo>
> </handlerInfoChain>
>
> </service>
> </deployment>
> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> -----
>
> ***** Patch for HandlerChainImpl.java *****
> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> -----
> // added by Toshi <[EMAIL PROTECTED]>
> private int falseIndex;
>
> public boolean handleRequest(MessageContext _context) {
> SOAPMessageContext context = (SOAPMessageContext) _context;
>
> // boolean processFault = false; === no use ===
> // added by Toshi <[EMAIL PROTECTED]>
> falseIndex = -1;
>
> for (int i = 0; i < size(); i++) {
> Handler currentHandler = getHandlerInstance(i);
> try {
> if (currentHandler.handleRequest(context) == false) {
> // added by Toshi <[EMAIL PROTECTED]>
> falseIndex = i;
> return false;
> }
> } catch (SOAPFaultException sfe) {
> throw sfe;
> }
> }
> return true;
> }
>
> public boolean handleResponse(MessageContext context) {
> // added by Toshi <[EMAIL PROTECTED]>
> int endIdx = handlerInfos.size() - 1;
>
> if (falseIndex != -1) {
> HandlerInfo info = (HandlerInfo)
> this.handlerInfos.get(falseIndex);
> String st = (String)
> info.getHandlerConfig().get("OnReturnFalseRestartAt");
>
> if (st != null) {
> endIdx = Integer.parseInt(st);
> } else {
> endIdx = falseIndex;
> }
> }
>
> // for (int i = size() - 1; i >= 0; i--) === Comented out ===
> // changed by Toshi <[EMAIL PROTECTED]>
> for (int i = endIdx; i >= 0; i--)
> if (getHandlerInstance(i).handleResponse(context) == false)
> return false;
> return true;
> }
> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> ----- <CUT> -----
>
> P.S.
> Please call me by my nickname; "Toshi" which comes from
> my given name "Toshiyuki".
>
> Best Regards,
>
> Toshi (Toshiyuki Kimura) <[EMAIL PROTECTED]>
> R&D Headquarters
> NTT DATA Corporation
>
> -----Original Message-----
> From: Sreekant Thirunagari [mailto:[EMAIL PROTECTED]
> Sent: Friday, February 28, 2003 3:23 AM
> To: [EMAIL PROTECTED]
> Subject: Re: Handler chain implementation
>
> Hi Toshiyuki Kimura,
>
> Here are my suggestions.. follow the --->>
>
> (1): H2(req) generates a response msg and the runtime
> directly sends back it to the client
> *** Currently, I'm not sure this path is needed ***
> --->> According to spec the handler that intends to return false is
> responsible
> to set the response message in handleRequest method. but i don't see any
> need
> or how to do this. Even i am not sure if we need to handle this.
>
> (2): H1(res) generates a response msg, and after that
> the runtime sends back it to the client
> --->> I want to address (2) and (4) together.
> (3): H2(res) generates a response msg, and the runtime
> invokes the next handler ( handleResponse of H1 )
> *** The spec says "It should be the default". ***
> ---->> So the runtime system should be able to make a decesion to follow
> 'default' or look for user customization??
> I think this can be achieved by setting a property in context
> passed
> to the handler that intends to return false.
> (4): H3(res) generates a response msg, and the runtime
> invokes the next handler ( handleResponse of H2 )
> ----->> As we ruled out (1) .. atleast for now and we know what default
> means..
> i want to bring up the question i raised last time .. what are the
> customizations user should be allowed to do??? I think two options mentioned
> below would be more generic.
> (a) As in the solution you proposed just let system invoke all the
> handlers leave the responsibility to user implementation of handleResponse.
> Option (4)
> set empty string as "HandlerFault" property in context passed to the
> handler .. to indicate the ChainImpl to invoke all the handlers and the
> handleResponse implementations of configured handlers are responsible for
> how
> they generate response and pass it over. (This is a convention i came up
> with ..
> obviously there should a better way of conveying this)
>
> (b) Should be able to say to the system to start from a perticular
> point
> in the chain and continue from there. If he configures it to be H1 that
> would be
> the only handler invoked and responsible for setting appropriate response
> SOAP
> message.
> set class name of the handler in configured chain from which you
> want to
> start as "HandlerFault" propert y in context passed to the handler
>
> So now we can mix both our solutions to achieve more generic solution.
> It
> doesn't look readable but i tried my best
> Introduced '--->>' for parts to be noted. I used the same code u sent in
> prevous
> mails and changed it a bit.
> --------- Handler -----------------
> public boolean handleRequest(
> javax.xml.rpc.handler.MessageContext context) {
>
> // **** if you want to return false ****:
>
> // set the class name of the handler implementation:
> --->>> //context.setProperty("HandlerFault", this.getClass().getName());
> String handlefault = ""; // to invoke all the handlers in chain
> context.setProperty("HandlerFault", handlefault);
> or
> String handlefault = "MyHandlers.handler3" // to start from handler -3
> class
> in chain
> //Note that this should be an existing handler in configured chain.
> context.setProperty("HandlerFault", handlefault);
> or
> -- DON'T SET THIS PROPERTY TO ALLOW THE SYSTEM TO FOLLOW DEFAULT
> FLOW ---
> return false;
> }
>
> public boolean handleResponse( javax.xml.rpc.handler.MessageContext
> context) {
> // get the state (class name was set or not) from MsgCtx:
> String name = (String)context.getProperty("HandlerFault");
> //if (name != null && name instanceof String &&
> name.equals(this.getClass().getName())) {
> ---->> if (name != null && name instanceof String ) {
> if(name.equals(""){
> // this is a fault situation and is upto you how to
> handle
> it...
> }
> else if(name.equals(this.getClass().getName())){
> // this is a fault situation and you are responsible to
> set
> SOAP response message
> }
> } else {
> :
> :
> }
> return true;
> }
>
> ------------------HandlerChainImpl -----------------------------------------
> protected int lastHandlerIndex = 0;
>
> public boolean handleRequest(MessageContext _context) {
> SOAPMessageContext context = (SOAPMessageContext) _context;
>
> boolean processFault = false;
>
> for (int i = 0; i < size(); i++) {
> Handler currentHandler = getHandlerInstance(i);
> lastHandlerIndex = i;
> try {
> if (currentHandler.handleRequest(context) == false) {
> // get the state (class name was set or not) from MsgCtx:
> String name =
> (String)context.getProperty("HandlerFault");
> boolean classFound = false;
> if( (name != null) && name instanceof String ) {
> if(name.equals("")){
> lastHandlerIndex = size() -1;
> }
> else if( ! name.equals("")){
> // have to traverse back from this handler class
> that is set by user ..
> for (int j = 0; j < size(); j++) {
> if(
> name.equals(getHandlerInstance(j).getClass().getName())) {
> // found it ..
> classFound = true;
> lastHandlerIndex = j; // set this as the
> index to start.
> continue;
> }
> }// end find class for
> if(!classFound){
> // automatically falls back to default.. in
> case
> of wrong class being set
> // or we can think of throwing a runtime
> exception here...
> }
> }// end of if name != ""
> }
> return false;
> }
> } catch (SOAPFaultException sfe) {
> throw sfe;
> }
> }
> }
>
> public boolean handleResponse(MessageContext context) {
> for (int i = lastHandlerIndex; i >= 0; i--){
> Handler currentHandler = getHandlerInstance(i);
> if (getHandlerInstance(i).handleResponse(context) == false)
> return false;
> }
> return true;
> }
>
> -----------------------------------------------
>
> These chages along with the one u mentoined SOAPService class should
> take
> care of everything.
>
> Regards,
> Sreekant