gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 24/277: implement POST /instances


From: gnunet
Subject: [taler-merchant] 24/277: implement POST /instances
Date: Sun, 05 Jul 2020 20:48:57 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit a417ca1d7cdf654a50ff6913f0071a171e0008e8
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Tue Apr 21 14:25:29 2020 +0200

    implement POST /instances
---
 src/include/taler_merchant_service.h               |  75 +++--
 src/lib/Makefile.am                                |   4 +-
 ...stances_ID.c => merchant_api_delete_instance.c} | 145 +++-------
 src/lib/merchant_api_get_instance.c                | 292 ++++++++++++++++++++
 src/lib/merchant_api_post_instances.c              | 307 +++++++++++++++++++++
 5 files changed, 695 insertions(+), 128 deletions(-)

diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 9cce6c9..c34be1d 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -505,6 +505,58 @@ struct TALER_MERCHANT_Account
 };
 
 
+/**
+ * Details about an instance.
+ */
+struct TALER_MERCHANT_InstanceDetails
+{
+  /**
+   * Name of the merchant instance
+   */
+  const char *name;
+
+  /**
+   * public key of the merchant instance
+   */
+  const struct TALER_MerchantPublicKeyP *merchant_pub;
+
+  /**
+   * physical address of the merchant instance
+   */
+  const json_t *address;
+
+  /**
+   * jurisdiction of the merchant instance
+   */
+  const json_t *jurisdiction;
+
+  /**
+   * default maximum wire fee merchant is willing to fully pay
+   */
+  const struct TALER_Amount *default_max_wire_fee;
+
+  /**
+   * default amortization factor for excess wire fees
+   */
+  uint32_t default_wire_fee_amortization;
+
+  /**
+   * default maximum deposit fee merchant is willing to pay
+   */
+  const struct TALER_Amount *default_max_deposit_fee;
+
+  /**
+   * default wire transfer delay merchant will ask for
+   */
+  struct GNUNET_TIME_Relative default_wire_transfer_delay;
+
+  /**
+   * default validity period for offers merchant makes
+   */
+  struct GNUNET_TIME_Relative default_pay_delay;
+};
+
+
 /**
  * Function called with the result of the GET /instances/$ID operation.
  *
@@ -512,15 +564,7 @@ struct TALER_MERCHANT_Account
  * @param hr HTTP response data
  * @param accounts_length length of the @a accounts array
  * @param accounts bank accounts of the merchant instance
- * @param name name of the merchant instance
- * @param merchant_pub public key of the merchant instance
- * @param address physical address of the merchant instance
- * @param jurisdiction jurisdiction of the merchant instance
- * @param default_max_wire_fee default maximum wire fee merchant is willing to 
fully pay
- * @param default_wire_fee_amortization default amortization factor for excess 
wire fees
- * @param default_max_deposit_fee default maximum deposit fee merchant is 
willing to pay
- * @param default_wire_transfer_delay default wire transfer delay merchant 
will ask for
- * @param default_pay_delay default validity period for offers merchant makes
+ * @param details details about the instance configuration
  */
 typedef void
 (*TALER_MERCHANT_InstanceGetCallback)(
@@ -528,15 +572,7 @@ typedef void
   const struct TALER_MERCHANT_HttpResponse *hr,
   unsigned int accounts_length,
   const struct TALER_MERCHANT_Account accounts[],
-  const char *name,
-  const struct TALER_MerchantPublicKeyP *merchant_pub,
-  const json_t *address,
-  const json_t *jurisdiction,
-  const struct TALER_Amount *default_max_wire_fee,
-  uint32_t default_wire_fee_amortization,
-  const struct TALER_Amount *default_max_deposit_fee,
-  struct GNUNET_TIME_Relative default_wire_transfer_delay,
-  struct GNUNET_TIME_Relative default_pay_delay);
+  const struct TALER_MERCHANT_InstanceDetails *details);
 
 
 /**
@@ -555,6 +591,7 @@ typedef void
 struct TALER_MERCHANT_InstanceGetHandle *
 TALER_MERCHANT_instance_get (struct GNUNET_CURL_Context *ctx,
                              const char *backend_url,
+                             const char *instance_id,
                              TALER_MERCHANT_InstanceGetCallback cb,
                              void *cb_cls);
 
@@ -589,7 +626,7 @@ typedef void
 
 
 /**
- * Get the private key of an instance of a backend, thereby disabling the
+ * Delete the private key of an instance of a backend, thereby disabling the
  * instance for future requests.  Will preserve the other instance data
  * (i.e. for taxation).
  *
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index c2d468e..0b76f53 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -20,9 +20,11 @@ libtalermerchanttesting_la_LDFLAGS = \
 
 libtalermerchant_la_SOURCES = \
   merchant_api_common.c \
-  merchant_api_delete_instances_ID.c \
+  merchant_api_delete_instance.c \
   merchant_api_get_config.c \
+  merchant_api_get_instance.c \
   merchant_api_get_instances.c \
+  merchant_api_post_instances.c \
   merchant_api_check_payment.c \
   merchant_api_history.c \
   merchant_api_proposal.c \
diff --git a/src/lib/merchant_api_delete_instances_ID.c 
b/src/lib/merchant_api_delete_instance.c
similarity index 50%
rename from src/lib/merchant_api_delete_instances_ID.c
rename to src/lib/merchant_api_delete_instance.c
index 0eeb50b..06c1d41 100644
--- a/src/lib/merchant_api_delete_instances_ID.c
+++ b/src/lib/merchant_api_delete_instance.c
@@ -15,8 +15,8 @@
   <http://www.gnu.org/licenses/>
 */
 /**
- * @file lib/merchant_api_delete_instances_ID.c
- * @brief Implementation of the GET /instances request of the merchant's HTTP 
API
+ * @file lib/merchant_api_delete_instance.c
+ * @brief Implementation of the DELETE /instance/$ID request of the merchant's 
HTTP API
  * @author Christian Grothoff
  */
 #include "platform.h"
