Mercurial > p > roundup > code
annotate roundup/dist/command/bdist_rpm.py @ 5710:0b79bfcb3312
Add support for making an idempotent POST. This allows retrying a POST
that was interrupted. It involves creating a post once only (poe) url
/rest/data/<class>/@poe/<random_token>. This url acts the same as a
post to /rest/data/<class>. However once the @poe url is used, it
can't be used for a second POST.
To make these changes:
1) Take the body of post_collection into a new post_collection_inner
function. Have post_collection call post_collection_inner.
2) Add a handler for POST to rest/data/class/@poe. This will return a
unique POE url. By default the url expires after 30 minutes. The
POE random token is only good for a specific user and is stored in
the session db.
3) Add a handler for POST to rest/data/<class>/@poe/<random token>.
The random token generated in 2 is validated for proper class (if
token is not generic) and proper user and must not have expired.
If everything is valid, call post_collection_inner to process the
input and generate the new entry.
To make recognition of 2 stable (so it's not confused with
rest/data/<:class_name>/<:item_id>), removed @ from
Routing::url_to_regex.
The current Routing.execute method stops on the first regular
expression to match the URL. Since item_id doesn't accept a POST, I
was getting 405 bad method sometimes. My guess is the order of the
regular expressions is not stable, so sometime I would get the right
regexp for /data/<class>/@poe and sometime I would get the one for
/data/<class>/<item_id>. By removing the @ from the url_to_regexp,
there was no way for the item_id case to match @poe.
There are alternate fixes we may need to look at. If a regexp matches
but the method does not, return to the regexp matching loop in
execute() looking for another match. Only once every possible match
has failed should the code return a 405 method failure.
Another fix is to implement a more sophisticated mechanism so that
@Routing.route("/data/<:class_name>/<:item_id>/<:attr_name>", 'PATCH')
has different regexps for matching <:class_name> <:item_id> and
<:attr_name>. Currently the regexp specified by url_to_regex is used
for every component.
Other fixes:
Made failure to find any props in props_from_args return an empty
dict rather than throwing an unhandled error.
Make __init__ for SimulateFieldStorageFromJson handle an empty json
doc. Useful for POSTing to rest/data/class/@poe with an empty
document.
Testing:
added testPostPOE to test/rest_common.py that I think covers
all the code that was added.
Documentation:
Add doc to rest.txt in the "Client API" section titled: Safely
Re-sending POST". Move existing section "Adding new rest endpoints" in
"Client API" to a new second level section called "Programming the
REST API". Also a minor change to the simple rest client moving the
header setting to continuation lines rather than showing one long
line.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 14 Apr 2019 21:07:11 -0400 |
| parents | e233d7a66343 |
| children | 42bf0a707763 |
| rev | line source |
|---|---|
| 4068 | 1 # |
| 2 # Copyright (C) 2009 Stefan Seefeld | |
| 3 # All rights reserved. | |
| 4 # For license terms see the file COPYING.txt. | |
| 5 # | |
| 6 from distutils.command.bdist_rpm import bdist_rpm as base | |
| 7 from distutils.file_util import write_file | |
| 8 import os | |
| 9 | |
| 10 class bdist_rpm(base): | |
| 11 | |
| 12 def finalize_options(self): | |
| 13 base.finalize_options(self) | |
| 14 if self.install_script: | |
| 15 # install script is overridden. skip default | |
| 16 return | |
| 17 # install script option must be file name. | |
| 18 # create the file in rpm build directory. | |
| 19 install_script = os.path.join(self.rpm_base, "install.sh") | |
| 20 self.mkpath(self.rpm_base) | |
| 21 self.execute(write_file, (install_script, [ | |
| 22 ("%s setup.py install --root=$RPM_BUILD_ROOT " | |
| 23 "--record=ROUNDUP_FILES") % self.python, | |
| 24 # allow any additional extension for man pages | |
| 25 # (rpm may compress them to .gz or .bz2) | |
| 26 # man page here is any file | |
| 27 # with single-character extension | |
| 28 # in man directory | |
| 29 "sed -e 's,\(/man/.*\..\)$,\\1*,' " | |
| 30 "<ROUNDUP_FILES >INSTALLED_FILES", | |
| 31 ]), "writing '%s'" % install_script) | |
| 32 self.install_script = install_script | |
| 33 |
