Posted by aevans1108
on August 14, 2008 at 2:21 AM PDT
I used the NetBeans (6.1) RESTful Web Services (0.8) plug-in to generate webservices from entity classes which I previously generated from an underlying MySQL database of my own creation. I then deployed the resulting services to Glassfish [Sun Application Server 9.1_02 (build b04-fcs)] where I previously configured a custom jdbc realm (named "quantumauth"). There are two roles: user and admin. Both are mapped to corresponding principals and groups by the same name in sun-web.xml. Associated constraints are likewise defined in web.xml.
Here's some background that I don't know is relevant. You can skip it for now and come back to it if you think it's important:
The default converter classes are generated such that they include "Ref" elements in the XML -- so that the application can be "well connected" I suppose. However, since I'm writing an AJAX front end and don't want to make several round trips from the browser to the web server to retrieve all the child records (i.e. foreign records) associated with a given master record, I modifed the getReferences() methods in the plurally named converter classes (e.g. "CustomersConverter") to return collections of actual objects (like "Collection" rather than "Collection".) The setReferences() method however, continues to accept a collection of reference classes (e.g. Collection) since that serves my purposes well. I also renamed the @XmlElement()s to not use the "Ref" suffix. That is, XML representation semantics are different for POSTs and PUTs than they are for GETs. In other words, while element names are identical in both representations, server generated representations include comprehensive child record representations, but client generated representations only include the subelement in the encapsulated child record representations (which also have a uri attribute) -- as if they were Ref subelements (which they are, save for the name). I'm sure someone is going to say this is rotten, but I'm really just doing some pro-bono work as a learning exercise so I figure I'm off the hook. ;-)
Background information ends here.
GETs and DELETEs work beautifully. POSTs and PUTs work just hunky dorey when operating on master records provided I don't include any foreign key "Ref"-style (but not so-named) elements in the XML representation. Once I do that, Glassfish sends back a 404 as if the uri attributes in the "Ref" tags (which again, aren't named "Ref", but are "Ref"s just the same) were invalid. However the associated resources are perfectly accessible with the provided credentials so long as I go right to them from the browser. I hope you're following me. Here comes the good part.
I cranked up logging on everything to FINEST. Ugh. Generates about 16 MB/sec of stuff that I went through with a pot of coffee and a pair of tweezers. It turns out that Glassfish authorizes the PUT operation, no problem. However, when it attempts to verify the "Refs" by their associated IDs using GETs against the resources it somehow loses the credentials I provided it through HTTP basic authentication (credentials that it has already verified) and attempts to authenticate with "null" as the value for the principal instead. Naturally, the com.sun.web.security.WebSecurityManager rejects the null credentials and the entire operation fails -- again, with a 404 passed back to the client. Now, I'm just putting this together based on what I've read in the logs. I might be all wet.
I can duplicate the error without involving the browser simply by using telnet and sending:
PUT http://localhost:8080/quantum6/resources/membrs/2/ ? HTTP/1.1
Authorization: Basic YWV2YW5zOg==
This approach (telnet) works fine with working elements of the application so it's not the problem.
I have uploaded the entire project to http://aevans.vendor.net/quantum6.zip . It's nearly 10 MB. Server.log and the SQL to generate the db are in the root of the archive (you have to run each create statement in the db seperately -- the database is called quantum2, the application is called quantum6). You can also just view server.log by itself at http://aevans.vendor.net/server.log . The code is a mess. Like I said, I'm learning.
I am happy to forgo checks on the referenced child records and defer database constraint enforcement well... to the database engine... but that means I need a different converter for incoming data than I use for outgoing data. Indeed I'll probably start using that approach tomorrow or Friday if there aren't any answers to this post. However, I find that I'm constantly working around my ignorance of Glassfish and I don't want to do that anymore. I want to know why it thinks it doesn't have GET permission to the child records. Why is it losing the credentials that I supplied it midway through the operation?
There is a similar issue posted at http://tinyurl.com/6gdtt9 but it is completely over my head. My sun-web.xml has the associated elements in any case.
I will be grateful for any and all responses whether from your experience, a tarot deck, ouija board, whatever...
Many thanks in advance for your time getting this far and my warmest regards... :)
PS: If you look at the code, you'll see that in service.MembrResource.getMembrResourceForWhoModifiedId() that I try a hack that uses @PermitAll and attempts to override the method I thought might be causing the problem. The problem occurs with or without the hack (I don't even know if @PermitAll can be used in this way.) I actually don't even think it gets this far. I put some logging in here at one point and it never wrote anything out.