gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: modernize POST /transfers API


From: gnunet
Subject: [taler-merchant] branch master updated: modernize POST /transfers API
Date: Sun, 23 Apr 2023 14:40:07 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 4b7d9f5e modernize POST /transfers API
4b7d9f5e is described below

commit 4b7d9f5e19e9f28ec1163f3b6e5c00f0805e6221
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Apr 23 14:40:05 2023 +0200

    modernize POST /transfers API
---
 src/include/taler_merchant_service.h         |  89 ++++++++++++++++----
 src/lib/merchant_api_post_transfers.c        | 120 +++++++++++++--------------
 src/testing/testing_api_cmd_post_transfers.c |  36 +++-----
 3 files changed, 142 insertions(+), 103 deletions(-)

diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 49bc83fd..92e18335 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -2898,31 +2898,88 @@ struct TALER_MERCHANT_TrackTransferDetail
 
 };
 
+
+/**
+ * @brief Response to a POST /transfers operation from a merchant's backend.
+ */
+struct TALER_MERCHANT_PostTransfersResponse
+{
+  /**
+   * HTTP response details
+   */
+  struct TALER_MERCHANT_HttpResponse hr;
+
+  /**
+   * Details depending on HTTP status.
+   */
+  union
+  {
+
+    /**
+     * Details in case of success (#MHD_HTTP_OK).
+     */
+    struct
+    {
+
+      /**
+       * when did the transfer happen (according to the exchange)
+       */
+      struct GNUNET_TIME_Timestamp execution_time;
+
+      /**
+       * total amount of the wire transfer
+       */
+      struct TALER_Amount total_amount;
+
+      /**
+       * how much did the exchange charge in terms of wire fees
+       */
+      struct TALER_Amount wire_fee;
+
+      /**
+       * Length of the @e details array
+       */
+      unsigned int details_length;
+
+      /**
+       * array with details about the combined transactions
+       */
+      const struct TALER_MERCHANT_TrackTransferDetail *details;
+    } success;
+
+    /**
+     * Details if we got an #MHD_HTTP_BAD_GATEWAY.
+     */
+    struct
+    {
+      /**
+       * HTTP status of the exchange (or 0 if not available).
+       */
+      unsigned int exchange_http_status;
+
+      /**
+       * Error code of the exchange (or TALER_EC_NONE if not available).
+       */
+      enum TALER_ErrorCode exchange_ec;
+
+    } bad_gateway;
+
+  } details;
+
+};
+
+
 /**
  * Callbacks of this type are used to work the result of submitting a
  * POST /transfers request to a merchant
  *
  * @param cls closure
- * @param hr HTTP response details
- * @param execution_time when did the transfer happen (according to the 
exchange),
- *          #GNUNET_TIME_UNIT_FOREVER_ABS if the transfer did not yet happen 
or if
- *          we have no data from the exchange about it
- * @param total_amount total amount of the wire transfer, or NULL if the 
exchange did
- *             not provide any details
- * @param wire_fee how much did the exchange charge in terms of wire fees, or 
NULL
- *             if the exchange did not provide any details
- * @param details_length length of the @a details array
- * @param details array with details about the combined transactions
+ * @param ptr response details
  */
 typedef void
 (*TALER_MERCHANT_PostTransfersCallback) (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  struct GNUNET_TIME_Timestamp execution_time,
-  const struct TALER_Amount *total_amount,
-  const struct TALER_Amount *wire_fee,
-  unsigned int details_length,
-  const struct TALER_MERCHANT_TrackTransferDetail details[]);
+  const struct TALER_MERCHANT_PostTransfersResponse *ptr);
 
 
 /**
diff --git a/src/lib/merchant_api_post_transfers.c 
b/src/lib/merchant_api_post_transfers.c
index 450b46d9..2a1a3f68 100644
--- a/src/lib/merchant_api_post_transfers.c
+++ b/src/lib/merchant_api_post_transfers.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2021 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -85,68 +85,68 @@ handle_post_transfers_finished (void *cls,
                                 const void *response)
 {
   struct TALER_MERCHANT_PostTransfersHandle *pth = cls;
-  const json_t *json = response;
-  json_t *deposit_sum = NULL;
-  struct TALER_MERCHANT_HttpResponse hr = {
-    .http_status = (unsigned int) response_code,
-    .reply = json
+  struct TALER_MERCHANT_PostTransfersResponse ptr = {
+    .hr.reply = response,
+    .hr.http_status = (unsigned int) response_code
   };
 
   pth->job = NULL;
   switch (response_code)
   {
   case 0:
-    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     break;
   case MHD_HTTP_OK:
     {
-      struct TALER_Amount total;
-      struct TALER_Amount wire_fee;
-      struct GNUNET_TIME_Timestamp execution_time;
       json_t *deposit_sums;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_any ("total",
-                                    &total),
-        TALER_JSON_spec_amount_any ("wire_fee",
-                                    &wire_fee),
-        GNUNET_JSON_spec_timestamp ("execution_time",
-                                    &execution_time),
+        TALER_JSON_spec_amount_any (
+          "total",
+          &ptr.details.success.total_amount),
+        TALER_JSON_spec_amount_any (
+          "wire_fee",
+          &ptr.details.success.wire_fee),
+        GNUNET_JSON_spec_timestamp (
+          "execution_time",
+          &ptr.details.success.execution_time),
         GNUNET_JSON_spec_json ("deposit_sums",
                                &deposit_sums),
         GNUNET_JSON_spec_end ()
       };
 
       if (GNUNET_OK !=
-          GNUNET_JSON_parse (json,
+          GNUNET_JSON_parse (ptr.hr.reply,
                              spec,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
-        hr.http_status = 0;
-        hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+        ptr.hr.http_status = 0;
+        ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+        break;
+      }
+      if (! json_is_array (deposit_sums))
+      {
+        GNUNET_break_op (0);
+        GNUNET_JSON_parse_free (spec);
+        ptr.hr.http_status = 0;
+        ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
         break;
       }
-      else
       {
-        size_t deposit_sums_length;
         struct TALER_MERCHANT_TrackTransferDetail *details;
         unsigned int i;
         bool ok;
+        json_t *deposit_sum;
 
-        if (! json_is_array (deposit_sums))
-        {
-          GNUNET_break_op (0);
-          GNUNET_JSON_parse_free (spec);
-          hr.http_status = 0;
-          hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
-          break;
-        }
-        deposit_sums_length = json_array_size (deposit_sums);
-        details = GNUNET_new_array (deposit_sums_length,
+        ptr.details.success.details_length
+          = json_array_size (deposit_sums);
+        details = GNUNET_new_array (ptr.details.success.details_length,
                                     struct TALER_MERCHANT_TrackTransferDetail);
+        ptr.details.success.details = details;
         ok = true;
         json_array_foreach (deposit_sums, i, deposit_sum) {
-          struct TALER_MERCHANT_TrackTransferDetail *d = &details[i];
+          struct TALER_MERCHANT_TrackTransferDetail *d
+            = &details[i];
           struct GNUNET_JSON_Specification ispec[] = {
             GNUNET_JSON_spec_string ("order_id",
                                      &d->order_id),
@@ -173,17 +173,12 @@ handle_post_transfers_finished (void *cls,
           GNUNET_break_op (0);
           GNUNET_free (details);
           GNUNET_JSON_parse_free (spec);
-          hr.http_status = 0;
-          hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+          ptr.hr.http_status = 0;
+          ptr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
           break;
         }
         pth->cb (pth->cb_cls,
-                 &hr,
-                 execution_time,
-                 &total,
-                 &wire_fee,
-                 deposit_sums_length,
-                 details);
+                 &ptr);
         GNUNET_free (details);
         GNUNET_JSON_parse_free (spec);
         TALER_MERCHANT_transfers_post_cancel (pth);
@@ -193,8 +188,8 @@ handle_post_transfers_finished (void *cls,
   case MHD_HTTP_ACCEPTED:
     break;
   case MHD_HTTP_UNAUTHORIZED:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply);
+    ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply);
     /* Nothing really to verify, merchant says we need to authenticate. */
     break;
   case MHD_HTTP_NOT_FOUND:
