exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler-exchange-httpd_aml-statistics-get.c (5079B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file taler-exchange-httpd_aml-statistics-get.c
     18  * @brief Return summary information about KYC statistics
     19  * @author Christian Grothoff
     20  */
     21 #include "taler/platform.h"
     22 #include <gnunet/gnunet_util_lib.h>
     23 #include <jansson.h>
     24 #include <microhttpd.h>
     25 #include <pthread.h>
     26 #include "taler/taler_json_lib.h"
     27 #include "taler/taler_mhd_lib.h"
     28 #include "taler/taler_signatures.h"
     29 #include "taler-exchange-httpd.h"
     30 #include "taler/taler_exchangedb_plugin.h"
     31 #include "taler-exchange-httpd_aml-statistics-get.h"
     32 #include "taler-exchange-httpd_metrics.h"
     33 
     34 /**
     35  * Maximum number of statistics that can be requested in one go.
     36  */
     37 #define MAX_STATS 64
     38 
     39 
     40 /**
     41  * Function called with AML statistics (counters).
     42  *
     43  * @param cls JSON array to build
     44  * @param name name of the counter
     45  * @param cnt number of events for @a name in the query range
     46  */
     47 static void
     48 add_stat (
     49   void *cls,
     50   const char *name,
     51   uint64_t cnt)
     52 {
     53   json_t *stats = cls;
     54 
     55   GNUNET_assert (
     56     0 ==
     57     json_array_append_new (
     58       stats,
     59       GNUNET_JSON_PACK (
     60         GNUNET_JSON_pack_string ("event",
     61                                  name),
     62         GNUNET_JSON_pack_uint64 ("counter",
     63                                  cnt))));
     64 }
     65 
     66 
     67 MHD_RESULT
     68 TEH_handler_aml_kyc_statistics_get (
     69   struct TEH_RequestContext *rc,
     70   const struct TALER_AmlOfficerPublicKeyP *officer_pub,
     71   const char *const args[])
     72 {
     73   struct GNUNET_TIME_Timestamp start_date = GNUNET_TIME_UNIT_ZERO_TS;
     74   struct GNUNET_TIME_Timestamp end_date = GNUNET_TIME_UNIT_FOREVER_TS;
     75   const char *all_names = args[0];
     76   json_t *stats;
     77   size_t max_names;
     78 
     79   if ( (NULL == args[0]) ||
     80        (NULL != args[1]) )
     81   {
     82     GNUNET_break_op (0);
     83     return TALER_MHD_reply_with_error (
     84       rc->connection,
     85       MHD_HTTP_NOT_FOUND,
     86       TALER_EC_GENERIC_ENDPOINT_UNKNOWN,
     87       rc->url);
     88   }
     89   TALER_MHD_parse_request_timestamp (rc->connection,
     90                                      "start_date",
     91                                      &start_date);
     92   TALER_MHD_parse_request_timestamp (rc->connection,
     93                                      "end_date",
     94                                      &end_date);
     95   if (GNUNET_TIME_absolute_is_never (end_date.abs_time))
     96     end_date = GNUNET_TIME_absolute_to_timestamp (
     97       GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS));
     98   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     99               "Looking for stats on %s from [%llu,%llu)\n",
    100               all_names,
    101               (unsigned long long) start_date.abs_time.abs_value_us,
    102               (unsigned long long) end_date.abs_time.abs_value_us);
    103   /* Estimate number of names in 'all_names' */
    104   max_names = 1;
    105   for (size_t i = 0; '\0' != all_names[i]; i++)
    106     if (' ' == all_names[i])
    107       max_names++;
    108   if (max_names > MAX_STATS)
    109   {
    110     GNUNET_break_op (0);
    111     return TALER_MHD_reply_with_error (
    112       rc->connection,
    113       MHD_HTTP_URI_TOO_LONG,
    114       TALER_EC_GENERIC_URI_TOO_LONG,
    115       rc->url);
    116   }
    117   stats = json_array ();
    118   GNUNET_assert (NULL != stats);
    119   {
    120     char *buf;
    121     const char *names[GNUNET_NZL (max_names)];
    122     enum GNUNET_DB_QueryStatus qs;
    123     size_t num_names = 0;
    124 
    125     buf = GNUNET_strdup (all_names);
    126     for (const char *tok = strtok (buf,
    127                                    " ");
    128          NULL != tok;
    129          tok = strtok (NULL,
    130                        " "))
    131     {
    132       GNUNET_assert (num_names < max_names);
    133       names[num_names++] = tok;
    134     }
    135     qs = TEH_plugin->select_aml_statistics (
    136       TEH_plugin->cls,
    137       num_names,
    138       names,
    139       start_date,
    140       end_date,
    141       &add_stat,
    142       stats);
    143     GNUNET_free (buf);
    144     switch (qs)
    145     {
    146     case GNUNET_DB_STATUS_HARD_ERROR:
    147     case GNUNET_DB_STATUS_SOFT_ERROR:
    148       GNUNET_break (0);
    149       return TALER_MHD_reply_with_error (
    150         rc->connection,
    151         MHD_HTTP_INTERNAL_SERVER_ERROR,
    152         TALER_EC_GENERIC_DB_FETCH_FAILED,
    153         "select_aml_statistics");
    154     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    155       return TALER_MHD_reply_static (
    156         rc->connection,
    157         MHD_HTTP_NO_CONTENT,
    158         NULL,
    159         NULL,
    160         0);
    161     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    162       break;
    163     }
    164     return TALER_MHD_REPLY_JSON_PACK (
    165       rc->connection,
    166       MHD_HTTP_OK,
    167       GNUNET_JSON_pack_array_steal ("statistics",
    168                                     stats));
    169   }
    170 }
    171 
    172 
    173 /* end of taler-exchange-httpd_aml-statistics_get.c */