gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 168/277: implement GET /reserves/RESERVE_ID


From: gnunet
Subject: [taler-merchant] 168/277: implement GET /reserves/RESERVE_ID
Date: Sun, 05 Jul 2020 20:51:21 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 61582eb5a70d02d8bd33978b5152de15b9ffb816
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Jun 1 18:51:24 2020 +0200

    implement GET /reserves/RESERVE_ID
---
 src/include/taler_merchant_service.h |   2 +-
 src/lib/Makefile.am                  |   1 +
 src/lib/merchant_api_get_reserve.c   | 314 +++++++++++++++++++++++++++++++++++
 3 files changed, 316 insertions(+), 1 deletion(-)

diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 79391c4..68550be 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -2598,7 +2598,7 @@ TALER_MERCHANT_reserve_get (struct GNUNET_CURL_Context 
*ctx,
                             const char *backend_url,
                             const struct TALER_ReservePublicKeyP *reserve_pub,
                             bool fetch_tips,
-                            TALER_MERCHANT_ReservesGetCallback cb,
+                            TALER_MERCHANT_ReserveGetCallback cb,
                             void *cb_cls);
 
 
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 2ed5827..482cfb3 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -23,6 +23,7 @@ libtalermerchant_la_SOURCES = \
   merchant_api_get_orders.c \
   merchant_api_get_product.c \
   merchant_api_get_products.c \
+  merchant_api_get_reserve.c \
   merchant_api_get_reserves.c \
   merchant_api_get_transfers.c \
   merchant_api_lock_product.c \
