Merge lp://staging/~johannes.erdfelt/nova/lp844905 into lp://staging/~hudson-openstack/nova/trunk

Proposed by Johannes Erdfelt
Status: Rejected
Rejected by: Brian Waldon
Proposed branch: lp://staging/~johannes.erdfelt/nova/lp844905
Merge into: lp://staging/~hudson-openstack/nova/trunk
Diff against target: 827 lines (+522/-81)
7 files modified
etc/nova/api-paste.ini (+1/-1)
nova/api/openstack/urlmap.py (+297/-0)
nova/api/openstack/versions.py (+6/-27)
nova/api/openstack/wsgi.py (+24/-28)
nova/tests/api/openstack/fakes.py (+1/-1)
nova/tests/api/openstack/test_urlmap.py (+111/-0)
nova/tests/api/openstack/test_versions.py (+82/-24)
To merge this branch: bzr merge lp://staging/~johannes.erdfelt/nova/lp844905
Reviewer Review Type Date Requested Status
Brian Waldon (community) Approve
Paul Voccio (community) Abstain
Review via email: mp+76439@code.staging.launchpad.net

Commit message

The 1.1 API specifies that the API version can be determined by URL path (eg /v1.1/tenant/servers/detail), Content-Type header (eg application/json;version=1.1) or Accept header (eg application/json;q=0.8;version=1.1, application/xml;q=0.2;version=1.1).

This branch adds support for looking at the Content-Type and Accept headers for the API version to use.

Description of the change

The 1.1 API specifies that the API version can be determined by URL path (eg /v1.1/tenant/servers/detail), Content-Type header (eg application/json;version=1.1) or Accept header (eg application/json;q=0.8;version=1.1, application/xml;q=0.2;version=1.1).

This branch adds support for looking at the Content-Type and Accept headers for the API version to use.

This merge proposal is more of a code review than a claim than the branch is ready. I'd like to hear opinions on the direction of the branch.

In particular:
* The approach I took using a custom URLMap class to integrate into paste deploy. It has the benefit of still allowing the paste config to enable/disable API versions. It subclasses a paste class, so it may end up being fragile in the long term.
* To support this correctly, the accepted content type needs to be determined much earlier than before (so we get the right version specified by the MIME type in the Accept header). Unfortunately, there are a couple of resources that define an additional supported content type of application/atom+xml. Since we determine the accepted content type before we call the resource, this leaves us in a difficult position. The branch semi-hard codes it. If anyone has a better idea, I'm open for discussion.
* Much of the current code tests like to skip the paste deploy part of the WSGI stack. Also the direct API doesn't use paste deploy. As a result, I left in code to determine the accepted content type at a later point. I originally went down the path of changing the rest of the code, but that resulted in a set of huge changes, but also some corner cases where only part of the WSGI stack is intentionally tested.

To post a comment you must log in.
1588. By Johannes Erdfelt

Remove hardcoded content type now that the code handles direct API again

1589. By Johannes Erdfelt

Remove FIXME now that it has a workaround

1590. By Johannes Erdfelt

Cleanup docstrings
Remove is_filename option, it's not necessary for us and is a hack anyway

Revision history for this message
Sandy Walsh (sandy-walsh) wrote :

Finding it hard to see that the new code is being properly covered by the tests.

Ideally I'd like to see explicit unit tests on each of the new methods added (and ensuring they hit each of the conditional branches).

At the very least, some description in the unit tests as to what they are actually testing and which methods are being touched. But ideally, simple single-method unit tests.

Revision history for this message
Johannes Erdfelt (johannes.erdfelt) wrote :

I'm not sure I understand what needs to be changed.

The unit tests check the two different methods to determine the best content type and the three different methods to determine the API version.

Each unit test checks a single piece of functionality, so I'm not sure I understand what you mean by "single-method unit tests".

Are you saying some code isn't being tested? The existing code being tested isn't tested well enough?

1591. By Johannes Erdfelt

Add docstrings to tests to better document the intent

Revision history for this message
Paul Voccio (pvo) wrote :

Wanted to echo removing comments and some of the formatting the others mentioned here.

I got some 3 failures with the S3APITestCase. Not sure if this is related or not yet.

