Skip to content

Commit

Permalink
Merge pull request #371 from biocore/daklapack_celery_polling
Browse files Browse the repository at this point in the history
Daklapack celery polling and emailing, plus archiving errored orders with Daklapack
  • Loading branch information
wasade authored Aug 27, 2021
2 parents 2245a82 + a961e5d commit 71fa6eb
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 20 deletions.
2 changes: 1 addition & 1 deletion microsetta_private_api/admin/admin_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ def query_barcode_stats(body, token_info, strip_sampleid):
validate_admin_access(token_info)
barcodes = body["sample_barcodes"]
if len(barcodes) > 1000:
return jsonify({"message": "Too manny barcodes requested"}), 400
return jsonify({"message": "Too many barcodes requested"}), 400
summary = per_sample(None, barcodes, strip_sampleid)
return jsonify(summary), 200

Expand Down
70 changes: 58 additions & 12 deletions microsetta_private_api/admin/daklapack_communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
SERVER_CONFIG["daklapack_subscription_key_val"]
}

ORDER_HOLD_TEMPLATE_PATH = "email/daklapack_fulfillment_hold_request"


def _get_daklapack_oauth2_session():
# run the "Resource Owner Client Credentials Grant Type" oauth2 workflow
Expand All @@ -26,29 +24,77 @@ def _get_daklapack_oauth2_session():


def post_daklapack_order(payload):
return _post_to_daklapack_api("/api/Orders/", payload)


def post_daklapack_order_archive(payload):
return _post_to_daklapack_api("/api/Orders/Archive", payload)


def _post_to_daklapack_api(url_suffix, payload):
oauth_session = _get_daklapack_oauth2_session()

dak_order_post_url = f"{SERVER_CONFIG['daklapack_api_base_url']}" \
f"{url_suffix}"

# the json parameter sets the content-type in the headers
# to application/json, whereas if used data parameter, would have to set
# content-type manually
dak_order_post_url = f"{SERVER_CONFIG['daklapack_api_base_url']}" \
f"/api/orders"
result = oauth_session.post(
dak_order_post_url, json=payload, headers=DAK_HEADERS)

if result.status_code >= 300:
raise ValueError(f"Posting {payload} to {url_suffix} received "
f"status code {result.status_code}: {result.json}")
return result


def send_daklapack_order_errors_report_email(errors_list):
result = None
if len(errors_list) > 0:
template_args = {"errors": errors_list}
email_subject = "Daklapack order errors"

result = _send_daklapack_email(template_args, email_subject,
"daklapack_errors_report_email",
"email/daklapack_order_errors_report",
"DAK_ORDER_ERRORS_REPORT")
return result


def send_daklapack_polling_errors_report_email(errors_list):
result = None
if len(errors_list) > 0:
template_args = {"errors": errors_list}
email_subject = "Daklapack polling code errors"

result = _send_daklapack_email(template_args, email_subject,
"daklapack_errors_report_email",
"email/daklapack_polling_errors_report",
"DAK_POLLING_ERRORS_REPORT")
return result


def send_daklapack_hold_email(daklapack_order):
template_args = {"order_id": daklapack_order.id,
"fulfillment_hold_msg":
daklapack_order.fulfillment_hold_msg}
email_subject = f"Hold fulfillment of order {daklapack_order.id}"

return _send_daklapack_email(template_args, email_subject,
"daklapack_service_email",
"email/daklapack_fulfillment_hold_request",
"DAK_ORDER_HOLD")


def _send_daklapack_email(template_args, email_subject, email_config_key,
template_path, email_subtype):
try:
template_args = {"order_id": daklapack_order.id,
"fulfillment_hold_msg":
daklapack_order.fulfillment_hold_msg}
email_subject = f"Hold fulfillment of order {daklapack_order.id}"
dak_service_email = SERVER_CONFIG["daklapack_service_email"]
errors_report_email = SERVER_CONFIG[email_config_key]
celery_send_email.apply_async(
args=[dak_service_email, email_subject,
ORDER_HOLD_TEMPLATE_PATH,
args=[errors_report_email, email_subject, template_path,
list(template_args.keys()), template_args,
"EMAIL", "DAK_ORDER_HOLD"])
"EMAIL", email_subtype])
email_success = True
except Exception: # noqa
email_success = False
Expand Down
13 changes: 8 additions & 5 deletions microsetta_private_api/admin/daklapack_polling.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ def make_error_str(ex):

curr_page += 1
# end while

# email a list of any failed orders to address in the config
# dc.send_daklapack_order_errors_report_email(results[ERROR_STATUS])
except Exception as outer_ex:
results[CODE_ERROR].append(make_error_str(outer_ex))

