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]>