Please also add yourself to the Authors file. This failed on the unit tests for me.

======================================================================
FAIL: test_authors_up_to_date (nova.tests.test_misc.ProjectTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/root/bzr/TrustedComputingPools/nova/tests/test_misc.py", line 93, in test_authors_up_to_date
    '%r not listed in Authors' % missing)
AssertionError: set([u'<email address hidden>']) not listed in Authors

review: Needs Fixing
Revision history for this message
Paul Voccio (pvo) wrote :

meh, too many windows open.

review: Abstain
Revision history for this message
Brian Waldon (bcwaldon) wrote :

I'm very curious why nova/api/openstack/urlmap.py is necessary. I feel like we can get most of this functionality out of webob, is there something I'm missing?

Since we have to do content-type checking up front now, can we guarantee it *always* gets done up front? It seems like best_match_content_type is now designed to allow late checking of that header.

review: Needs Information
Revision history for this message
Johannes Erdfelt (johannes.erdfelt) wrote :

paste deploy determines which versions of the API are available by using the configuration in etc/nova/api-paste.ini. This all happens before webob gets into the picture.

My original stab at this task modified nova.api.openstack.versions (which is the handler for / and thusly the default for any URL paths not prefixed with a version) instead. However, I had to duplicate the configuration of API versions, which I wanted to avoid.

The reason for best_match_content_type is covered in the description for the merge prop. As a summary, it's because the direct API uses some of the same WSGI stack but not paste deploy, and there are tests that deliberately operate on only part of the WSGI stack (for instance nova/tests/api/openstack/test_faults.py) and partially test the same functionality of urlmap (suffix content type tests).

I can't say I'm pleased with having two different methods of determining content type either. It might be possible to fix the direct API to use a different request object or maybe even use paste deploy. It might also be possible to mock up a different request object for the tests. I think there might be other problems too, I ran into a lot when I tried developing a patch that left best_match_content_type out.

It's guaranteed to get done up front if the paste configuration is correct. I'm not a fan of requiring configuration to get correct behavior, but there's already precedent for that (see the auth middleware) and I didn't want the scope to grow beyond the original bug.

Revision history for this message
Brian Waldon (bcwaldon) wrote :

Okay, I can definitely understand many of your concerns here. Maybe one day we will get away from paste and our problems will be solved ;)

As for the accept header parsing: I feel like the code in urlmap.py is duplicating functionality provided in webob.acceptparse (http://docs.webob.org/en/latest/modules/webob.html). Can you take a look at that and see if you agree with me?

Revision history for this message
Johannes Erdfelt (johannes.erdfelt) wrote :

It *does* duplicate the code in webob, but only because webob ignores all parameters except for 'q'. We need the 'version' parameter as well (which is kind of the purpose of the branch).

I should also mention that the Accept parsing code in this branch is based off of the code in Werkzeug. It's BSD licensed and appears to be compatible with the Apache license Openstack uses. I'm thinking I might need to move that code to a separate file to keep the license separate.

Revision history for this message
Brian Waldon (bcwaldon) wrote :

Okay, I didn't look close enough at acceptparse to notice it didn't return values other than quality. I'm going to approve with the understanding that some of this will get simplified in the future.

review: Approve
Revision history for this message
Brian Waldon (bcwaldon) wrote :

Moved to gerrit.

Unmerged revisions

1591. By Johannes Erdfelt

Add docstrings to tests to better document the intent

1590. By Johannes Erdfelt

Cleanup docstrings
Remove is_filename option, it's not necessary for us and is a hack anyway

1589. By Johannes Erdfelt

Remove FIXME now that it has a workaround

1588. By Johannes Erdfelt

Remove hardcoded content type now that the code handles direct API again

1587. By Johannes Erdfelt

Accept application/atom+xml for a few exceptions as well

1586. By Johannes Erdfelt

Add content type tests

1585. By Johannes Erdfelt

PEP8 cleanup

1584. By Johannes Erdfelt

Merge with trunk

1583. By Johannes Erdfelt

Start adding some unit tests

1582. By Johannes Erdfelt

Rename to urlmap to better reflect the purpose

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.