# email a list of any failed orders to address in the config
dc.send_daklapack_order_errors_report_email(results[ERROR_STATUS])

# email a list of any encountered exceptions to address in the config
# dc.send_daklapack_polling_errors_report_email(results[CODE_ERROR])
dc.send_daklapack_polling_errors_report_email(results[CODE_ERROR])

return results

Expand All @@ -100,7 +100,10 @@ def _process_single_order(curr_order_id, curr_status, curr_creation_date):
per_article_info = process_order_articles(
per_order_admin_repo, curr_order_id, curr_status,
curr_creation_date)
# end if error or sent

if curr_status == ERROR_STATUS:
# archive the errored order
dc.post_daklapack_order_archive({"orderIds": [curr_order_id]})

per_order_t.commit()

Expand Down
20 changes: 19 additions & 1 deletion microsetta_private_api/admin/tests/test_daklapack_polling.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,25 @@ def test_poll_dak_orders(self):
200, articles_for_orders[0]), make_test_response(
200, articles_for_orders[1])]

real_out = poll_dak_orders()
with patch("microsetta_private_api.admin."
"daklapack_communication."
"post_daklapack_order_archive") as mock_archive:
mock_archive.side_effect = [make_test_response(
200, {"updated": 1})]

with patch("microsetta_private_api.admin."
"daklapack_communication.send_"
"daklapack_order_errors_report_email") as \
mock_order_email:
mock_order_email.side_effect = [True]

with patch("microsetta_private_api.admin."
"daklapack_communication.send_daklapack"
"_polling_errors_report_email") as \
mock_polling_email:
mock_polling_email.side_effect = [True]

real_out = poll_dak_orders()

# for three incomplete orders that saved, check status in db
self._check_last_polling_status(
Expand Down
4 changes: 4 additions & 0 deletions microsetta_private_api/celery_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def __call__(self, *args, **kwargs):
"update_vioscreen_sessions": {
"task": "microsetta_private_api.util.vioscreen.update_session_detail", # noqa
"schedule": 60 * 60 * 24 # every 24 hours
},
"poll_daklapack_orders": {
"task": "microsetta_private_api.admin.daklapack_polling.poll_dak_orders", # noqa
"schedule": 60 * 60 * 24 # every 24 hours
}
}

Expand Down
4 changes: 4 additions & 0 deletions microsetta_private_api/model/log_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class EventSubtype(Enum):
EMAIL_NO_SOURCE = "no_associated_source"
# Fulfillment of a daklapack order must be held
DAK_ORDER_HOLD = "daklapack_order_hold"
# Daklapack order polling idenfitied orders with errors
DAK_ORDER_ERRORS_REPORT = "daklapack_orders_error_report"
# Daklapack polling encountered code errors
DAK_POLLING_ERRORS_REPORT = "daklapack_polling_errors_report"
# Pester daniel if for what are expected to be unusual situations
PESTER_DANIEL = "pester_daniel"
# for project per-sample summaries
Expand Down
3 changes: 2 additions & 1 deletion microsetta_private_api/server_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"daklapack_subscription_key_name": "dak-specific-key",
"daklapack_subscription_key_val": "123abc456d89z",
"daklapack_api_base_url": "https://example.com/dak_api",
"daklapack_service_email": "[email protected]"
"daklapack_service_email": "[email protected]",
"daklapack_errors_report_email": "[email protected]"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
</head>
<body>
<p>
Daklapack reports that the following orders have an error in their system and cannot be fulfilled.
Please identify and correct these errors and then submit replacement Daklapack orders.
</p>
<table>
<thead>
<tr>
<th>Order ID</th>
<th>Article Code</th>
<th>Sent-To Address</th>
<th>Order Submitter</th>
<th>Creation Date</th>
<th>Status Description</th>
</tr>
</thead>
<tbody>
{% for curr_error in errors %}
<tr>
<td>{{ curr_error['order_id'] }}</td>
<td>{{ curr_error['article_code'] }}</td>
<td>{{ curr_error['sent_to_address'] }}</td>
<td>{{ curr_error['order_submitter'] }}</td>
<td>{{ curr_error['creation_date'] }}</td>
<td>{{ curr_error['status_description'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
</head>
<body>
<p>
The Daklapack order status polling code encountered the following exceptions.
Please alert the development team.
</p>

{% for curr_error in errors %}
<p>{{ curr_error }}</p>
{% endfor %}

</body>
</html>

0 comments on commit 71fa6eb

Please sign in to comment.