Bug 688707 - Add an X-Candlepin-Version (or similar) field to *all* response headers
Add an X-Candlepin-Version (or similar) field to *all* response headers
Status: CLOSED CURRENTRELEASE
Product: Candlepin
Classification: Community
Component: candlepin (Show other bugs)
0.5
Unspecified Unspecified
urgent Severity high
: ---
: ---
Assigned To: Jesus M. Rodriguez
John Sefler
:
Depends On:
Blocks: rhsm-rhel62
  Show dependency treegraph
 
Reported: 2011-03-17 15:10 EDT by Ken Coar
Modified: 2015-05-14 11:23 EDT (History)
4 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2012-07-17 09:03:11 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Comment 2 Ken Coar 2011-09-27 14:25:05 EDT
This is still not reliably completed.  Some responses are still missing the X-Candlepin-Version field.  For example, try a 'PUT /consumers/{uuid}' with no content; the response is a generic 400 Bad Request.

This is still an urgent need.  The fix is *mostly* there.
Comment 3 Ken Coar 2011-09-27 15:27:50 EDT
At any rate, that entrypoint fails to set the header field in Stage on s01.candlepin.stage.ext.phx2.redhat.com with

X-Candlepin-Version: 0.4.17-1

(that's from /candlepin/status, *not* a failing entrypoint)
Comment 5 Jesus M. Rodriguez 2011-09-28 13:18:02 EDT
The solution in Comment #1 was the addition of a servlet filter called VersionFilter which simply adds the header to the response. The PUT command in comment #2 seems to error out on the request BEFORE it hits the filter on the way back out, causing the filter *NOT* to run. Hence no header.
Comment 6 Jesus M. Rodriguez 2011-09-28 16:16:28 EDT
(In reply to comment #5)
> The solution in Comment #1 was the addition of a servlet filter called
> VersionFilter which simply adds the header to the response. The PUT command in
> comment #2 seems to error out on the request BEFORE it hits the filter on the
> way back out, causing the filter *NOT* to run. Hence no header.

I've found that the filter DOES run, but RESTEasy is handling the exception itself and writing directly to the response, causing the VersionFilter's data to be ignored.

Creating an implementation of ExceptionMapper similar to CandlepinExceptionMapper helps the situation. I have it working specifically for ReaderException, but then it this bug will occur under a different scenario. What's needed is a more generic ExceptionMapper.
Comment 7 Jesus M. Rodriguez 2011-11-01 20:03:27 EDT
For some unknown reason, when RESTEasy handles an internal exception
it completely bypasses the defined servlet filters which means that
the custom header put in place will not be set.

Another issue is that RESTEasy will not invoke exception mappers
for super classes until *AFTER* it has processed its internal
exceptions. In order to override that functionality, you must have
an exception mapper for *ALL* of the specific internal exceptions.

Once, those are covered a generic RuntimeException mapper can do
the rest of the work for you.

The Response seems to get committed before the VersionFilter
has a chance to add the header during exception mapping, so the
mappers add the header to the Response as well as the VersionFilter
doing it during normal processing.
Comment 8 Jesus M. Rodriguez 2011-11-01 20:06:35 EDT
The fix involves creating an exception mapper for each internal exception:

ApplicationExceptionMapper.java
BadRequestExceptionMapper.java
CandlepinExceptionMapper.java
DefaultOptionsMethodExceptionMapper.java
FailureExceptionMapper.java
InternalServerErrorExceptionMapper.java
JAXBMarshalExceptionMapper.java
JAXBUnmarshalExceptionMapper.java
MethodNotAllowedExceptionMapper.java
NoLogWebApplicationExceptionMapper.java
NotAcceptableExceptionMapper.java
NotFoundExceptionMapper.java
ReaderExceptionMapper.java
RuntimeExceptionMapper.java
UnauthorizedExceptionMapper.java
UnsupportedMediaTypeExceptionMapper.java
WebApplicationExceptionMapper.java
WriterExceptionMapper.java

Each ExceptionMapper has to add the header to its Response
since the Response will have been committed by the time
the VersionFilter gets to add the header (odd I know).

Then it involves adding a PostProcessInterceptor to add a header
after running a successful resource method.
Comment 9 Jesus M. Rodriguez 2011-11-01 21:01:29 EDT
* make call to non-existent uri:
  curl -i -k -u admin:admin https://localhost:8443/candlepin/foobar
  * verify X-Candlepin-Version header is present
  * return code is 404

* make call to non-existent item:
  curl -i -k -u admin:admin https://localhost:8443/candlepin/consumers/notthere/
  * verify header is present
  * return code is 404

The following items require an existing consumer, create one using
the cpc tool:

   ./cpc register mymachine system ""   '{"key" => "fact"}' admin admin | grep uuid

be sure to make a note of the uuid

* make call to EXISTING consumer:
  curl -i -k -u admin:admin https://localhost:8443/candlepin/consumers/6f2005e4-1ce1-434a-bbb6-25120f372849
  * verify header is in present
  * valid json
  * return code is 200

* make a PUT with no data to EXISTING consumer:
  curl -i -k -u admin:admin -X PUT  https://localhost:8443/candlepin/consumers/6f2005e4-1ce1-434a-bbb6-25120f372849
  * verify header is present
  * return code is 500

* make PUT with partial data to EXISTING consumer:
  curl -i -k -u admin:admin -X PUT --data @partial.json https://localhost:8443/candlepin/consumers/6f2005e4-1ce1-434a-bbb6-25120f372849
  * verify header is present
  * return code is 400

* make PUT with partial data to EXISTING consumer with json header:
  curl -i -k -u admin:admin -X PUT -H "Accept: application/json" --data @partial.json https://localhost:8443/candlepin/consumers/6f2005e4-1ce1-434a-bbb6-25120f372849
  * verify header is present
  * return code is 400

Feel free to add your other test cases, always verify that the header is present
and that the return code is valid, i.e. no 200 on exceptions.
Comment 10 Jesus M. Rodriguez 2011-11-01 21:02:10 EDT
The partial.json file used in the above test cases contains the following snippet of invalid json:

{"name":"foo", "baddata
Comment 11 Jesus M. Rodriguez 2011-11-07 13:24:36 EST
fixed in master: f69c31f1d8f103402d2011e56c10be840bd76353
will appear in candlepin >= 0.5.1
Comment 12 Bryan Kearney 2012-07-17 09:03:11 EDT
Marking all community bugs modified or beyong as closed.

Note You need to log in before you can comment on or make changes to this bug.