diff --git a/src/lib/merchant_api_get_reserve.c 
b/src/lib/merchant_api_get_reserve.c
new file mode 100644
index 0000000..a836b8b
--- /dev/null
+++ b/src/lib/merchant_api_get_reserve.c
@@ -0,0 +1,314 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2017, 2020 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
+  Foundation; either version 2.1, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
details.
+
+  You should have received a copy of the GNU Lesser General Public License 
along with
+  TALER; see the file COPYING.LGPL.  If not, see
+  <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file lib/merchant_api_get_reserve.c
+ * @brief Implementation of the GET /reserve request of the merchant's HTTP API
+ * @author Marcello Stanisci
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <curl/curl.h>
+#include <jansson.h>
+#include <microhttpd.h> /* just for HTTP status codes */
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include "taler_merchant_service.h"
+#include <taler/taler_json_lib.h>
+#include <taler/taler_signatures.h>
+
+
+/**
+ * @brief A Handle for tracking wire reserve.
+ */
+struct TALER_MERCHANT_ReserveGetHandle
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_MERCHANT_ReserveGetCallback cb;
+
+  /**
+   * Closure for @a cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+};
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP GET /reserve request.
+ *
+ * @param cls the `struct TALER_MERCHANT_ReserveGetHandle`
+ * @param response_code HTTP response code, 0 on error
+ * @param json response body, NULL if not in JSON
+ */
+static void
+handle_reserve_get_finished (void *cls,
+                             long response_code,
+                             const void *response)
+{
+  struct TALER_MERCHANT_ReserveGetHandle *rgh = cls;
+  const json_t *json = response;
+  struct TALER_MERCHANT_HttpResponse hr = {
+    .http_status = (unsigned int) response_code,
+    .reply = json
+  };
+
+  rgh->job = NULL;
+  switch (response_code)
+  {
+  case 0:
+    hr.ec = TALER_EC_INVALID_RESPONSE;
+    break;
+  case MHD_HTTP_OK:
+    {
+      struct TALER_MERCHANT_ReserveSummary rs;
+      const json_t *tips;
+      struct GNUNET_JSON_Specification spec[] = {
+        TALER_JSON_spec_amount ("merchant_initial_amount",
+                                &rs.merchant_initial_amount),
+        TALER_JSON_spec_amount ("exchange_initial_amount",
+                                &rs.exchange_initial_amount),
+        TALER_JSON_spec_amount ("pickup_amount",
+                                &rs.pickup_amount),
+        TALER_JSON_spec_amount ("committed_amount",
+                                &rs.committed_amount),
+        GNUNET_JSON_spec_fixed_auto ("reserve_pub",
+                                     &rs.reserve_pub),
+        GNUNET_JSON_spec_absolute_time ("creation_time",
+                                        &rs.creation_time),
+        GNUNET_JSON_spec_absolute_time ("expiration_time",
+                                        &rs.expiration_time),
+        GNUNET_JSON_spec_bool ("active",
+                               &rs.active),
+        GNUNET_JSON_spec_end ()
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (json,
+                             spec,
+                             NULL, NULL))
+      {
+        GNUNET_break_op (0);
+        hr.http_status = 0;
+        hr.ec = TALER_EC_INVALID_RESPONSE;
+        break;
+      }
+
+      tips = json_object_get (json,
+                              "tips");
+      if (NULL == tips)
+      {
+        rgh->cb (rgh->cb_cls,
+                 &hr,
+                 &rs,
+                 0,
+                 NULL);
+        TALER_MERCHANT_reserve_get_cancel (rgh);
+        return;
+      }
+      if (! json_is_array (tips))
+      {
+        GNUNET_break_op (0);
+        hr.http_status = 0;
+        hr.ec = TALER_EC_INVALID_RESPONSE;
+        break;
+      }
+      {
+        size_t tds_length;
+        json_t *tip;
+        struct TALER_MERCHANT_TipDetails *tds;
+        unsigned int i;
+        bool ok;
+
+        tds_length = json_array_size (tips);
+        tds = GNUNET_new_array (tds_length,
+                                struct TALER_MERCHANT_TipDetails);
+        ok = true;
+        json_array_foreach (tips, i, tip) {
+          struct TALER_MERCHANT_TipDetails *td = &tds[i];
+          struct GNUNET_JSON_Specification ispec[] = {
+            TALER_JSON_spec_amount ("amount",
+                                    &td->amount),
+            GNUNET_JSON_spec_fixed_auto ("tip_id",
+                                         &td->tip_id),
+            GNUNET_JSON_spec_string ("reason",
+                                     &td->reason),
+            GNUNET_JSON_spec_end ()
+          };
+
+          if (GNUNET_OK !=
+              GNUNET_JSON_parse (tip,
+                                 ispec,
+                                 NULL, NULL))
+          {
+            GNUNET_break_op (0);
+            ok = false;
+            break;
+          }
+        }
+
+        if (! ok)
+        {
+          GNUNET_break_op (0);
+          GNUNET_free (tds);
+          hr.http_status = 0;
+          hr.ec = TALER_EC_INVALID_RESPONSE;
+          break;
+        }
+        rgh->cb (rgh->cb_cls,
+                 &hr,
+                 &rs,
+                 tds_length,
+                 tds);
+        GNUNET_free (tds);
+        TALER_MERCHANT_reserve_get_cancel (rgh);
+        return;
+      }
+    }
+  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);
+    break;
+  default:
+    /* unexpected response code */
+    GNUNET_break_op (0);
+    TALER_MERCHANT_parse_error_details_ (json,
+                                         response_code,
+                                         &hr);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d\n",
+                (unsigned int) response_code,
+                (int) hr.ec);
+    response_code = 0;
+    break;
+  }
+  rgh->cb (rgh->cb_cls,
+           &hr,
+           NULL,
+           0,
+           NULL);
+  TALER_MERCHANT_reserve_get_cancel (rgh);
+}
+
+
+/**
+ * Issue a GET /reserve/$RESERVE_ID request to the backend.  Queries the 
backend
+ * about the status of a reserve.
+ *
+ * @param ctx execution context
+ * @param backend_url base URL of the merchant backend
+ * @param reserve_pub which reserve should be queried
+ * @param tips should we return details about the tips issued from the reserve
+ * @param cb function to call with the result(s)
+ * @param cb_cls closure for @a cb
+ * @return handle for this operation, NULL upon errors
+ */
+struct TALER_MERCHANT_ReserveGetHandle *
+TALER_MERCHANT_reserve_get (struct GNUNET_CURL_Context *ctx,
+                            const char *backend_url,
+                            const struct TALER_ReservePublicKeyP *reserve_pub,
+                            bool fetch_tips,
+                            TALER_MERCHANT_ReserveGetCallback cb,
+                            void *cb_cls)
+{
+  struct TALER_MERCHANT_ReserveGetHandle *rgh;
+  CURL *eh;
+
+  rgh = GNUNET_new (struct TALER_MERCHANT_ReserveGetHandle);
+  rgh->ctx = ctx;
+  rgh->cb = cb;
+  rgh->cb_cls = cb_cls;
+  {
+    char res_str[sizeof (*reserve_pub) * 2];
+    char arg_str[sizeof (res_str) + 32];
+    char *end;
+
+    end = GNUNET_STRINGS_data_to_string (reserve_pub,
+                                         sizeof (*reserve_pub),
+                                         res_str,
+                                         sizeof (res_str));
+    *end = '\0';
+    GNUNET_snprintf (arg_str,
+                     sizeof (arg_str),
+                     "/reserves/%s",
+                     res_str);
+    rgh->url = TALER_url_join (backend_url,
+                               arg_str,
+                               "tips",
+                               fetch_tips ? "yes" : "no",
+                               NULL);
+  }
+  if (NULL == rgh->url)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not construct request URL.\n");
+    GNUNET_free (rgh);
+    return NULL;
+  }
+  eh = curl_easy_init ();
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_URL,
+                                   rgh->url));
+  rgh->job = GNUNET_CURL_job_add (ctx,
+                                  eh,
+                                  GNUNET_YES,
+                                  &handle_reserve_get_finished,
+                                  rgh);
+  return rgh;
+}
+
+
+/**
+ * Cancel a GET /reserves/$RESERVE_ID request.
+ *
+ * @param rgh handle to the request to be canceled
+ */
+void
+TALER_MERCHANT_reserve_get_cancel (
+  struct TALER_MERCHANT_ReserveGetHandle *rgh)
+{
+  if (NULL != rgh->job)
+  {
+    GNUNET_CURL_job_cancel (rgh->job);
+    rgh->job = NULL;
+  }
+  GNUNET_free (rgh->url);
+  GNUNET_free (rgh);
+}
+
+
+/* end of merchant_api_get_reserve.c */

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