merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

taler-merchant-httpd_get-private-statistics-counter-SLUG.c (7025B)


      1 /*
      2   This file is part of TALER
      3   (C) 2023, 2024, 2025 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 General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file src/backend/taler-merchant-httpd_get-private-statistics-counter-SLUG.c
     18  * @brief implement GET /statistics-counter/$SLUG/
     19  * @author Martin Schanzenbach
     20  */
     21 #include "platform.h"
     22 #include "taler-merchant-httpd_get-private-statistics-counter-SLUG.h"
     23 #include <gnunet/gnunet_json_lib.h>
     24 #include <taler/taler_json_lib.h>
     25 #include "merchant-database/lookup_statistics_counter_by_bucket.h"
     26 #include "merchant-database/lookup_statistics_counter_by_interval.h"
     27 
     28 
     29 /**
     30  * Function returning integer-valued statistics.
     31  * Typically called by `lookup_statistics_counter_by_bucket`.
     32  *
     33  * @param cls a `json_t *` JSON array to build
     34  * @param description description of the statistic
     35  * @param bucket_start start time of the bucket
     36  * @param bucket_end end time of the bucket
     37  * @param bucket_range range of the bucket
     38  * @param cumulative_number counter value
     39  */
     40 static void
     41 counter_by_bucket (void *cls,
     42                    const char *description,
     43                    struct GNUNET_TIME_Timestamp bucket_start,
     44                    struct GNUNET_TIME_Timestamp bucket_end,
     45                    const char *bucket_range,
     46                    uint64_t cumulative_number)
     47 {
     48   json_t *root = cls;
     49   json_t *buckets_array;
     50 
     51   GNUNET_assert (json_is_object (root));
     52   buckets_array = json_object_get (root,
     53                                    "buckets");
     54   GNUNET_assert (NULL != buckets_array);
     55   GNUNET_assert (json_is_array (buckets_array));
     56   GNUNET_assert (
     57     0 ==
     58     json_array_append_new (
     59       buckets_array,
     60       GNUNET_JSON_PACK (
     61         GNUNET_JSON_pack_timestamp (
     62           "start_time",
     63           bucket_start),
     64         GNUNET_JSON_pack_timestamp (
     65           "end_time",
     66           bucket_end),
     67         GNUNET_JSON_pack_string (
     68           "range",
     69           bucket_range),
     70         GNUNET_JSON_pack_uint64 (
     71           "cumulative_counter",
     72           cumulative_number))));
     73   if (NULL == json_object_get (root,
     74                                "buckets_description"))
     75   {
     76     GNUNET_assert (
     77       0 ==
     78       json_object_set_new (root,
     79                            "buckets_description",
     80                            json_string (description)));
     81   }
     82 }
     83 
     84 
     85 /**
     86  * Function returning integer-valued statistics for a time interval.
     87  * Called by `lookup_statistics_counter_by_interval`.
     88  *
     89  * @param cls a `json_t *` JSON array to build
     90  * @param description description of the statistic
     91  * @param bucket_start start time of the interval
     92  * @param cumulative_number counter value
     93  */
     94 static void
     95 counter_by_interval (void *cls,
     96                      const char *description,
     97                      struct GNUNET_TIME_Timestamp bucket_start,
     98                      uint64_t cumulative_number)
     99 {
    100   json_t *root = cls;
    101   json_t *intervals_array;
    102 
    103   GNUNET_assert (json_is_object (root));
    104   intervals_array = json_object_get (root,
    105                                      "intervals");
    106   GNUNET_assert (NULL != intervals_array);
    107   GNUNET_assert (json_is_array (intervals_array));
    108   GNUNET_assert (
    109     0 ==
    110     json_array_append_new (
    111       intervals_array,
    112       GNUNET_JSON_PACK (
    113         GNUNET_JSON_pack_timestamp (
    114           "start_time",
    115           bucket_start),
    116         GNUNET_JSON_pack_uint64 (
    117           "cumulative_counter",
    118           cumulative_number))));
    119   if (NULL == json_object_get (root,
    120                                "intervals_description"))
    121   {
    122     GNUNET_assert (
    123       0 ==
    124       json_object_set_new (root,
    125                            "intervals_description",
    126                            json_string (description)));
    127   }
    128 }
    129 
    130 
    131 /**
    132  * Handle a GET "/statistics-counter/$SLUG" request.
    133  *
    134  * @param rh context of the handler
    135  * @param connection the MHD connection to handle
    136  * @param[in,out] hc context with further information about the request
    137  * @return MHD result code
    138  */
    139 enum MHD_Result
    140 TMH_private_get_statistics_counter_SLUG (const struct TMH_RequestHandler *rh,
    141                                          struct MHD_Connection *connection,
    142                                          struct TMH_HandlerContext *hc)
    143 {
    144   struct TMH_MerchantInstance *mi = hc->instance;
    145   json_t *root;
    146   bool get_buckets = true;
    147   bool get_intervals = true;
    148 
    149   GNUNET_assert (NULL != mi);
    150   {
    151     const char *filter;
    152 
    153     filter = MHD_lookup_connection_value (connection,
    154                                           MHD_GET_ARGUMENT_KIND,
    155                                           "by");
    156     if (NULL != filter)
    157     {
    158       if (0 == strcasecmp (filter,
    159                            "bucket"))
    160         get_intervals = false;
    161       else if (0 == strcasecmp (filter,
    162                                 "interval"))
    163         get_buckets = false;
    164       else if (0 != strcasecmp (filter,
    165                                 "any"))
    166       {
    167         GNUNET_break_op (0);
    168         return TALER_MHD_reply_with_error (
    169           connection,
    170           MHD_HTTP_BAD_REQUEST,
    171           TALER_EC_GENERIC_PARAMETER_MALFORMED,
    172           "by");
    173       }
    174     }
    175   }
    176   root = GNUNET_JSON_PACK (
    177     GNUNET_JSON_pack_array_steal ("intervals",
    178                                   json_array ()),
    179     GNUNET_JSON_pack_array_steal ("buckets",
    180                                   json_array ()));
    181   if (get_buckets)
    182   {
    183     enum GNUNET_DB_QueryStatus qs;
    184 
    185     qs = TALER_MERCHANTDB_lookup_statistics_counter_by_bucket (
    186       TMH_db,
    187       mi->settings.id,
    188       hc->infix,
    189       &counter_by_bucket,
    190       root);
    191     if (0 > qs)
    192     {
    193       GNUNET_break (0);
    194       json_decref (root);
    195       return TALER_MHD_reply_with_error (
    196         connection,
    197         MHD_HTTP_INTERNAL_SERVER_ERROR,
    198         TALER_EC_GENERIC_DB_FETCH_FAILED,
    199         "lookup_statistics_counter_by_bucket");
    200     }
    201   }
    202   if (get_intervals)
    203   {
    204     enum GNUNET_DB_QueryStatus qs;
    205 
    206     qs = TALER_MERCHANTDB_lookup_statistics_counter_by_interval (
    207       TMH_db,
    208       mi->settings.id,
    209       hc->infix,
    210       &counter_by_interval,
    211       root);
    212     if (0 > qs)
    213     {
    214       GNUNET_break (0);
    215       json_decref (root);
    216       return TALER_MHD_reply_with_error (
    217         connection,
    218         MHD_HTTP_INTERNAL_SERVER_ERROR,
    219         TALER_EC_GENERIC_DB_FETCH_FAILED,
    220         "lookup_statistics_counter_by_interval");
    221     }
    222   }
    223   return TALER_MHD_reply_json (connection,
    224                                root,
    225                                MHD_HTTP_OK);
    226 }
    227 
    228 
    229 /* end of taler-merchant-httpd_get-private-statistics-counter-SLUG.c */