Implement fine-grained error replies to cloud queries (#12460)
Timotej S committed
Mar 21, 2022 at 19:23 UTC
252915d6cdca8a26f041716ffa9e19fc06885a6d
4 files changed
+38
-9
aclk/aclk_query.c
+5
-5
@@ -115,20 +115,20 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query)
115
char *node_uuid = query->data.http_api_v2.query + strlen(NODE_ID_QUERY);
116
char nodeid[UUID_STR_LEN];
117
if (strlen(node_uuid) < (UUID_STR_LEN - 1)) {
118
- error("URL requests node_id but there is not enough chars following. Returning 404 to Cloud.");
118
+ error_report(CLOUD_EMSG_MALFORMED_NODE_ID);
119
retval = 1;
120
w->response.code = 404;
121
- aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, NULL, 0);
121
+ aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, CLOUD_EC_MALFORMED_NODE_ID, CLOUD_EMSG_MALFORMED_NODE_ID, NULL, 0);
122
goto cleanup;
123
}
124
strncpyz(nodeid, node_uuid, UUID_STR_LEN - 1);
125
126
query_host = node_id_2_rrdhost(nodeid);
127
if (!query_host) {
128
- error("Host with node_id \"%s\" not found! Returning 404 to Cloud!", node_uuid);
128
+ error_report("Host with node_id \"%s\" not found! Returning 404 to Cloud!", nodeid);
129
retval = 1;
130
w->response.code = 404;
131
- aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, NULL, 0);
131
+ aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, CLOUD_EC_NODE_NOT_FOUND, CLOUD_EMSG_NODE_NOT_FOUND, NULL, 0);
132
goto cleanup;
133
}
134
}
@@ -187,7 +187,7 @@ static int http_api_v2(struct aclk_query_thread *query_thr, aclk_query_t query)
187
error("Unknown error during zlib compression.");
188
retval = 1;
189
w->response.code = 500;
190
- aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, NULL, 0);
190
+ aclk_http_msg_v2_err(query_thr->client, query->callback_topic, query->msg_id, w->response.code, CLOUD_EC_ZLIB_ERROR, CLOUD_EMSG_ZLIB_ERROR, NULL, 0);
191
goto cleanup;
192
}
193
int bytes_to_cpy = NETDATA_WEB_RESPONSE_ZLIB_CHUNK_SIZE - w->response.zstream.avail_out;
aclk/aclk_tx_msgs.c
+19
-3
@@ -325,12 +325,19 @@ void aclk_send_alarm_metadata(mqtt_wss_client client, int metadata_submitted)
325
buffer_free(local_buffer);
326
}
327
328
-void aclk_http_msg_v2_err(mqtt_wss_client client, const char *topic, const char *msg_id, int http_code, const char *payload, size_t payload_len)
328
+void aclk_http_msg_v2_err(mqtt_wss_client client, const char *topic, const char *msg_id, int http_code, int ec, const char* emsg, const char *payload, size_t payload_len)
329
{
330
json_object *tmp, *msg;
331
msg = create_hdr("http", msg_id, 0, 0, 2);
332
tmp = json_object_new_int(http_code);
333
json_object_object_add(msg, "http-code", tmp);
334
+
335
+ tmp = json_object_new_int(ec);
336
+ json_object_object_add(msg, "error-code", tmp);
337
+
338
+ tmp = json_object_new_string(emsg);
339
+ json_object_object_add(msg, "error-description", tmp);
340
+
341
if (aclk_send_message_with_bin_payload(client, msg, topic, payload, payload_len)) {
342
error("Failed to send cancelation message for http reply");
343
}
@@ -355,8 +362,17 @@ void aclk_http_msg_v2(mqtt_wss_client client, const char *topic, const char *msg
362
int rc = aclk_send_message_with_bin_payload(client, msg, topic, payload, payload_len);
363
json_object_put(msg);
364
358
- if (rc)
359
- aclk_http_msg_v2_err(client, topic, msg_id, rc, payload, payload_len);
365
+ switch (rc) {
366
+ case 403:
367
+ aclk_http_msg_v2_err(client, topic, msg_id, rc, CLOUD_EC_REQ_REPLY_TOO_BIG, CLOUD_EMSG_REQ_REPLY_TOO_BIG, payload, payload_len);
368
+ break;
369
+ case 500:
370
+ aclk_http_msg_v2_err(client, topic, msg_id, rc, CLOUD_EC_FAIL_TOPIC, CLOUD_EMSG_FAIL_TOPIC, payload, payload_len);
371
+ break;
372
+ case 503:
373
+ aclk_http_msg_v2_err(client, topic, msg_id, rc, CLOUD_EC_SND_TIMEOUT, CLOUD_EMSG_SND_TIMEOUT, payload, payload_len);
374
+ break;
375
+ }
376
}
377
378
void aclk_chart_msg(mqtt_wss_client client, RRDHOST *host, const char *chart)
aclk/aclk_tx_msgs.h
+1
-1
@@ -14,7 +14,7 @@ uint16_t aclk_send_bin_message_subtopic_pid(mqtt_wss_client client, char *msg, s
14
void aclk_send_info_metadata(mqtt_wss_client client, int metadata_submitted, RRDHOST *host);
15
void aclk_send_alarm_metadata(mqtt_wss_client client, int metadata_submitted);
16
17
-void aclk_http_msg_v2_err(mqtt_wss_client client, const char *topic, const char *msg_id, int http_code, const char *payload, size_t payload_len);
17
+void aclk_http_msg_v2_err(mqtt_wss_client client, const char *topic, const char *msg_id, int http_code, int ec, const char* emsg, const char *payload, size_t payload_len);
18
void aclk_http_msg_v2(mqtt_wss_client client, const char *topic, const char *msg_id, usec_t t_exec, usec_t created, int http_code, const char *payload, size_t payload_len);
19
20
void aclk_chart_msg(mqtt_wss_client client, RRDHOST *host, const char *chart);
aclk/aclk_util.h
+13
@@ -5,6 +5,19 @@
5
#include "libnetdata/libnetdata.h"
6
#include "mqtt_wss_client.h"
7
8
+#define CLOUD_EC_MALFORMED_NODE_ID 1
9
+#define CLOUD_EMSG_MALFORMED_NODE_ID "URL requests node_id but there is not enough chars following (for it to be valid uuid)."
10
+#define CLOUD_EC_NODE_NOT_FOUND 2
11
+#define CLOUD_EMSG_NODE_NOT_FOUND "Node with requested node_id not found"
12
+#define CLOUD_EC_ZLIB_ERROR 3
13
+#define CLOUD_EMSG_ZLIB_ERROR "Error during zlib compression"
14
+#define CLOUD_EC_REQ_REPLY_TOO_BIG 4
15
+#define CLOUD_EMSG_REQ_REPLY_TOO_BIG "Request reply produces message bigger than allowed maximum"
16
+#define CLOUD_EC_FAIL_TOPIC 5
17
+#define CLOUD_EMSG_FAIL_TOPIC "Internal Topic Error"
18
+#define CLOUD_EC_SND_TIMEOUT 6
19
+#define CLOUD_EMSG_SND_TIMEOUT "Timeout sending binpacked message"
20
+
21
// Helper stuff which should not have any further inside ACLK dependency
22
// and are supposed not to be needed outside of ACLK
23
extern int aclk_use_new_cloud_arch;