Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

feat(odk): more warnings and info messages #437

Merged
merged 3 commits into from
Oct 25, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 76 additions & 6 deletions aether-odk-module/aether/odk/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@

# list of messages that can be translated
MSG_XFORM_VERSION_WARNING = _(
'Requesting {requested_version} xform version, current is {current_version}'
'Requesting {requested_version} xform version, '
'while current is {current_version}.'
)
MSG_KERNEL_CONNECTION_ERR = _(
'Connection with Aether Kernel is not possible.'
Expand All @@ -77,18 +78,22 @@
'Instance ID is missing in submission.'
)
MSG_SUBMISSION_XFORM_UNAUTHORIZED_ERR = _(
'xForm entry {form_id} unauthorized.'
'xForm entry "{form_id}" unauthorized.'
)
MSG_SUBMISSION_XFORM_NOT_FOUND_ERR = _(
'xForm entry {form_id} no found.'
'xForm entry "{form_id}" no found.'
)
MSG_SUBMISSION_XFORM_VERSION_WARNING = _(
'Sending response to {submission_version} xform version, current is {current_version}'
'Sending response to {submission_version} version of the xForm "{form_id}", '
'while current is {current_version}.'
)
MSG_SUBMISSION_KERNEL_ARTEFACTS_ERR = _(
'Unexpected error from Aether Kernel '
'while checking the xForm artefacts "{form_id}".'
)
MSG_SUBMISSION_KERNEL_EXISTENT_INSTANCE_ID = _(
'There is already a submission "{id}" in Aether Kernel with instance ID "{instance}".'
)
MSG_SUBMISSION_KERNEL_SUBMIT_ERR = _(
'Unexpected response {status} from Aether Kernel '
'while submitting data of the xForm "{form_id}".'
Expand All @@ -104,6 +109,9 @@
MSG_SUBMISSION_SUBMIT_SUCCESS = _(
'Successfully submitted data of the xForm "{form_id}" to Aether Kernel.'
)
MSG_SUBMISSION_SUBMIT_SUCCESS_ID = _(
'The submission with instance ID "{instance}" has ID "{id}" in Aether Kernel.'
)


class ProjectViewSet(viewsets.ModelViewSet):
Expand Down Expand Up @@ -357,6 +365,59 @@ def xform_submission(request):
Response specification:
https://docs.opendatakit.org/openrosa-http/#openrosa-responses

Any time a request is received the following steps are executed:

1. Checks if the connection with Aether Kernel is possible.
Otherwise responds with a 424 (failed dependency) status code.

2. Checks if the request includes content as a FILE
in the ``xml_submission_file`` param.
Otherwise responds with a 422 (unprocessable entity) status code.

3. Reads and parses the file content (from XML to JSON format).
If fails responds with a 422 (unprocessable entity) status code.

4. Checks if the content has a `meta.instanceID` value.
This check is part of the OpenRosa spec.
Otherwise responds with a 422 (unprocessable entity) status code.

5. Checks if the xForm linked to the request exists in Aether ODK.
Otherwise responds with a 404 (not found) status code.

6. Checks if the request user is a granted surveyor of the xForm.
Otherwise responds with a 401 (unauthorized) status code.

7. Compares the content xForm version with the current xForm version.
Warns if the content one is older than the current one and continues.

8. Propagates xForm artefacts to Aether Kernel.
(This creates all the required artefacts in Aether Kernel
that receive the request content and extract the linked entities)
If fails responds with a 424 (failed dependency) status code.

Note: Any error beyond this point will respond with a 400 (bad request) status code.
Also it will delete any submission or attachment linked to this request
in Aether Kernel.

9. Checks if the request instance ID is already in any Aether Kernel submission.
As part of the OpenRosa specs, submissions with big attachments could be
split in several requests depending on the size of the attachments.
In all of the cases the ``xml_submission_file`` FILE is included in the
request.

9.1. If there is no submission in Aether Kernel with this instance ID,
submits the parsed JSON content to Aether Kernel.
Also submits the original XML content as an attachment of the submission.

9.2. If there is at least one submission (there should be only one)
warns about it and continues.

10. Checks if there are more FILE entries in the request.

10.1. If there are more files submits them as attachments linked to
this submission to Aether Kernel.

11. Responds with a 201 (created) status code.
'''

# first of all check if the connection is possible
Expand Down Expand Up @@ -476,7 +537,7 @@ def xform_submission(request):
# check sent version with current one
if version < xform.version: # pragma: no cover
logger.warning(MSG_SUBMISSION_XFORM_VERSION_WARNING.format(
submission_version=version, current_version=xform.version))
submission_version=version, current_version=xform.version, form_id=form_id))

# make sure that the xForm artefacts already exist in Aether Kernel
try:
Expand Down Expand Up @@ -507,8 +568,9 @@ def xform_submission(request):
)
previous_submissions = json.loads(previous_submissions_response.content.decode('utf-8'))
previous_submissions_count = previous_submissions['count']

# If there are no previous submissions with the same instance id as
# the current submission, save this submission and assign its id to
# the current submission, post this submission and assign its id to
# `submission_id`.
if previous_submissions_count == 0:
submission_id = None
Expand All @@ -535,12 +597,17 @@ def xform_submission(request):
# If there is one field with non ascii characters, the usual
# response.json() will throw a `UnicodeDecodeError`.
submission_id = json.loads(submission_content).get('id')

# If there already exists a submission with for this instance id, we
# need to retrieve its submission id in order to be able to associate
# attachments with it.
else:
submission_id = previous_submissions['results'][0]['id']

msg = MSG_SUBMISSION_KERNEL_EXISTENT_INSTANCE_ID.format(instance=instance_id, id=submission_id)
logger.warning(msg)
logger.warning(previous_submissions['results'][0])

# Submit attachments (if any) to the submission.
attachments_url = get_attachments_url()
for name, f in request.FILES.items():
Expand Down Expand Up @@ -577,6 +644,9 @@ def xform_submission(request):
headers={'X-OpenRosa-Version': '1.0'},
)

msg = MSG_SUBMISSION_SUBMIT_SUCCESS_ID.format(instance=instance_id, id=submission_id)
logger.info(msg)

return Response(
data={
'nature': 'submit_success',
Expand Down