gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 167/277: implement TALER_MERCHANT_reserves_get()


From: gnunet
Subject: [taler-merchant] 167/277: implement TALER_MERCHANT_reserves_get()
Date: Sun, 05 Jul 2020 20:51:20 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 8fb5fd3450b0ccd721a86c3ca4e18f154f13d7ae
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Jun 1 15:14:01 2020 +0200

    implement TALER_MERCHANT_reserves_get()
---
 src/lib/Makefile.am                 |   1 +
 src/lib/merchant_api_get_reserves.c | 305 ++++++++++++++++++++++++++++++++++++
 2 files changed, 306 insertions(+)

diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index ecb5e9a..2ed5827 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_reserves.c \
   merchant_api_get_transfers.c \
   merchant_api_lock_product.c \
   merchant_api_patch_instance.c \
diff --git a/src/lib/merchant_api_get_reserves.c 
b/src/lib/merchant_api_get_reserves.c
new file mode 100644
index 0000000..102d433
--- /dev/null
+++ b/src/lib/merchant_api_get_reserves.c
@@ -0,0 +1,305 @@
+/*
+  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_reserves.c
+ * @brief Implementation of the GET /reserves 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 reserves.
+ */
+struct TALER_MERCHANT_ReservesGetHandle
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_MERCHANT_ReservesGetCallback 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 /reserves request.
+ *
+ * @param cls the `struct TALER_MERCHANT_ReservesGetHandle`
+ * @param response_code HTTP response code, 0 on error
+ * @param json response body, NULL if not in JSON
+ */
+static void
+handle_reserves_get_finished (void *cls,
+                              long response_code,
+                              const void *response)
+{
+  struct TALER_MERCHANT_ReservesGetHandle *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:
+    {
+      json_t *reserves;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_json ("reserves",
+                               &reserves),
+        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;
+      }
+      else
+      {
+        size_t rds_length;
+        struct TALER_MERCHANT_ReserveSummary *rds;
+        json_t *reserve;
+        unsigned int i;
+        bool ok;
+
+        if (! json_is_array (reserves))
+        {
+          GNUNET_break_op (0);
+          GNUNET_JSON_parse_free (spec);
+          hr.http_status = 0;
+          hr.ec = TALER_EC_INVALID_RESPONSE;
+          break;
+        }
+        rds_length = json_array_size (reserves);
+        rds = GNUNET_new_array (rds_length,
+                                struct TALER_MERCHANT_ReserveSummary);
+        ok = true;
+        json_array_foreach (reserves, i, reserve) {
+          struct TALER_MERCHANT_ReserveSummary *rd = &rds[i];
+          struct GNUNET_JSON_Specification ispec[] = {
+            TALER_JSON_spec_amount ("merchant_initial_amount",
+                                    &rd->merchant_initial_amount),
+            TALER_JSON_spec_amount ("exchange_initial_amount",
+                                    &rd->exchange_initial_amount),
+            TALER_JSON_spec_amount ("pickup_amount",
+                                    &rd->pickup_amount),
+            TALER_JSON_spec_amount ("committed_amount",
+                                    &rd->committed_amount),
+            GNUNET_JSON_spec_fixed_auto ("reserve_pub",
+                                         &rd->reserve_pub),
+            GNUNET_JSON_spec_absolute_time ("creation_time",
+                                            &rd->creation_time),
+            GNUNET_JSON_spec_absolute_time ("expiration_time",
+                                            &rd->expiration_time),
+            GNUNET_JSON_spec_bool ("active",
+                                   &rd->active),
+            GNUNET_JSON_spec_end ()
+          };
+
+          if (GNUNET_OK !=
+              GNUNET_JSON_parse (reserve,
+                                 ispec,
+                                 NULL, NULL))
+          {
+            GNUNET_break_op (0);
+            ok = false;
+            break;
+          }
+        }
+
+        if (! ok)
+        {
+          GNUNET_break_op (0);
+          GNUNET_free (rds);
+          GNUNET_JSON_parse_free (spec);
+          hr.http_status = 0;
+          hr.ec = TALER_EC_INVALID_RESPONSE;
+          break;
+        }
+        rgh->cb (rgh->cb_cls,
+                 &hr,
+                 rds_length,
+                 rds);
+        GNUNET_free (rds);
+        GNUNET_JSON_parse_free (spec);
+        TALER_MERCHANT_reserves_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,
+           0,
+           NULL);
+  TALER_MERCHANT_reserves_get_cancel (rgh);
+}
+
+
+/**
+ * Issue a GET /reserves request to the backend.  Informs the backend
+ * that a customer wants to pick up a reserves.
+ *
+ * @param ctx execution context
+ * @param backend_url base URL of the merchant backend
+ * @param after filter for reserves created after this date, use 0 for no 
filtering
+ * @param active filter for reserves that are active
+ * @param failures filter for reserves where we disagree about the balance with
+ *        the exchange
+ * @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_ReservesGetHandle *
+TALER_MERCHANT_reserves_get (struct GNUNET_CURL_Context *ctx,
+                             const char *backend_url,
+                             struct GNUNET_TIME_Absolute after,
+                             enum TALER_MERCHANT_YesNoAll active,
+                             enum TALER_MERCHANT_YesNoAll failures,
+                             TALER_MERCHANT_ReservesGetCallback cb,
+                             void *cb_cls)
+{
+  struct TALER_MERCHANT_ReservesGetHandle *rgh;
+  CURL *eh;
+  const char *active_s = NULL;
+  const char *failures_s = NULL;
+  char *after_s;
+
+  rgh = GNUNET_new (struct TALER_MERCHANT_ReservesGetHandle);
+  rgh->ctx = ctx;
+  rgh->cb = cb;
+  rgh->cb_cls = cb_cls;
+  if (TALER_MERCHANT_YNA_YES == active)
+    active_s = "yes";
+  if (TALER_MERCHANT_YNA_NO == active)
+    active_s = "no";
+  if (TALER_MERCHANT_YNA_YES == failures)
+    failures_s = "yes";
+  if (TALER_MERCHANT_YNA_NO == failures)
+    failures_s = "no";
+  after_s = GNUNET_strdup (GNUNET_STRINGS_absolute_time_to_string (after));
+  rgh->url = TALER_url_join (backend_url,
+                             "reserves",
+                             "active",
+                             active_s,
+                             "failures",
+                             failures_s,
+                             "after",
+                             after.abs_value_us != 0
+                             ? after_s
+                             : NULL,
+                             NULL);
+  GNUNET_free (after_s);
+  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_reserves_get_finished,
+                                  rgh);
+  return rgh;
+}
+
+
+/**
+ * Cancel a GET /reserves request.
+ *
+ * @param rgh handle to the request to be canceled
+ */
+void
+TALER_MERCHANT_reserves_get_cancel (
+  struct TALER_MERCHANT_ReservesGetHandle *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_reserves.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]