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 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_counter counter value
37 : */
38 : static void
39 24 : 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 24 : json_t *root = cls;
47 : json_t *buckets_array;
48 :
49 24 : GNUNET_assert (json_is_object (root));
50 24 : buckets_array = json_object_get (root,
51 : "buckets");
52 24 : GNUNET_assert (NULL != buckets_array);
53 24 : GNUNET_assert (json_is_array (buckets_array));
54 24 : 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 24 : if (NULL == json_object_get (root,
72 : "buckets_description"))
73 : {
74 4 : GNUNET_assert (
75 : 0 ==
76 : json_object_set_new (root,
77 : "buckets_description",
78 : json_string (description)));
79 : }
80 24 : }
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 interval_start start time of the interval
90 : * @param cumulative_counter counter value
91 : */
92 : static void
93 0 : counter_by_interval (void *cls,
94 : const char *description,
95 : struct GNUNET_TIME_Timestamp bucket_start,
96 : uint64_t cumulative_number)
97 : {
98 0 : json_t *root = cls;
99 : json_t *intervals_array;
100 :
101 0 : GNUNET_assert (json_is_object (root));
102 0 : intervals_array = json_object_get (root,
103 : "intervals");
104 0 : GNUNET_assert (NULL != intervals_array);
105 0 : GNUNET_assert (json_is_array (intervals_array));
106 0 : 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 0 : if (NULL == json_object_get (root,
118 : "intervals_description"))
119 : {
120 0 : GNUNET_assert (
121 : 0 ==
122 : json_object_set_new (root,
123 : "intervals_description",
124 : json_string (description)));
125 : }
126 0 : }
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 4 : TMH_private_get_statistics_counter_SLUG (const struct TMH_RequestHandler *rh,
139 : struct MHD_Connection *connection,
140 : struct TMH_HandlerContext *hc)
141 : {
142 4 : struct TMH_MerchantInstance *mi = hc->instance;
143 : json_t *root;
144 4 : bool get_buckets = true;
145 4 : bool get_intervals = true;
146 :
147 4 : GNUNET_assert (NULL != mi);
148 : {
149 : const char *filter;
150 :
151 4 : filter = MHD_lookup_connection_value (connection,
152 : MHD_GET_ARGUMENT_KIND,
153 : "by");
154 4 : if (NULL != filter)
155 : {
156 0 : if (0 == strcasecmp (filter,
157 : "bucket"))
158 0 : get_intervals = false;
159 0 : else if (0 == strcasecmp (filter,
160 : "interval"))
161 0 : get_buckets = false;
162 0 : else if (0 != strcasecmp (filter,
163 : "any"))
164 : {
165 0 : GNUNET_break_op (0);
166 0 : 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 4 : 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 4 : if (get_buckets)
180 : {
181 : enum GNUNET_DB_QueryStatus qs;
182 :
183 4 : qs = TMH_db->lookup_statistics_counter_by_bucket (
184 4 : TMH_db->cls,
185 4 : mi->settings.id,
186 4 : hc->infix,
187 : &counter_by_bucket,
188 : root);
189 4 : if (0 > qs)
190 : {
191 0 : GNUNET_break (0);
192 0 : json_decref (root);
193 0 : 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 4 : if (get_intervals)
201 : {
202 : enum GNUNET_DB_QueryStatus qs;
203 :
204 4 : qs = TMH_db->lookup_statistics_counter_by_interval (
205 4 : TMH_db->cls,
206 4 : mi->settings.id,
207 4 : hc->infix,
208 : &counter_by_interval,
209 : root);
210 4 : if (0 > qs)
211 : {
212 0 : GNUNET_break (0);
213 0 : json_decref (root);
214 0 : 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 4 : 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 */
|