@@ -202,20 +197,20 @@ handle_post_transfers_finished (void *cls,
        happen, we should pass the JSON reply to the application */
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Did not find any data\n");
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply);
+    ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply);
     break;
   case MHD_HTTP_INTERNAL_SERVER_ERROR:
     /* Server had an internal issue; we should retry, but this API
        leaves this to the application */
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply);
+    ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply);
     break;
   case MHD_HTTP_BAD_GATEWAY:
     /* Exchange had an issue; we should retry, but this API
        leaves this to the application */
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply);
+    ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply);
     {
       uint32_t eec;
       uint32_t ehc;
@@ -228,16 +223,22 @@ handle_post_transfers_finished (void *cls,
       };
 
       if (GNUNET_OK !=
-          GNUNET_JSON_parse (deposit_sum,
+          GNUNET_JSON_parse (ptr.hr.reply,
                              ispec,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
+        ptr.details.bad_gateway.exchange_http_status = 0;
+        ptr.details.bad_gateway.exchange_ec = TALER_EC_NONE;
         break;
       }
       else
       {
-        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+        ptr.details.bad_gateway.exchange_http_status
+          = (unsigned int) ehc;
+        ptr.details.bad_gateway.exchange_ec
+          = (enum TALER_ErrorCode) eec;
+        GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                     "Exchange returned %u/%u\n",
                     (unsigned int) eec,
                     (unsigned int) ehc);
@@ -247,28 +248,23 @@ handle_post_transfers_finished (void *cls,
   case MHD_HTTP_GATEWAY_TIMEOUT:
     /* Server had an internal issue; we should retry, but this API
        leaves this to the application */
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ptr.hr.ec = TALER_JSON_get_error_code (ptr.hr.reply);
+    ptr.hr.hint = TALER_JSON_get_error_hint (ptr.hr.reply);
     break;
   default:
     /* unexpected response code */
     GNUNET_break_op (0);
-    TALER_MERCHANT_parse_error_details_ (json,
+    TALER_MERCHANT_parse_error_details_ (ptr.hr.reply,
                                          response_code,
-                                         &hr);
+                                         &ptr.hr);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unexpected response code %u/%d\n",
-                (unsigned int) response_code,
-                (int) hr.ec);
+                (unsigned int) ptr.hr.http_status,
+                (int) ptr.hr.ec);
     break;
   }
   pth->cb (pth->cb_cls,
-           &hr,
-           GNUNET_TIME_UNIT_FOREVER_TS,
-           NULL,
-           NULL,
-           0,
-           NULL);
+           &ptr);
   TALER_MERCHANT_transfers_post_cancel (pth);
 }
 