@@ -65,14 +65,14 @@ struct TALER_MERCHANT_InstanceDeleteHandle
 
 /**
  * Function called when we're done processing the
- * HTTP DELETE /instances/$ID request.
+ * HTTP GET /instances/$ID request.
  *
- * @param cls the `struct TALER_MERCHANT_InstancesDeleteHandle`
+ * @param cls the `struct TALER_MERCHANT_InstanceDeleteHandle`
  * @param response_code HTTP response code, 0 on error
  * @param json response body, NULL if not in JSON
  */
 static void
-handle_instance_delete_finished (void *cls,
+handle_delete_instance_finished (void *cls,
                                  long response_code,
                                  const void *response)
 {
@@ -85,15 +85,11 @@ handle_instance_delete_finished (void *cls,
 
   idh->job = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Got /instances response with status code %u\n",
+              "Got /instances/$ID response with status code %u\n",
               (unsigned int) response_code);
   switch (response_code)
   {
-  case MHD_HTTP_OK:
-    break;
-  case MHD_HTTP_NOT_FOUND:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+  case MHD_HTTP_NO_CONTENT:
     break;
   default:
     /* unexpected response code */
@@ -112,8 +108,9 @@ handle_instance_delete_finished (void *cls,
 
 
 /**
- * Purge all data associated with an instance. Use with
- * extreme caution.
+ * Delete the private key of an instance of a backend, thereby disabling the
+ * instance for future requests.  Will preserve the other instance data
+ * (i.e. for taxation).
  *
  * @param ctx the context
  * @param backend_url HTTP base URL for the backend
@@ -123,38 +120,28 @@ handle_instance_delete_finished (void *cls,
  * @param instances_cb_cls closure for @a config_cb
  * @return the instances handle; NULL upon error
  */
-static struct TALER_MERCHANT_InstanceDeleteHandle *
-instance_delete (
-  struct GNUNET_CURL_Context *ctx,
-  const char *backend_url,
-  const char *instance_id,
-  bool purge,
-  TALER_MERCHANT_InstanceDeleteCallback instances_cb,
-  void *instances_cb_cls)
+struct TALER_MERCHANT_InstanceDeleteHandle *
+TALER_MERCHANT_instance_delete (struct GNUNET_CURL_Context *ctx,
+                                const char *backend_url,
+                                const char *instance_id,
+                                TALER_MERCHANT_InstanceDeleteCallback cb,
+                                void *cb_cls)
 {
   struct TALER_MERCHANT_InstanceDeleteHandle *idh;
-  CURL *eh;
 
   idh = GNUNET_new (struct TALER_MERCHANT_InstanceDeleteHandle);
   idh->ctx = ctx;
-  idh->cb = instances_cb;
-  idh->cb_cls = instances_cb_cls;
+  idh->cb = cb;
+  idh->cb_cls = cb_cls;
   {
     char *path;
 
     GNUNET_asprintf (&path,
                      "instances/%s",
                      instance_id);
-    if (purge)
-      idh->url = TALER_url_join (backend_url,
-                                 path,
-                                 "purge",
-                                 "true",
-                                 NULL);
-    else
-      idh->url = TALER_url_join (backend_url,
-                                 path,
-                                 NULL);
+    idh->url = TALER_url_join (backend_url,
+                               path,
+                               NULL);
     GNUNET_free (path);
   }
   if (NULL == idh->url)
@@ -167,85 +154,27 @@ instance_delete (
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Requesting URL '%s'\n",
               idh->url);
-  eh = curl_easy_init ();
-  GNUNET_assert (CURLE_OK ==
-                 curl_easy_setopt (eh,
-                                   CURLOPT_URL,
-                                   idh->url));
-  GNUNET_assert (CURLE_OK ==
-                 curl_easy_setopt (eh,
-                                   CURLOPT_CUSTOMREQUEST,
-                                   MHD_HTTP_METHOD_DELETE));
-  idh->job = GNUNET_CURL_job_add (ctx,
-                                  eh,
-                                  GNUNET_YES,
-                                  &handle_instance_delete_finished,
-                                  idh);
+  {
+    CURL *eh;
+
+    eh = curl_easy_init ();
+    GNUNET_assert (CURLE_OK ==
+                   curl_easy_setopt (eh,
+                                     CURLOPT_URL,
+                                     idh->url));
+    idh->job = GNUNET_CURL_job_add (ctx,
+                                    eh,
+                                    GNUNET_YES,
+                                    &handle_delete_instance_finished,
+                                    idh);
+  }
   return idh;
 }
 
 
 /**
- * Purge all data associated with an instance. Use with
- * extreme caution.
- *
- * @param ctx the context
- * @param backend_url HTTP base URL for the backend
- * @param instance_id which instance should be deleted
- * @param instances_cb function to call with the
- *        backend's return
- * @param instances_cb_cls closure for @a config_cb
- * @return the instances handle; NULL upon error
- */
-struct TALER_MERCHANT_InstanceDeleteHandle *
-TALER_MERCHANT_instance_delete (
-  struct GNUNET_CURL_Context *ctx,
-  const char *backend_url,
-  const char *instance_id,
-  TALER_MERCHANT_InstanceDeleteCallback instances_cb,
-  void *instances_cb_cls)
-{
-  return instance_delete (ctx,
-                          backend_url,
-                          instance_id,
-                          false,
-                          instances_cb,
-                          instances_cb_cls);
-}
-
-
-/**
- * Purge all data associated with an instance. Use with
- * extreme caution.
- *
- * @param ctx the context
- * @param backend_url HTTP base URL for the backend
- * @param instance_id which instance should be deleted
- * @param instances_cb function to call with the
- *        backend's return
- * @param instances_cb_cls closure for @a config_cb
- * @return the instances handle; NULL upon error
- */
-struct TALER_MERCHANT_InstanceDeleteHandle *
-TALER_MERCHANT_instance_purge (
-  struct GNUNET_CURL_Context *ctx,
-  const char *backend_url,
-  const char *instance_id,
-  TALER_MERCHANT_InstanceDeleteCallback instances_cb,
-  void *instances_cb_cls)
-{
-  return instance_delete (ctx,
-                          backend_url,
-                          instance_id,
-                          true,
-                          instances_cb,
-                          instances_cb_cls);
-}
-
-
-/**
- * Cancel /instances DELETE request.  Must not be called by clients after the
- * callback was invoked.
+ * Cancel DELETE /instance/$ID request.  Must not be called by clients after
+ * the callback was invoked.
  *
  * @param idh request to cancel.
  */
diff --git a/src/lib/merchant_api_get_instance.c 
b/src/lib/merchant_api_get_instance.c
new file mode 100644
index 0000000..6499a6e
--- /dev/null
+++ b/src/lib/merchant_api_get_instance.c
@@ -0,0 +1,292 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2018, 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_instance.c
+ * @brief Implementation of the GET /instance/$ID request of the merchant's 
HTTP API
+ * @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>
+
+
+/**
+ * Handle for a GET /instances/$ID operation.
+ */
+struct TALER_MERCHANT_InstanceGetHandle
+{
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_MERCHANT_InstanceGetCallback 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 /instances/$ID request.
+ *
+ * @param cls the `struct TALER_MERCHANT_InstanceGetHandle`
+ * @param response_code HTTP response code, 0 on error
+ * @param json response body, NULL if not in JSON
+ */
+static void
+handle_get_instance_finished (void *cls,
+                              long response_code,
+                              const void *response)
+{
+  struct TALER_MERCHANT_InstanceGetHandle *igh = cls;
+  const json_t *json = response;
+  struct TALER_MERCHANT_HttpResponse hr = {
+    .http_status = (unsigned int) response_code,
+    .reply = json
+  };
+
+  igh->job = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Got /instances/$ID response with status code %u\n",
+              (unsigned int) response_code);
+  switch (response_code)
+  {
+  case MHD_HTTP_OK:
+    {
+      json_t *accounts;
+      const char *name;
+      struct TALER_MerchantPublicKeyP merchant_pub;
+      json_t *address;
+      json_t *jurisdiction;
+      struct TALER_Amount default_max_wire_fee;
+      uint32_t default_wire_fee_amortization;
+      struct TALER_Amount default_max_deposit_fee;
+      struct GNUNET_TIME_Relative default_wire_transfer_delay;
+      struct GNUNET_TIME_Relative default_pay_delay;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_json ("accounts",
+                               &accounts),
+        GNUNET_JSON_spec_string ("name",
+                                 &name),
+        GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+                                     &merchant_pub),
+        GNUNET_JSON_spec_json ("address",
+                               &address),
+        GNUNET_JSON_spec_json ("jurisdiction",
+                               &jurisdiction),
+        TALER_JSON_spec_amount ("default_max_wire_fee",
+                                &default_max_wire_fee),
+        GNUNET_JSON_spec_uint32 ("default_wire_fee_amortization",
+                                 &default_wire_fee_amortization),
+        TALER_JSON_spec_amount ("default_max_deposit_fee",
+                                &default_max_deposit_fee),
+        GNUNET_JSON_spec_relative_time ("default_wire_transfer_delay",
+                                        &default_wire_transfer_delay),
+        GNUNET_JSON_spec_relative_time ("default_pay_delay",
+                                        &default_pay_delay),
+        GNUNET_JSON_spec_end ()
+      };
+
+      if ( (GNUNET_OK ==
+            GNUNET_JSON_parse (json,
+                               spec,
+                               NULL, NULL)) &&
+           (json_is_array (accounts)) )
+      {
+        unsigned int accounts_length = json_array_size (accounts);
+        struct TALER_MERCHANT_Account aa[accounts_length];
+        const char *payto_uris[accounts_length];
+        size_t index;
+        json_t *value;
+        int ret = GNUNET_OK;
+
+        memset (payto_uris, 0, sizeof (payto_uris));
+        json_array_foreach (accounts, index, value)
+        {
+          struct GNUNET_JSON_Specification spec[] = {
+            GNUNET_JSON_spec_fixed_auto ("salt",
+                                         &aa[index].salt),
+            GNUNET_JSON_spec_string ("payto_uri",
+                                     &payto_uris[index]),
+            GNUNET_JSON_spec_fixed_auto ("h_wire",
+                                         &aa[index].h_wire),
+            GNUNET_JSON_spec_bool ("active",
+                                   &aa[index].active),
+            GNUNET_JSON_spec_end ()
+          };
+
+          if (GNUNET_OK !=
+              GNUNET_JSON_parse (value,
+                                 spec,
+                                 NULL, NULL))
+          {
+            GNUNET_break_op (0);
+            ret = GNUNET_SYSERR;
+            break;
+          }
+          aa[index].payto_uri = payto_uris[index];
+        }
+
+        if (GNUNET_OK == ret)
+        {
+          struct TALER_MERCHANT_InstanceDetails details = {
+            .name = name,
+            .merchant_pub = &merchant_pub,
+            .address = address,
+            .jurisdiction = jurisdiction,
+            .default_max_wire_fee = &default_max_wire_fee,
+            .default_wire_fee_amortization = default_wire_fee_amortization,
+            .default_max_deposit_fee = &default_max_deposit_fee,
+            .default_wire_transfer_delay = default_wire_transfer_delay,
+            .default_pay_delay = default_pay_delay
+          };
+
+          igh->cb (igh->cb_cls,
+                   &hr,
+                   accounts_length,
+                   aa,
+                   &details);
+          GNUNET_JSON_parse_free (spec);
+          TALER_MERCHANT_instance_get_cancel (igh);
+          return;
+        }
+      }
+      hr.http_status = 0;
+      hr.ec = TALER_EC_INVALID_RESPONSE;
+      GNUNET_JSON_parse_free (spec);
+      break;
+    }
+  default:
+    /* unexpected response code */
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d\n",
+                (unsigned int) response_code,
+                (int) hr.ec);
+    break;
+  }
+  igh->cb (igh->cb_cls,
+           &hr,
+           0,
+           NULL,
+           NULL);
+  TALER_MERCHANT_instance_get_cancel (igh);
+}
+
+
+/**
+ * Get the instance data of a backend. Will connect to the merchant backend
+ * and obtain information about the instances.  The respective information will
+ * be passed to the @a cb once available.
+ *
+ * @param ctx the context
+ * @param backend_url HTTP base URL for the backend
+ * @param instance_id identity of the instance to get information about
+ * @param cb function to call with the
+ *        backend's instances information
+ * @param cb_cls closure for @a cb
+ * @return the instances handle; NULL upon error
+ */
+struct TALER_MERCHANT_InstanceGetHandle *
+TALER_MERCHANT_instance_get (struct GNUNET_CURL_Context *ctx,
+                             const char *backend_url,
+                             const char *instance_id,
+                             TALER_MERCHANT_InstanceGetCallback cb,
+                             void *cb_cls)
+{
+  struct TALER_MERCHANT_InstanceGetHandle *igh;
+  CURL *eh;
+
+  igh = GNUNET_new (struct TALER_MERCHANT_InstanceGetHandle);
+  igh->ctx = ctx;
+  igh->cb = cb;
+  igh->cb_cls = cb_cls;
+  {
+    char *path;
+
+    GNUNET_asprintf (&path,
+                     "instances/%s",
+                     instance_id);
+    igh->url = TALER_url_join (backend_url,
+                               path,
+                               NULL);
+    GNUNET_free (path);
+  }
+  if (NULL == igh->url)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not construct request URL.\n");
+    GNUNET_free (igh);
+    return NULL;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Requesting URL '%s'\n",
+              igh->url);
+  eh = curl_easy_init ();
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_URL,
+                                   igh->url));
+  igh->job = GNUNET_CURL_job_add (ctx,
+                                  eh,
+                                  GNUNET_YES,
+                                  &handle_get_instance_finished,
+                                  igh);
+  return igh;
+}
+
+
+/**
+ * Cancel GET /instance/$ID request.  Must not be called by clients after
+ * the callback was invoked.
+ *
+ * @param igh request to cancel.
+ */
+void
+TALER_MERCHANT_instance_get_cancel (
+  struct TALER_MERCHANT_InstanceGetHandle *igh)
+{
+  if (NULL != igh->job)
+    GNUNET_CURL_job_cancel (igh->job);
+  GNUNET_free (igh->url);
+  GNUNET_free (igh);
+}
diff --git a/src/lib/merchant_api_post_instances.c 
b/src/lib/merchant_api_post_instances.c
new file mode 100644
index 0000000..153a984
--- /dev/null
+++ b/src/lib/merchant_api_post_instances.c
@@ -0,0 +1,307 @@
+/*
+  This file is part of TALER
+  Copyright (C) 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_post_instances.c
+ * @brief Implementation of the POST /instances request
+ *        of the merchant's HTTP API
+ * @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 "taler_merchant_service.h"
+#include <taler/taler_json_lib.h>
+#include <taler/taler_curl_lib.h>
+
+
+/**
+ * Handle for a POST /instances/$ID operation.
+ */
+struct TALER_MERCHANT_InstancesPostHandle
+{
+
+  /**
+   * The url for this request.
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  TALER_MERCHANT_InstancesPostCallback cb;
+
+  /**
+   * Closure for @a cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+
+  /**
+   * Minor context that holds body and headers.
+   */
+  struct TALER_CURL_PostContext post_ctx;
+
+};
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP POST /instances request.
+ *
+ * @param cls the `struct TALER_MERCHANT_Pay`
+ * @param response_code HTTP response code, 0 on error
+ * @param json response body, NULL if not in JSON
+ */
+static void
+handle_post_instances_finished (void *cls,
+                                long response_code,
+                                const void *response)
+{
+  struct TALER_MERCHANT_InstancesPostHandle *iph = cls;
+  const json_t *json = response;
+  struct TALER_MERCHANT_HttpResponse hr = {
+    .http_status = (unsigned int) response_code,
+    .reply = json
+  };
+
+  iph->job = NULL;
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "POST /instances completed with response code %u\n",
+              (unsigned int) response_code);
+  switch (response_code)
+  {
+  case 0:
+    hr.ec = TALER_EC_INVALID_RESPONSE;
+    break;
+  case MHD_HTTP_NO_CONTENT:
+    break;
+  case MHD_HTTP_BAD_REQUEST:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    /* This should never happen, either us
+     * or the merchant is buggy (or API version conflict);
+     * just pass JSON reply to the application */
+    break;
+  case MHD_HTTP_FORBIDDEN:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    /* Nothing really to verify, merchant says we tried to abort the payment
+     * after it was successful. We should pass the JSON reply to the
+     * application */
+    break;
+  case MHD_HTTP_NOT_FOUND:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    /* Nothing really to verify, this should never
+       happen, we should pass the JSON reply to the
+       application */
+    break;
+  case MHD_HTTP_CONFLICT:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    break;
+  case MHD_HTTP_INTERNAL_SERVER_ERROR:
+    hr.ec = TALER_JSON_get_error_code (json);
+    hr.hint = TALER_JSON_get_error_hint (json);
+    /* Server had an internal issue; we should retry,
+       but this API leaves this to the application */
+    break;
+  default:
+    TALER_MERCHANT_parse_error_details_ (json,
+                                         response_code,
+                                         &hr);
+    /* unexpected response code */
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u/%d\n",
+                (unsigned int) response_code,
+                (int) hr.ec);
+    GNUNET_break_op (0);
+    break;
+  }
+  iph->cb (iph->cb_cls,
+           &hr);
+  TALER_MERCHANT_instances_post_cancel (iph);
+}
+
+
+/**
+ * Setup an new instance in the backend.
+ *
+ * @param ctx the context
+ * @param backend_url HTTP base URL for the backend
+ * @param instance_id identity of the instance to get information about
+ * @param payto_uris_length length of the @a accounts array
+ * @param payto_uris URIs of the bank accounts of the merchant instance
+ * @param name name of the merchant instance
+ * @param address physical address of the merchant instance
+ * @param jurisdiction jurisdiction of the merchant instance
+ * @param default_max_wire_fee default maximum wire fee merchant is willing to 
fully pay
+ * @param default_wire_fee_amortization default amortization factor for excess 
wire fees
+ * @param default_max_deposit_fee default maximum deposit fee merchant is 
willing to pay
+ * @param default_wire_transfer_delay default wire transfer delay merchant 
will ask for
+ * @param default_pay_delay default validity period for offers merchant makes
+ * @param cb function to call with the
+ *        backend's instances information
+ * @param cb_cls closure for @a config_cb
+ * @return the instances handle; NULL upon error
+ */
+struct TALER_MERCHANT_InstancesPostHandle *
+TALER_MERCHANT_instances_post (
+  struct GNUNET_CURL_Context *ctx,
+  const char *backend_url,
+  const char *instance_id,
+  unsigned int accounts_length,
+  const char *payto_uris[],
+  const char *name,
+  const json_t *address,
+  const json_t *jurisdiction,
+  const struct TALER_Amount *default_max_wire_fee,
+  uint32_t default_wire_fee_amortization,
+  const struct TALER_Amount *default_max_deposit_fee,
+  struct GNUNET_TIME_Relative default_wire_transfer_delay,
+  struct GNUNET_TIME_Relative default_pay_delay,
+  TALER_MERCHANT_InstancesPostCallback cb,
+  void *cb_cls)
+{
+  struct TALER_MERCHANT_InstancesPostHandle *iph;
+  json_t *jpayto_uris;
+  json_t *req_obj;
+
+  jpayto_uris = json_array ();
+  if (NULL == jpayto_uris)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  for (unsigned int i = 0; i<accounts_length; i++)
+  {
+    if (0 !=
+        json_array_append_new (jpayto_uris,
+                               json_string (payto_uris[i])))
+    {
+      GNUNET_break (0);
+      json_decref (jpayto_uris);
+      return NULL;
+    }
+  }
+  req_obj = json_pack ("{s:o, s:s, s:s, s:O, s:O"
+                       " s:o, s:I: s:o, s:o, s:o}",
+                       "payto_uris",
+                       jpayto_uris,
+                       "id",
+                       instance_id,
+                       "name",
+                       name,
+                       "address",
+                       address,
+                       "jurisdiction",
+                       jurisdiction,
+                       /* end of group of 5 */
+                       "default_max_wire_fee",
+                       TALER_JSON_from_amount (default_max_wire_fee),
+                       "default_wire_fee_amortization",
+                       (json_int_t) default_wire_fee_amortization,
+                       "default_max_deposit_fee",
+                       TALER_JSON_from_amount (default_max_deposit_fee),
+                       "default_wire_transfer_delay",
+                       GNUNET_JSON_from_time_rel (default_wire_transfer_delay),
+                       "default_pay_delay",
+                       GNUNET_JSON_from_time_rel (default_pay_delay));
+  if (NULL == req_obj)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  iph = GNUNET_new (struct TALER_MERCHANT_InstancesPostHandle);
+  iph->ctx = ctx;
+  iph->cb = cb;
+  iph->cb_cls = cb_cls;
+  iph->url = TALER_url_join (backend_url,
+                             "/instances",
+                             NULL);
+  if (NULL == iph->url)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Could not construct request URL.\n");
+    json_decref (req_obj);
+    GNUNET_free (iph);
+    return NULL;
+  }
+  {
+    CURL *eh;
+
+    eh = curl_easy_init ();
+    if (GNUNET_OK !=
+        TALER_curl_easy_post (&iph->post_ctx,
+                              eh,
+                              req_obj))
+    {
+      GNUNET_break (0);
+      json_decref (req_obj);
+      GNUNET_free (iph);
+      return NULL;
+    }
+
+    json_decref (req_obj);
+    GNUNET_assert (CURLE_OK == curl_easy_setopt (eh,
+                                                 CURLOPT_URL,
+                                                 iph->url));
+    iph->job = GNUNET_CURL_job_add2 (ctx,
+                                     eh,
+                                     iph->post_ctx.headers,
+                                     &handle_post_instances_finished,
+                                     iph);
+  }
+  return iph;
+}
+
+
+/**
+ * Cancel /instances request.  Must not be called by clients after
+ * the callback was invoked.
+ *
+ * @param igh request to cancel.
+ */
+void
+TALER_MERCHANT_instances_post_cancel (
+  struct TALER_MERCHANT_InstancesPostHandle *iph)
+{
+  if (NULL != iph->job)
+  {
+    GNUNET_CURL_job_cancel (iph->job);
+    iph->job = NULL;
+  }
+  TALER_curl_easy_post_finished (&iph->post_ctx);
+  GNUNET_free (iph->url);
+  GNUNET_free (iph);
+}
+
+
+/* end of merchant_api_post_instances.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]