Guys, I have to say I am mystified and irritated. My interceptors patch has
been around for over a year. I made as little mods as possible to the code
in order to facilitate its acceptance, realizing the problems in the design
which made extensibility harder. Now I see a patch which seems to be a good
step forward in refactoring, which provides XmlRequestProcessor and
XMLResponseProcessor which look rather like interceptors (except they
handle the actual reading/writing of data), and which could be made very
simply to iterate through a list of interceptors to mutate the
request/response.
Nevertheless, I think using an XmlRpcRequest object is a good step
forward and I will modify my patch to use this object, which should make
the interceptors themselves a lot less unweildy (basically aggregating
several parameters into one). I would also like to see the
XmlRpcRequest object used on the client side, where the same conceptual
data is currently in seperate parameters (user, password,
method)...perhaps I will make that mod myself.
Aaron Hamid
CIT/I&D
> Date: 22 Aug 2002 10:22:14 -0700
> To: [EMAIL PROTECTED]
> From: Daniel Rall <[EMAIL PROTECTED]>
> Subject: Re: Making Invoker public?
> Message-ID: <[EMAIL PROTECTED]>
>
> Kevin Hester <[EMAIL PROTECTED]> writes:
>
> > Hi,
>
> Hi Kevin.
>
> > Yesterday I began using the Apache XML-RPC library, and I must
give praise:
> > This is a great library - it works well and it is very cleanly
constructed.
> > However, I have run into one issue and I'd like to see if you
want my fix.
> >
> > I have a number of objects which are currently using RMI, and as
such they
> > have methods declared as void. I've decided to encapsulate these
objects in
> > an XML-RPC framework, but I would still like to have the option
of using RMI.
> > Everything works great except that the void functions return
null when
> > invoked through the introspection API.
> >
> > It seemed to me that creating a glue class that implements the
XmlRpcHandler
> > and uses introspection would be an ideal solution to this
problem. The glue
> > class could invoke the method on its target object, check for
null return
> > value and substitute a value which is acceptable in XML-RPC land
(i.e.
> > Integer(0)).
>
> This sounds like a nice extension. I'm not sure it's something that
> we want on by default, but I wouldn't be against finding some way to
> include it in the package.
>
> > Of course, the glue class I'm describing is only a slight
modification of
> > Invoker.
> >
> > My solution: Make the invoker class public so that users can
subclass it for
> > custom behavior. In my case, I override execute to check for a
null return
> > value.
>
> Andrew Evers is currently working on refactoring the XmlRpcServer
> class, splitting on its child classes and making it more reusable.
It
> would be terrific if you could grab this small chunk of the work
which
> he has proposed. See his recent message for details:
>
>
http://archives.apache.org/eyebrowse/ReadMsg?[EMAIL PROTECTED]&msgNo=22
7
>
> > My question to all:
> >
> > 1) Does this seem like a good solution? It sure seems better
than people
> > having to reinvent the introspection glue.
>
> Yeah, sounds useful.
>
> > 2) Do you want diffs for this minor change?
>
> I defer to Andrew. You guys can work it out. :-)
> --
>
> Daniel Rall <[EMAIL PROTECTED]>
>
> ------------------------------
>
> Date: 22 Aug 2002 10:34:35 -0700
> To: [EMAIL PROTECTED]
> From: Daniel Rall <[EMAIL PROTECTED]>
> Subject: Re: WebServer.java
> Message-ID: <[EMAIL PROTECTED]>
>
> "Andrew Evers" <[EMAIL PROTECTED]> writes:
>
> > Well, since I suggested it, and I have time to do it at the
moment, I'll
> > have a go at splitting it up.
> > >From my perusal of the code it seems that XmlRpcServer has four
> > responsibilities:
> > 1. Maintaining the handlername -> object mapping (in
XmlRpcServer).
> > 2. Plumbing extending XmlRpc (in Worker).
> > 3. Managing the thread pool of workers (in XmlRpcServer).
> > 4. Providing automatic invoker support (in Invoker).
>
> Looks right on, and worth adding to its header documentation. I'd
do
> it myself, but don't want to interfere with your changes; would you
> include this list of responsibilities in your patch?
>
> > 1 & 2:
> > a. Encapsulate the methodName, request, username, and password
> > into an XmlRpcRequest class. Have a class that extends XmlRpc
> > (say XmlRpcProcessor) providing:
> > XmlRpcRequest parseRequest(InputStream, String, String)
> > XmlRpcRequest parseRequest(InputStream)
> > These methods would be non-synchronized and non-reentrant.
>
> Excellent suggestion! This follows the pattern set by the servlet
> API, Apache's httpd, and many other request/response app framework
> I've worked with. Were you thinking protected or public for the
> method scoping?
>
> I would be +1 on deprecating the XmlRpc class, moving its content
into
> a new XmlRpcProcessor class, and having the original XmlRpc class
> extend the new one.
>
> > b. XmlRpcProcessor also provides an executeRequest method that
> > will use a callback interface to map handlers to objects.
> > void executeRequest(InputStream, String, String,
HandlerMapping)
> > void executeRequest(InputStream, HandlerMapping)
>
> I like it. Why do to suggest passing the HandlerMapping into the
> method call rather than having the XmlRpcProcessor maintain that
> information internally?
>
> > c. The HandlerMapping interface is a single method
> > Object getHandler(String methodName)
> > this will return null for no mapping.
>
> Why not use the Map interface instead of a custom HandlerMapping?
> Though HandlerMapping might have a narrower interface (which is
nice),
> is it really worth the trade-off of introducing a new object type?
> The less custom object types involved in a package, the easier I
find
> it to understand (especially as a new developer/user). It seems
that
> alternate mapping types could be just as easily supplied through
> custom Map implementations.
>
> > d. The DefaultHandlerMapping class implements HandlerMapping.
> > XmlRpcServer delegates calls to the DefaultHandlerMapping.
>
> See above comment.
>
> > 3. The changes above allow external management of threads
> > including having different threads handle the request
> > and response, and using the caller thread (for the
> > servlet engine case).
>
> Yay!
>
> > 4. Splitting out the Invoker has recently been suggested by Kevin
> > Hester (my formatting):
> >
> > > Of course, the glue class I'm describing is only a
> > > slight modification of Invoker.
> > >
> > > My solution: Make the invoker class public so that
> > > users can subclass it for custom behavior. In my case,
> > > I override execute to check for a null return value.
> > >
> > > My question to all:
> > >
> > > 1) Does this seem like a good solution? It sure
> > > seems better than people having to reinvent the
> > > introspection glue.
>
> Yup.
> --
>
> Daniel Rall <[EMAIL PROTECTED]>
>
> ------------------------------
>
> Date: Fri, 23 Aug 2002 10:00:07 +0200 (CEST)
> To: <[EMAIL PROTECTED]>
> From: "Andrew Evers" <[EMAIL PROTECTED]>
> Subject: PATCH: Refactor XmlRpcServer and friends for flexible
threading.
> Message-ID:
<[EMAIL PROTECTED]>
>
> ------=_20020823100007_59525
> Content-Type: text/plain; charset=iso-8859-1
> Content-Transfer-Encoding: 8bit
>
> > "Andrew Evers" <[EMAIL PROTECTED]> writes:
> >
> > Looks right on, and worth adding to its header documentation.
I'd do
> > it myself, but don't want to interfere with your changes; would
you
> > include this list of responsibilities in your patch?
>
> Shall we wait for the discussion to die down? ;)
>
> >> XmlRpcRequest parseRequest(InputStream, String, String)
> >> XmlRpcRequest parseRequest(InputStream)
> >
> > Excellent suggestion! This follows the pattern set by the
servlet API,
> > Apache's httpd, and many other request/response app framework I've
> > worked with. Were you thinking protected or public for the
> > method scoping?
> >
> > I would be +1 on deprecating the XmlRpc class, moving its content
into
> > a new XmlRpcProcessor class, and having the original XmlRpc class
> > extend the new one.
> >
> >> b. XmlRpcProcessor also provides an executeRequest method that
> >> will use a callback interface to map handlers to objects.
> >> void executeRequest(InputStream, String, String,
HandlerMapping)
> >> void executeRequest(InputStream, HandlerMapping)
> >
> > I like it. Why do to suggest passing the HandlerMapping into the
> > method call rather than having the XmlRpcProcessor maintain that
> > information internally?
> >
> >> c. The HandlerMapping interface is a single method
> >> Object getHandler(String methodName)
> >> this will return null for no mapping.
> >
> > Why not use the Map interface instead of a custom HandlerMapping?
> > Though HandlerMapping might have a narrower interface (which is
nice),
> > is it really worth the trade-off of introducing a new object
type? The
> > less custom object types involved in a package, the easier I find
it to
> > understand (especially as a new developer/user). It seems that
> > alternate mapping types could be just as easily supplied through
> > custom Map implementations.
>
> Two reasons (other than the narrower interface):
> 1. The current patch specifies that the HandlerMapping will throw an
> Exception if the handler is not found. This allows better error
> propagation than simply returning null.
> 2. It works with Java 1.1.
>
> I think calling through an XmlRpcHandlerMapping is clearer than
> through a generic Map, but that could just be me.
>
> >> 3. The changes above allow external management of threads
> >
> > Yay!
> >
> >> 4. Splitting out the Invoker has recently been suggested by Kevin
> >> Hester (my formatting):
> > Yup.
>
> OK, the patch is attached in "cvs diff -u" format, with extra files
> attached independently. Everything is in a JAR file, since I hope
> you all have jar ;) Commentary for the patch follows.
>
> New classes effectively already described:
> + XmlRpcHandlerMapping - the getHandler(String) throws Exception
interface.
> + DefaultHandlerMapping - an implementation of HandlerMapping based
> on the existing XmlRpcServer implementation.
> + ParseFailed - A runtime exception a'la AuthenticationFailed.
> + Invoker - the Invoker class previously in XmlRpcServer.java, now
public.
> + XmlRpcRequest - encapsulates an XML-RPC request.
>
> Completely new classes:
> + XmlRpcRequestProcessor - decode a request
> Produce an XmlRpcRequest from an InputStream (optional user/pass).
> public XmlRpcRequest processRequest(InputStream, String, String)
> public XmlRpcRequest processRequest(InputStream)
> + XmlRpcResponseProcessor - encode a response/exception
> Produce a byte [] from either an Object - representing a return
value
> or an Exception - representing an error.
> public byte [] processException(Exception x, String encoding)
> public byte [] processResponse(Object outParam, String encoding)
> + XmlRpcWorker - decode, process and encode a request/response.
> Ties everything together, but only communicates with the
XmlRpcServer
> via XmlRpcServer -> XmlRpcWorker execute() and XmlRpcWorker calls
via
> the XmlRpcHandlerMapping.
>
> Current classes with new roles:
> + XmlRpcServer - handle a thread pool and a default handler mapping.
>
> Things changed a little from the patch I originally proposed. The
> whole thing is probably best explained by four lines in
XmlRpcWorker:
>
> request = requestProcessor.processRequest(is, user, password);
> handler = handlerMapping.getHandler(request.getMethodName());
> response = invokeHandler(handler, request);
> return responseProcessor.processResponse(response,
> requestProcessor.getEncoding());
> The *Processor classes are public and have public entry points so
that
> it is possible to build your own XmlRpcWorker-like classes, by
assembly
> (ie. delegation) rather than by inheritance, which can be trickier.
>
> I've copied in licenses, copyright dates and redistributed authors
> as best I could, please don't be offended if I've made a mistake
here ;)
>
> Otherwise, let me know what you think.
>
> Andrew.
>
> ------------------------------
>
> Date: 23 Aug 2002 15:14:10 -0700
> To: [EMAIL PROTECTED]
> From: Daniel Rall <[EMAIL PROTECTED]>
> Subject: Re: patch to correct improper handling of HTTP Basic
authentication
> Message-ID: <[EMAIL PROTECTED]>
>
> Adam Megacz <[EMAIL PROTECTED]> writes:
>
> > Daniel Rall <[EMAIL PROTECTED]> writes:
> > > My intention was to leave the authentication step up to the
handler,
> > > an approach which gives more freedom to the author. However,
if HTTP
> > > demands a user name for Basic auth ('scuse my ignorance), we
should
> > > not only do as you suggest but also throw an
AuthenticationFailed
> > > exception if the empty string is used. Does this sound okay?
> >
> > That sounds fine.
> >
> > The key concept here is that HTTP simply does not support the
notion
> > of "optional authentication".
>
> HTTP does not support the notation of optional auth, but a XML-RPC
> handler might (say, based on some configuration parameter). Sorry
if
> I'm being dense here, but how does having the handler take care of
the
> authentication prevent proper HTTP basic auth? If it does not, were
> you trying to keep AuthenticatedXmlRpcHandler authors from shooting
> themselves in the foot?
>
> > A resource is either authenticated or not, and the process of
> > authenticating to a resource involves first deliberately sending a
> > failed attempt (which is how you get stuff like the realm,
authtype,
> > and digest nonce) before you send an authenticated attempt.
>
> Right.
> --
>
> Daniel Rall <[EMAIL PROTECTED]>