diff --git a/src/testing/testing_api_cmd_post_transfers.c 
b/src/testing/testing_api_cmd_post_transfers.c
index 4cff2348..9a01d2d5 100644
--- a/src/testing/testing_api_cmd_post_transfers.c
+++ b/src/testing/testing_api_cmd_post_transfers.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020 Taler Systems SA
+  Copyright (C) 2020, 2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -126,48 +126,34 @@ struct PostTransfersState
  * Callback for a POST /transfers operation.
  *
  * @param cls closure for this function
- * @param hr HTTP response details
- * @param execution_time when did the transfer happen (according to the 
exchange),
- *          #GNUNET_TIME_UNIT_FOREVER_ABS if the transfer did not yet happen 
or if
- *          we have no data from the exchange about it
- * @param total_amount total amount of the wire transfer, or NULL if the 
exchange did
- *             not provide any details
- * @param wire_fee how much did the exchange charge in terms of wire fees, or 
NULL
- *             if the exchange did not provide any details
- * @param details_length length of the @a details array
- * @param details array with details about the combined transactions
+ * @param ptr response details
  */
 static void
 transfers_cb (void *cls,
-              const struct TALER_MERCHANT_HttpResponse *hr,
-              struct GNUNET_TIME_Timestamp execution_time,
-              const struct TALER_Amount *total_amount,
-              const struct TALER_Amount *wire_fee,
-              unsigned int details_length,
-              const struct TALER_MERCHANT_TrackTransferDetail details[])
+              const struct TALER_MERCHANT_PostTransfersResponse *ptr)
 {
   struct PostTransfersState *pts = cls;
 
   pts->pth = NULL;
-  if (pts->http_status != hr->http_status)
+  if (pts->http_status != ptr->hr.http_status)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unexpected response code %u (%d) to command %s\n",
-                hr->http_status,
-                (int) hr->ec,
+                ptr->hr.http_status,
+                (int) ptr->hr.ec,
                 TALER_TESTING_interpreter_get_current_label (pts->is));
     TALER_TESTING_interpreter_fail (pts->is);
     return;
   }
-  switch (hr->http_status)
+  switch (ptr->hr.http_status)
   {
   case MHD_HTTP_OK:
     {
-      pts->execution_time = execution_time;
-      pts->wire_fee = *wire_fee;
+      pts->execution_time = ptr->details.success.execution_time;
+      pts->wire_fee = ptr->details.success.wire_fee;
       fprintf (stderr,
                "FIXME");
-      json_dumpf (hr->reply,
+      json_dumpf (ptr->hr.reply,
                   stderr,
                   0);
 #if FIXME_WRITE_PROPPER_CHECK_OF_RETURNED_DATA_HERE
@@ -316,7 +302,7 @@ transfers_cb (void *cls,
     GNUNET_break (0);
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Unhandled HTTP status %u for POST /transfers.\n",
-                hr->http_status);
+                ptr->hr.http_status);
   }
   TALER_TESTING_interpreter_next (pts->is);
 }

-- 
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]