Line data Source code
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/iterate_statistic_bucket_counters.h"
26 : #include "merchant-database/iterate_statistic_interval_counters.h"
27 :
28 :
29 : /**
30 : * Function returning integer-valued statistics.
31 : * Typically called by `iterate_statistic_bucket_counters`.
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 24 : 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 24 : json_t *root = cls;
49 : json_t *buckets_array;
50 :
51 24 : GNUNET_assert (json_is_object (root));
52 24 : buckets_array = json_object_get (root,
53 : "buckets");
54 24 : GNUNET_assert (NULL != buckets_array);
55 24 : GNUNET_assert (json_is_array (buckets_array));
56 24 : 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 24 : if (NULL == json_object_get (root,
74 : "buckets_description"))
75 : {
76 4 : GNUNET_assert (
77 : 0 ==
78 : json_object_set_new (root,
79 : "buckets_description",
80 : json_string (description)));
81 : }
82 24 : }
83 :
84 :
85 : /**
86 : * Function returning integer-valued statistics for a time interval.
87 : * Called by `iterate_statistic_interval_counters`.
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 6 : counter_by_interval (void *cls,
96 : const char *description,
97 : struct GNUNET_TIME_Timestamp bucket_start,
98 : uint64_t cumulative_number)
99 : {
100 6 : json_t *root = cls;
101 : json_t *intervals_array;
102 :
103 6 : GNUNET_assert (json_is_object (root));
104 6 : intervals_array = json_object_get (root,
105 : "intervals");
106 6 : GNUNET_assert (NULL != intervals_array);
107 6 : GNUNET_assert (json_is_array (intervals_array));
108 6 : 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 6 : if (NULL == json_object_get (root,
120 : "intervals_description"))
121 : {
122 4 : GNUNET_assert (
123 : 0 ==
124 : json_object_set_new (root,
125 : "intervals_description",
126 : json_string (description)));
127 : }
128 6 : }
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 4 : TMH_private_get_statistics_counter_SLUG (const struct TMH_RequestHandler *rh,
141 : struct MHD_Connection *connection,
142 : struct TMH_HandlerContext *hc)
143 : {
144 4 : struct TMH_MerchantInstance *mi = hc->instance;
145 : json_t *root;
146 4 : bool get_buckets = true;
147 4 : bool get_intervals = true;
148 :
149 4 : GNUNET_assert (NULL != mi);
150 : {
151 : const char *filter;
152 :
153 4 : filter = MHD_lookup_connection_value (connection,
154 : MHD_GET_ARGUMENT_KIND,
155 : "by");
156 4 : if (NULL != filter)
157 : {
158 0 : if (0 == strcasecmp (filter,
159 : "bucket"))
160 0 : get_intervals = false;
161 0 : else if (0 == strcasecmp (filter,
162 : "interval"))
163 0 : get_buckets = false;
164 0 : else if (0 != strcasecmp (filter,
165 : "any"))
166 : {
167 0 : GNUNET_break_op (0);
168 0 : 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 4 : 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 4 : if (get_buckets)
182 : {
183 : enum GNUNET_DB_QueryStatus qs;
184 :
185 4 : qs = TALER_MERCHANTDB_iterate_statistic_bucket_counters (
186 : TMH_db,
187 4 : mi->settings.id,
188 4 : hc->infix,
189 : &counter_by_bucket,
190 : root);
191 4 : if (0 > qs)
192 : {
193 0 : GNUNET_break (0);
194 0 : json_decref (root);
195 0 : return TALER_MHD_reply_with_error (
196 : connection,
197 : MHD_HTTP_INTERNAL_SERVER_ERROR,
198 : TALER_EC_GENERIC_DB_FETCH_FAILED,
199 : "iterate_statistic_bucket_counters");
200 : }
201 : }
202 4 : if (get_intervals)
203 : {
204 : enum GNUNET_DB_QueryStatus qs;
205 :
206 4 : qs = TALER_MERCHANTDB_iterate_statistic_interval_counters (
207 : TMH_db,
208 4 : mi->settings.id,
209 4 : hc->infix,
210 : &counter_by_interval,
211 : root);
212 4 : if (0 > qs)
213 : {
214 0 : GNUNET_break (0);
215 0 : json_decref (root);
216 0 : return TALER_MHD_reply_with_error (
217 : connection,
218 : MHD_HTTP_INTERNAL_SERVER_ERROR,
219 : TALER_EC_GENERIC_DB_FETCH_FAILED,
220 : "iterate_statistic_interval_counters");
221 : }
222 : }
223 4 : 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 */
|