diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-templates.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-templates.c | 171 |
1 files changed, 83 insertions, 88 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-templates.c b/src/backend/taler-merchant-httpd_private-post-templates.c index 276e225f..4a5d8133 100644 --- a/src/backend/taler-merchant-httpd_private-post-templates.c +++ b/src/backend/taler-merchant-httpd_private-post-templates.c @@ -29,12 +29,6 @@ /** - * How often do we retry the simple INSERT database transaction? - */ -#define MAX_RETRIES 3 - - -/** * Check if the two templates are identical. * * @param t1 template to compare @@ -47,12 +41,12 @@ templates_equal (const struct TALER_MERCHANTDB_TemplateDetails *t1, { return ( (0 == strcmp (t1->template_description, t2->template_description)) && - ( ( (NULL == t1->pos_key) && - (NULL == t2->pos_key) ) || - ( (NULL != t1->pos_key) && - (NULL != t2->pos_key) && - (0 == strcmp (t1->pos_key, - t2->pos_key))) ) && + ( ( (NULL == t1->otp_id) && + (NULL == t2->otp_id) ) || + ( (NULL != t1->otp_id) && + (NULL != t2->otp_id) && + (0 == strcmp (t1->otp_id, + t2->otp_id))) ) && (1 == json_equal (t1->template_contract, t2->template_contract)) ); } @@ -67,24 +61,20 @@ TMH_private_post_templates (const struct TMH_RequestHandler *rh, struct TALER_MERCHANTDB_TemplateDetails tp = { 0 }; const char *template_id; enum GNUNET_DB_QueryStatus qs; - uint32_t pos_algorithm = 0; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("template_id", &template_id), GNUNET_JSON_spec_string ("template_description", (const char **) &tp.template_description), GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_uint32 ("pos_algorithm", - &pos_algorithm), - NULL), - GNUNET_JSON_spec_mark_optional ( - GNUNET_JSON_spec_string ("pos_key", - (const char **) &tp.pos_key), + GNUNET_JSON_spec_string ("otp_id", + (const char **) &tp.otp_id), NULL), GNUNET_JSON_spec_json ("template_contract", &tp.template_contract), GNUNET_JSON_spec_end () }; + uint64_t otp_serial = 0; GNUNET_assert (NULL != mi); { @@ -101,7 +91,6 @@ TMH_private_post_templates (const struct TMH_RequestHandler *rh, : MHD_NO; } } - tp.pos_algorithm = (enum TALER_MerchantConfirmationAlgorithm) pos_algorithm; if (! TMH_template_contract_valid (tp.template_contract)) { GNUNET_break_op (0); @@ -115,23 +104,63 @@ TMH_private_post_templates (const struct TMH_RequestHandler *rh, "template_contract"); } - /* finally, interact with DB until no serialization error */ - for (unsigned int i = 0; i<MAX_RETRIES; i++) + if (NULL != tp.otp_id) { - /* Test if a template of this id is known */ - struct TALER_MERCHANTDB_TemplateDetails etp; - - if (GNUNET_OK != - TMH_db->start (TMH_db->cls, - "/post templates")) + qs = TMH_db->select_otp_serial (TMH_db->cls, + mi->settings.id, + tp.otp_id, + &otp_serial); + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: + case GNUNET_DB_STATUS_SOFT_ERROR: GNUNET_break (0); GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_START_FAILED, + TALER_EC_GENERIC_DB_STORE_FAILED, + "select_otp_serial"); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_MERCHANT_GENERIC_OTP_DEVICE_UNKNOWN, NULL); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; } + } + + qs = TMH_db->insert_template (TMH_db->cls, + mi->settings.id, + template_id, + otp_serial, + &tp); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_break (0); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + NULL); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_static (connection, + MHD_HTTP_NO_CONTENT, + NULL, + NULL, + 0); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + break; + } + + { + /* Test if a template of this id is known */ + struct TALER_MERCHANTDB_TemplateDetails etp; + qs = TMH_db->lookup_template (TMH_db->cls, mi->settings.id, template_id, @@ -139,79 +168,45 @@ TMH_private_post_templates (const struct TMH_RequestHandler *rh, switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: + case GNUNET_DB_STATUS_SOFT_ERROR: /* Clean up and fail hard */ GNUNET_break (0); - TMH_db->rollback (TMH_db->cls); GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_FETCH_FAILED, NULL); - case GNUNET_DB_STATUS_SOFT_ERROR: - /* restart transaction */ - goto retry; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: - /* Good, we can proceed! */ - break; + GNUNET_break (0); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + "logic error"); case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: - /* idempotency check: is etp == tp? */ - { - bool eq; - - eq = templates_equal (&tp, - &etp); - TALER_MERCHANTDB_template_details_free (&etp); - TMH_db->rollback (TMH_db->cls); - GNUNET_JSON_parse_free (spec); - return eq - ? TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0) - : TALER_MHD_reply_with_error (connection, - MHD_HTTP_CONFLICT, - TALER_EC_MERCHANT_PRIVATE_POST_TEMPLATES_CONFLICT_TEMPLATE_EXISTS, - template_id); - } - } /* end switch (qs) */ - - qs = TMH_db->insert_template (TMH_db->cls, - mi->settings.id, - template_id, - &tp); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - { - TMH_db->rollback (TMH_db->cls); break; } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) + /* idempotency check: is etp == tp? */ { - qs = TMH_db->commit (TMH_db->cls); - if (GNUNET_DB_STATUS_SOFT_ERROR != qs) - break; + bool eq; + + eq = templates_equal (&tp, + &etp); + TALER_MERCHANTDB_template_details_free (&etp); + TMH_db->rollback (TMH_db->cls); + GNUNET_JSON_parse_free (spec); + return eq + ? TALER_MHD_reply_static (connection, + MHD_HTTP_NO_CONTENT, + NULL, + NULL, + 0) + : TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_MERCHANT_PRIVATE_POST_TEMPLATES_CONFLICT_TEMPLATE_EXISTS, + template_id); } -retry: - GNUNET_assert (GNUNET_DB_STATUS_SOFT_ERROR == qs); - TMH_db->rollback (TMH_db->cls); - } /* for RETRIES loop */ - GNUNET_JSON_parse_free (spec); - if (qs < 0) - { - GNUNET_break (0); - return TALER_MHD_reply_with_error ( - connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - (GNUNET_DB_STATUS_SOFT_ERROR == qs) - ? TALER_EC_GENERIC_DB_SOFT_FAILURE - : TALER_EC_GENERIC_DB_COMMIT_FAILED, - NULL); } - return TALER_MHD_reply_static (connection, - MHD_HTTP_NO_CONTENT, - NULL, - NULL, - 0); } |