gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: address some backend fixmes


From: gnunet
Subject: [taler-merchant] branch master updated: address some backend fixmes
Date: Thu, 27 Aug 2020 19:59:23 +0200

This is an automated email from the git hooks/post-receive script.

jonathan-buchanan pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 01d4723  address some backend fixmes
     new 9272cb8  Merge branch 'master' of ssh://git.taler.net/merchant
01d4723 is described below

commit 01d4723f8e58a7b68b0d814b58cc6c3e72702575
Author: Jonathan Buchanan <jonathan.russ.buchanan@gmail.com>
AuthorDate: Thu Aug 27 13:57:21 2020 -0400

    address some backend fixmes
---
 .../taler-merchant-httpd_private-get-products-ID.c |   8 +-
 ...merchant-httpd_private-patch-orders-ID-forget.c | 249 +++++++++++----------
 src/include/taler_merchant_testing_lib.h           |  21 ++
 src/testing/test_merchant_api.c                    |   5 +
 4 files changed, 168 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 41ef612..f446ac2 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 ce79037..d2d7d65 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
@@ -27,6 +27,12 @@
 #include <taler/taler_json_lib.h>
 
 
+/**
+ * How often do we retry the UPDATE database transaction?
+ */
+#define MAX_RETRIES 3
+
+
 /**
  * Forget part of the contract terms.
  *
@@ -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,
diff --git a/src/include/taler_merchant_testing_lib.h 
b/src/include/taler_merchant_testing_lib.h
index 98751ce..aa0211a 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -613,6 +613,27 @@ TALER_TESTING_cmd_wallet_get_order (const char *label,
                                     unsigned int http_status);
 
 
+/**
+ * Start a long poll for GET /private/orders/$ORDER_ID.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wallet_poll_order_start (
+  const char *label,
+  const char *merchant_url,
+  const char *order_id,
+  struct GNUNET_TIME_Relative timeout);
+
+
+/**
+ * Complete a long poll for GET /private/orders/$ORDER_ID.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wallet_poll_order_conclude (
+  const char *label,
+  unsigned int http_status,
+  const char *poll_start_reference);
+
+
 /**
  * Define a GET /private/orders/$ORDER_ID CMD.
  *
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index d4348bf..9c5a8d3 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -1364,6 +1364,11 @@ run (void *cls,
                                             "product-2",
                                             MHD_HTTP_OK,
                                             "patch-products-p2"),
+    TALER_TESTING_cmd_merchant_get_product ("get-product-nx",
+                                            merchant_url,
+                                            "product-nx",
+                                            MHD_HTTP_NOT_FOUND,
+                                            NULL),
     TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3-nx",
                                               merchant_url,
                                               "product-3",

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]