diff options
author | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-08-27 13:57:21 -0400 |
---|---|---|
committer | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-08-27 13:57:21 -0400 |
commit | 01d4723f8e58a7b68b0d814b58cc6c3e72702575 (patch) | |
tree | 60ef3ab071f68b8ced300e51a7fda89325fb28e7 /src/backend | |
parent | d354d119db7ca0195cb93140bf3160b11449fa92 (diff) | |
download | merchant-01d4723f8e58a7b68b0d814b58cc6c3e72702575.tar.gz merchant-01d4723f8e58a7b68b0d814b58cc6c3e72702575.tar.bz2 merchant-01d4723f8e58a7b68b0d814b58cc6c3e72702575.zip |
address some backend fixmes
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-get-products-ID.c | 8 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c | 249 |
2 files changed, 142 insertions, 115 deletions
diff --git a/src/backend/taler-merchant-httpd_private-get-products-ID.c b/src/backend/taler-merchant-httpd_private-get-products-ID.c index 41ef612d..f446ac21 100644 --- a/src/backend/taler-merchant-httpd_private-get-products-ID.c +++ b/src/backend/taler-merchant-httpd_private-get-products-ID.c @@ -53,7 +53,13 @@ TMH_private_get_products_ID (const struct TMH_RequestHandler *rh, TALER_EC_GET_PRODUCTS_DB_LOOKUP_ERROR, NULL); } - // FIXME: MUST return 404 if qs == 0, not this! + else if (0 == qs) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_GET_PRODUCTS_NOT_FOUND, + NULL); + } { json_t *reply; diff --git a/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c b/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c index ce79037e..d2d7d65f 100644 --- a/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c +++ b/src/backend/taler-merchant-httpd_private-patch-orders-ID-forget.c @@ -28,6 +28,12 @@ /** + * How often do we retry the UPDATE database transaction? + */ +#define MAX_RETRIES 3 + + +/** * Forget part of the contract terms. * * @param cls pointer to the result of the forget operation. @@ -66,132 +72,147 @@ TMH_private_patch_orders_ID_forget (const struct TMH_RequestHandler *rh, json_t *contract_terms; uint64_t order_serial; - // FIXME: should be a transaction with the update! - qs = TMH_db->lookup_contract_terms (TMH_db->cls, - hc->instance->settings.id, - order_id, - &contract_terms, - &order_serial); - switch (qs) - { - case GNUNET_DB_STATUS_HARD_ERROR: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR, - NULL); - case GNUNET_DB_STATUS_SOFT_ERROR: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_ORDERS_CLAIM_SOFT_DB_ERROR, - NULL); - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_FORGET_ORDER_NOT_FOUND, - order_id); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - GNUNET_assert (NULL != contract_terms); - break; - } - - { - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("fields", - &fields), - GNUNET_JSON_spec_end () - }; - enum GNUNET_GenericReturnValue res; - - res = TALER_MHD_parse_json_data (connection, - hc->request_body, - spec); - if (GNUNET_OK != res) - return (GNUNET_NO == res) - ? MHD_YES - : MHD_NO; - } - if (! (json_is_array (fields))) + for (unsigned int i = 0; i<MAX_RETRIES; i++) { - json_decref (contract_terms); - json_decref (fields); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_PARAMETER_MALFORMED, - "fields"); - } - - { - size_t index; - json_t *value; - json_array_foreach (fields, index, value) { - int forget_status = GNUNET_OK; - int expand_status; + if (GNUNET_OK != + TMH_db->start (TMH_db->cls, + "forget order")) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_FORGET_ORDER_DB_START_ERROR, + NULL); + } + qs = TMH_db->lookup_contract_terms (TMH_db->cls, + hc->instance->settings.id, + order_id, + &contract_terms, + &order_serial); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + TMH_db->rollback (TMH_db->cls); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR, + NULL); + case GNUNET_DB_STATUS_SOFT_ERROR: + goto retry; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + TMH_db->rollback (TMH_db->cls); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_FORGET_ORDER_NOT_FOUND, + order_id); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + GNUNET_assert (NULL != contract_terms); + break; + } - if (! (json_is_string (value))) - { - json_decref (contract_terms); - json_decref (fields); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_FORGET_PATH_SYNTAX_INCORRECT, - "field is not a string"); - } - expand_status = TALER_JSON_expand_path (contract_terms, - json_string_value (value), - &forget, - &forget_status); - if (GNUNET_SYSERR == forget_status) + { + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_json ("fields", + &fields), + GNUNET_JSON_spec_end () + }; + enum GNUNET_GenericReturnValue res; + + res = TALER_MHD_parse_json_data (connection, + hc->request_body, + spec); + if (GNUNET_OK != res) { - /* We tried to forget a field that isn't forgettable */ - json_decref (contract_terms); - json_decref (fields); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_CONFLICT, - TALER_EC_FORGET_PATH_NOT_FORGETTABLE, - json_string_value (value)); - } - if (GNUNET_SYSERR == expand_status) - { - /* One of the paths was malformed and couldn't be expanded */ - json_decref (contract_terms); - json_decref (fields); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_FORGET_PATH_SYNTAX_INCORRECT, - json_string_value (value)); + TMH_db->rollback (TMH_db->cls); + return (GNUNET_NO == res) + ? MHD_YES + : MHD_NO; } } - } + if (! (json_is_array (fields))) + { + TMH_db->rollback (TMH_db->cls); + json_decref (contract_terms); + json_decref (fields); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_PARAMETER_MALFORMED, + "fields"); + } - qs = TMH_db->update_contract_terms (TMH_db->cls, - hc->instance->settings.id, - order_id, - contract_terms); + { + size_t index; + json_t *value; + json_array_foreach (fields, index, value) { + int forget_status = GNUNET_OK; + int expand_status; + + if (! (json_is_string (value))) + { + TMH_db->rollback (TMH_db->cls); + json_decref (contract_terms); + json_decref (fields); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_FORGET_PATH_SYNTAX_INCORRECT, + "field is not a string"); + } + expand_status = TALER_JSON_expand_path (contract_terms, + json_string_value (value), + &forget, + &forget_status); + if (GNUNET_SYSERR == forget_status) + { + /* We tried to forget a field that isn't forgettable */ + TMH_db->rollback (TMH_db->cls); + json_decref (contract_terms); + json_decref (fields); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_FORGET_PATH_NOT_FORGETTABLE, + json_string_value (value)); + } + if (GNUNET_SYSERR == expand_status) + { + /* One of the paths was malformed and couldn't be expanded */ + TMH_db->rollback (TMH_db->cls); + json_decref (contract_terms); + json_decref (fields); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_FORGET_PATH_SYNTAX_INCORRECT, + json_string_value (value)); + } + } + } - switch (qs) + qs = TMH_db->update_contract_terms (TMH_db->cls, + hc->instance->settings.id, + order_id, + contract_terms); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + TMH_db->rollback (TMH_db->cls); + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + goto retry; + else + goto giveup; + } + qs = TMH_db->commit (TMH_db->cls); +retry: + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + continue; + break; + } +giveup: + json_decref (contract_terms); + json_decref (fields); + if (0 > qs) { - case GNUNET_DB_STATUS_HARD_ERROR: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR, - NULL); - case GNUNET_DB_STATUS_SOFT_ERROR: - // FIXME: We should not re-try a few times AND make this a larger transaction! return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_ORDERS_CLAIM_SOFT_DB_ERROR, + TALER_EC_FORGET_ORDER_DB_COMMIT_ERROR, NULL); - case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - GNUNET_break (0); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_FORGET_ORDER_NOT_FOUND, - order_id); - case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - break; } - json_decref (contract_terms); - json_decref (fields); return TALER_MHD_reply_static (connection, MHD_HTTP_OK, |