merchant

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

taler-merchant-httpd_private-get-statistics-counter-SLUG.c (6874B)


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