Skip to content

Commit 93ee7be

Browse files
committed
Merge branch 'metrics_mqtt3' of github.com:awslabs/aws-c-mqtt into metrics_mqtt5
2 parents 6f6aa06 + 74e3049 commit 93ee7be

5 files changed

Lines changed: 74 additions & 30 deletions

File tree

include/aws/mqtt/private/mqtt_iot_sdk_metrics.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ int aws_mqtt_append_sdk_metrics_to_username(
4848
size_t *out_full_username_size);
4949

5050
/**
51-
* Validates that all string fields in aws_mqtt_iot_sdk_metrics
51+
* Validates all string fields in aws_mqtt_iot_sdk_metrics
5252
*
5353
* @param metrics The metrics structure to validate
54-
* @return AWS_OP_SUCCESS if all strings are valid, AWS_OP_ERR otherwise
54+
* @return AWS_OP_SUCCESS if metrics is not null and all metrics value are valid, AWS_OP_ERR otherwise
5555
*/
5656
AWS_MQTT_API
5757
int aws_mqtt_validate_iot_sdk_metrics(const struct aws_mqtt_iot_sdk_metrics *metrics);

source/client.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -650,12 +650,7 @@ static void s_mqtt_client_init(
650650
}
651651
}
652652

653-
if (aws_byte_cursor_is_valid(&username_cur)) {
654-
AWS_LOGF_DEBUG(
655-
AWS_LS_MQTT_CLIENT,
656-
"id=%p: Adding username " PRInSTR " to connection",
657-
(void *)connection,
658-
AWS_BYTE_CURSOR_PRI(username_cur));
653+
if (aws_byte_cursor_is_valid(&username_cur) && username_cur.len > 0) {
659654

660655
struct aws_byte_cursor password_cur;
661656
AWS_ZERO_STRUCT(password_cur);
@@ -664,9 +659,15 @@ static void s_mqtt_client_init(
664659
password_cur = aws_byte_cursor_from_string(connection->password);
665660
}
666661

662+
AWS_LOGF_DEBUG(
663+
AWS_LS_MQTT_CLIENT,
664+
"id=%p: Adding username " PRInSTR " to connection",
665+
(void *)connection,
666+
AWS_BYTE_CURSOR_PRI(username_cur));
667+
667668
aws_mqtt_packet_connect_add_credentials(&connect, username_cur, password_cur);
668669
} else {
669-
AWS_LOGF_WARN(
670+
AWS_LOGF_INFO(
670671
AWS_LS_MQTT_CLIENT,
671672
"id=%p: Failed to set username and password. Most likely there is an issue in metrics. (e.x.: username "
672673
"is empty and metrics string exceed the size limit). ",
@@ -3389,7 +3390,7 @@ static int s_aws_mqtt_client_connection_311_set_metrics(void *impl, const struct
33893390
if (metrics) {
33903391
if (aws_mqtt_validate_iot_sdk_metrics(metrics) == AWS_OP_ERR) {
33913392
AWS_LOGF_ERROR(AWS_LS_MQTT_CLIENT, "id=%p: Invalid metrics.", (void *)connection);
3392-
return aws_raise_error(AWS_ERROR_INVALID_UTF8);
3393+
return AWS_OP_ERR;
33933394
}
33943395

33953396
metrics_storage = aws_mqtt_iot_sdk_metrics_storage_new(connection->allocator, metrics);
@@ -3421,12 +3422,10 @@ static int s_aws_mqtt_client_connection_311_set_metrics(void *impl, const struct
34213422
goto done;
34223423
}
34233424

3424-
/* Clean up existing metrics if any */
3425-
if (connection->metrics_storage) {
3426-
aws_mqtt_iot_sdk_metrics_storage_destroy(connection->metrics_storage);
3427-
}
3428-
connection->metrics_storage = metrics_storage;
34293425
AWS_LOGF_TRACE(AWS_LS_MQTT_CLIENT, "id=%p: Setting IoT SDK metrics", (void *)connection);
3426+
aws_mqtt_iot_sdk_metrics_storage_destroy(connection->metrics_storage);
3427+
connection->metrics_storage = metrics_storage;
3428+
34303429
metrics_storage = NULL;
34313430
result = AWS_OP_SUCCESS;
34323431

source/mqtt_iot_sdk_metrics.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,23 @@
1515
const size_t AWS_IOT_MAX_USERNAME_SIZE = UINT16_MAX;
1616
const size_t DEFAULT_QUERY_PARAM_COUNT = 10;
1717

18-
// Build username query string from params_list, the caller is responsible to init and clean up output_username
19-
// If output_username is NULL, the function will just calculate the full username size and return it in
20-
// out_full_username_size
18+
/**
19+
* Builds final username with query parameters appended.
20+
*
21+
* @param base_username The original username cursor
22+
* @param base_username_length Length of base username to use (may differ from cursor length)
23+
* @param params_list List of query parameters to append
24+
* @param output_username [Optional] Buffer to write result. Caller must init/cleanup the buffer.
25+
* @param out_final_username_size [Optional] Outputs the final username size
26+
*
27+
* @return AWS_OP_SUCCESS on success, AWS_OP_ERR on failure
28+
*/
2129
int s_build_username_query(
2230
const struct aws_byte_cursor *base_username,
2331
size_t base_username_length,
2432
const struct aws_array_list *params_list,
2533
struct aws_byte_buf *output_username,
26-
size_t *out_full_username_size) {
34+
size_t *out_final_username_size) {
2735

2836
AWS_ASSERT(base_username);
2937
AWS_ASSERT(params_list);
@@ -34,8 +42,8 @@ int s_build_username_query(
3442
}
3543
}
3644

37-
if (out_full_username_size) {
38-
*out_full_username_size = base_username_length;
45+
if (out_final_username_size) {
46+
*out_final_username_size = base_username_length;
3947
}
4048

4149
struct aws_byte_cursor query_delim = aws_byte_cursor_from_c_str("?");
@@ -56,8 +64,8 @@ int s_build_username_query(
5664
}
5765
}
5866

59-
if (out_full_username_size) {
60-
*out_full_username_size += 1;
67+
if (out_final_username_size) {
68+
*out_final_username_size += 1;
6169
}
6270

6371
if (output_username) {
@@ -78,8 +86,8 @@ int s_build_username_query(
7886
}
7987
}
8088

81-
if (out_full_username_size) {
82-
*out_full_username_size += param.key.len + (param.value.len > 0 ? 1 : 0) + param.value.len;
89+
if (out_final_username_size) {
90+
*out_final_username_size += param.key.len + (param.value.len > 0 ? 1 : 0) + param.value.len;
8391
}
8492
}
8593

@@ -93,6 +101,7 @@ int aws_mqtt_append_sdk_metrics_to_username(
93101
const struct aws_mqtt_iot_sdk_metrics *metrics,
94102
struct aws_byte_buf *output_username,
95103
size_t *out_full_username_size) {
104+
AWS_PRECONDITION(aws_byte_buf_is_valid(output_username) && output_username->buffer == NULL);
96105

97106
if (!allocator) {
98107
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
@@ -126,11 +135,13 @@ int aws_mqtt_append_sdk_metrics_to_username(
126135
struct aws_array_list params_list;
127136
aws_array_list_init_dynamic(&params_list, allocator, DEFAULT_QUERY_PARAM_COUNT, sizeof(struct aws_uri_param));
128137

138+
// Looking for any existing query in the original username
129139
if (local_original_username.len > 0) {
130140
struct aws_byte_cursor question_mark_find = local_original_username;
131141

132142
bool found_query = false;
133-
// Find last question mark
143+
// Find last question mark. The IoT service will trim string after last question mark and handle it as metrics
144+
// metadata
134145
while (AWS_OP_SUCCESS ==
135146
aws_byte_cursor_find_exact(&question_mark_find, &question_mark_str, &question_mark_find)) {
136147
// Advance cursor to skip the "?" character
@@ -147,6 +158,7 @@ int aws_mqtt_append_sdk_metrics_to_username(
147158
}
148159
}
149160

161+
// Verify if the username already contains "SDK" and "Platform" fields.
150162
bool found_sdk = false;
151163
bool found_platform = false;
152164

@@ -180,7 +192,7 @@ int aws_mqtt_append_sdk_metrics_to_username(
180192
}
181193

182194
// Rebuild metrics string from params_list
183-
// First parse to calculate total size
195+
// First parse to get final username size
184196
size_t total_size = 0;
185197
s_build_username_query(&local_original_username, base_username_length, &params_list, NULL, &total_size);
186198

@@ -288,7 +300,7 @@ void aws_mqtt_iot_sdk_metrics_storage_destroy(struct aws_mqtt_iot_sdk_metrics_st
288300

289301
int aws_mqtt_validate_iot_sdk_metrics(const struct aws_mqtt_iot_sdk_metrics *metrics) {
290302
if (metrics == NULL) {
291-
return AWS_OP_SUCCESS;
303+
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
292304
}
293305

294306
if (aws_mqtt_validate_utf8_text(metrics->library_name)) {

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ add_test_case(mqtt_append_sdk_metrics_existing_attributes)
146146
add_test_case(mqtt_append_sdk_metrics_special_chars)
147147
add_test_case(mqtt_append_sdk_metrics_long_strings)
148148
add_test_case(mqtt_append_sdk_metrics_invalid_utf8)
149+
add_test_case(mqtt_append_sdk_metrics_multiple_question_mark)
149150

150151
# topic aliasing
151152
add_test_case(mqtt5_inbound_topic_alias_register_failure)

tests/shared_utils_tests.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,38 @@ static int s_test_mqtt_append_sdk_metrics_special_chars(struct aws_allocator *al
284284

285285
AWS_TEST_CASE(mqtt_append_sdk_metrics_special_chars, s_test_mqtt_append_sdk_metrics_special_chars)
286286

287+
static int s_test_mqtt_append_sdk_metrics_multiple_question_mark(struct aws_allocator *allocator, void *ctx) {
288+
(void)ctx;
289+
290+
struct aws_mqtt_iot_sdk_metrics metrics = {.library_name = aws_byte_cursor_from_c_str("SDK/Test-1.0")};
291+
292+
struct aws_byte_buf output_username;
293+
AWS_ZERO_STRUCT(output_username);
294+
295+
struct aws_byte_cursor original_username = aws_byte_cursor_from_c_str("user?name?test?");
296+
297+
ASSERT_SUCCESS(
298+
aws_mqtt_append_sdk_metrics_to_username(allocator, &original_username, &metrics, &output_username, NULL));
299+
300+
struct aws_byte_cursor output_cursor = aws_byte_cursor_from_buf(&output_username);
301+
302+
/* Expected string: user?name?test?SDK=SDK/Test-1.0&Platform=<OS> */
303+
struct aws_byte_cursor base_username = aws_byte_cursor_from_c_str("user?name?test");
304+
struct aws_byte_buf expected_buf;
305+
AWS_ZERO_STRUCT(expected_buf);
306+
aws_test_mqtt_build_expected_metrics(
307+
allocator, &base_username, aws_byte_cursor_from_c_str("SDK/Test-1.0"), NULL, &expected_buf);
308+
309+
ASSERT_TRUE(aws_byte_cursor_eq_byte_buf(&output_cursor, &expected_buf));
310+
311+
aws_byte_buf_clean_up(&output_username);
312+
aws_byte_buf_clean_up(&expected_buf);
313+
314+
return AWS_OP_SUCCESS;
315+
}
316+
317+
AWS_TEST_CASE(mqtt_append_sdk_metrics_multiple_question_mark, s_test_mqtt_append_sdk_metrics_multiple_question_mark)
318+
287319
static int s_test_mqtt_append_sdk_metrics_long_strings(struct aws_allocator *allocator, void *ctx) {
288320
(void)ctx;
289321

@@ -308,12 +340,12 @@ static int s_test_mqtt_append_sdk_metrics_long_strings(struct aws_allocator *all
308340
// aws_mqtt_append_sdk_metrics_to_username does not valid original username length
309341
ASSERT_SUCCESS(
310342
aws_mqtt_append_sdk_metrics_to_username(allocator, &original_username, &short_metrics, &output_username, NULL));
343+
aws_byte_buf_clean_up(&output_username);
344+
311345
// aws_mqtt_append_sdk_metrics_to_username fails when the extra metrics string exceeds buffer limit
312346
ASSERT_FAILS(
313347
aws_mqtt_append_sdk_metrics_to_username(allocator, &original_username, &metrics, &output_username, NULL));
314348

315-
aws_byte_buf_clean_up(&output_username);
316-
317349
return AWS_OP_SUCCESS;
318350
}
319351

0 commit comments

Comments
 (0)