Skip to content

Commit 3e92a0a

Browse files
committed
finalize aws_mqtt_append_sdk_metrics_to_username
1 parent 74d2cc9 commit 3e92a0a

7 files changed

Lines changed: 312 additions & 120 deletions

File tree

include/aws/mqtt/mqtt.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,6 @@ struct aws_mqtt_iot_sdk_metrics {
133133
*/
134134
size_t metadata_count;
135135

136-
/**
137-
* Library version string
138-
*/
139-
struct aws_byte_cursor library_version;
140-
141136
/**
142137
* Library name string (SDK attribute)
143138
*/

include/aws/mqtt/private/client_impl_shared.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ struct aws_mqtt_iot_sdk_metrics_storage {
141141

142142
struct aws_array_list metadata_entries;
143143

144-
struct aws_byte_cursor library_version;
145-
146144
struct aws_byte_cursor library_name;
147145

148146
struct aws_byte_buf storage;
@@ -173,7 +171,7 @@ AWS_MQTT_API struct aws_event_loop *aws_mqtt_client_connection_get_event_loop(
173171
/**
174172
* Appends SDK metrics to the username field
175173
*
176-
* @param original_username The original username (may be NULL)
174+
* @param original_username The original username
177175
* @param metrics The metrics configuration
178176
* @param output_username Buffer to store the modified username
179177
*
@@ -183,7 +181,7 @@ AWS_MQTT_API
183181
int aws_mqtt_append_sdk_metrics_to_username(
184182
struct aws_allocator *allocator,
185183
const struct aws_byte_cursor *original_username,
186-
const struct aws_mqtt_iot_sdk_metrics *metrics,
184+
const struct aws_mqtt_iot_sdk_metrics metrics,
187185
struct aws_byte_buf *output_username);
188186

189187
#endif /* AWS_MQTT_PRIVATE_CLIENT_IMPL_SHARED_H */

source/client.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ static void s_mqtt_client_init(
637637
/* Apply metrics to username if configured */
638638
if (connection->metrics) {
639639
if (aws_mqtt_append_sdk_metrics_to_username(
640-
connection->allocator, &username_cur, &connection->metrics->storage_view, &metrics_username_buf) ==
640+
connection->allocator, &username_cur, connection->metrics->storage_view, &metrics_username_buf) ==
641641
AWS_OP_SUCCESS) {
642642
username_cur = aws_byte_cursor_from_buf(&metrics_username_buf);
643643
} else {

source/client_impl_shared.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ static size_t s_aws_mqtt_iot_sdk_metrics_compute_storage_size(const struct aws_m
240240
size_t storage_size = 0;
241241

242242
storage_size += metrics->library_name.len;
243-
storage_size += metrics->library_version.len;
244243

245244
for (size_t i = 0; i < metrics->metadata_count; ++i) {
246245
storage_size += metrics->metadata_entries[i].key.len;
@@ -309,14 +308,6 @@ int aws_mqtt_iot_sdk_metrics_storage_init(
309308
storage_view->library_name = metrics_storage->library_name;
310309
}
311310

312-
if (metrics_options->library_version.len > 0) {
313-
metrics_storage->library_version = metrics_options->library_version;
314-
if (aws_byte_buf_append_and_update(&metrics_storage->storage, &metrics_storage->library_version)) {
315-
goto metrics_storage_error;
316-
}
317-
storage_view->library_version = metrics_storage->library_version;
318-
}
319-
320311
return AWS_OP_SUCCESS;
321312

322313
metrics_storage_error:

source/mqtt_iot_sdk_metrics.c

Lines changed: 106 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -11,112 +11,117 @@
1111

1212
#include <stdio.h>
1313

14+
// Maximum MQTT5 Content Type size https://docs.aws.amazon.com/general/latest/gr/iot-core.html#thing-limits
15+
const int AWS_IOT_MAX_CONTENT_SIZE = 256;
16+
1417
int aws_mqtt_append_sdk_metrics_to_username(
1518
struct aws_allocator *allocator,
1619
const struct aws_byte_cursor *original_username,
17-
const struct aws_mqtt_iot_sdk_metrics *metrics,
20+
const struct aws_mqtt_iot_sdk_metrics metrics,
1821
struct aws_byte_buf *output_username) {
1922

20-
// WIP
21-
// if (!allocator || !metrics || !output_username) {
22-
// return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
23-
// }
24-
25-
// /* Estimate buffer size needed */
26-
// size_t estimated_size = 256;
27-
// if (original_username && original_username->len > 0) {
28-
// estimated_size += original_username->len;
29-
// }
30-
31-
// if (aws_byte_buf_init(output_username, allocator, estimated_size)) {
32-
// return AWS_OP_ERR;
33-
// }
34-
35-
// /* Add original username if it exists */
36-
// if (original_username && original_username->len > 0) {
37-
// if (aws_byte_buf_append(output_username, original_username)) {
38-
// goto error;
39-
// }
40-
41-
// /* Add separator */
42-
// struct aws_byte_cursor separator = aws_byte_cursor_from_c_str("?");
43-
// if (aws_byte_buf_append(output_username, &separator)) {
44-
// goto error;
45-
// }
46-
// }
47-
48-
// /* Add SDK attribute */
49-
// if (metrics->library_name.len > 0) {
50-
// struct aws_byte_cursor sdk_prefix =
51-
// aws_byte_cursor_from_c_str(original_username && original_username->len > 0 ? "SDK=" : "?SDK=");
52-
// if (aws_byte_buf_append(output_username, &sdk_prefix)) {
53-
// goto error;
54-
// }
55-
// if (aws_byte_buf_append(output_username, &metrics->library_name)) {
56-
// goto error;
57-
// }
58-
// }
59-
60-
// /* Add Version attribute */
61-
// if (metrics->library_version.len > 0) {
62-
// struct aws_byte_cursor version_prefix = aws_byte_cursor_from_c_str("&Version=");
63-
// if (aws_byte_buf_append(output_username, &version_prefix)) {
64-
// goto error;
65-
// }
66-
// if (aws_byte_buf_append(output_username, &metrics->library_version)) {
67-
// goto error;
68-
// }
69-
// }
70-
71-
// /* Add Platform attribute */
72-
// struct aws_byte_cursor platform_cursor = aws_get_platform_build_os_string();
73-
74-
// struct aws_byte_cursor platform_prefix = aws_byte_cursor_from_c_str("&Platform=");
75-
// if (aws_byte_buf_append(output_username, &platform_prefix)) {
76-
// goto error;
77-
// }
78-
// if (aws_byte_buf_append(output_username, &platform_cursor)) {
79-
// goto error;
80-
// }
81-
82-
// /* Add Metadata if present */
83-
// if (metrics->metadata_entries && metrics->metadata_count > 0) {
84-
// struct aws_byte_cursor metadata_prefix = aws_byte_cursor_from_c_str("&Metadata=(");
85-
// if (aws_byte_buf_append(output_username, &metadata_prefix)) {
86-
// goto error;
87-
// }
88-
89-
// for (size_t i = 0; i < metrics->metadata_count; ++i) {
90-
// if (i > 0) {
91-
// struct aws_byte_cursor semicolon = aws_byte_cursor_from_c_str(";");
92-
// if (aws_byte_buf_append(output_username, &semicolon)) {
93-
// goto error;
94-
// }
95-
// }
96-
97-
// if (aws_byte_buf_append(output_username, &metrics->metadata_entries[i].key)) {
98-
// goto error;
99-
// }
100-
101-
// struct aws_byte_cursor equals = aws_byte_cursor_from_c_str("=");
102-
// if (aws_byte_buf_append(output_username, &equals)) {
103-
// goto error;
104-
// }
105-
106-
// if (aws_byte_buf_append(output_username, &metrics->metadata_entries[i].value)) {
107-
// goto error;
108-
// }
109-
// }
110-
111-
// struct aws_byte_cursor metadata_suffix = aws_byte_cursor_from_c_str(")");
112-
// if (aws_byte_buf_append(output_username, &metadata_suffix)) {
113-
// goto error;
114-
// }
115-
// }
116-
23+
if (!allocator || !output_username) {
24+
return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
25+
}
26+
27+
/* Build metrics string */
28+
struct aws_byte_buf metrics_string;
29+
if (aws_byte_buf_init(&metrics_string, allocator, AWS_IOT_MAX_CONTENT_SIZE)) {
30+
return AWS_OP_ERR;
31+
}
32+
33+
/* Check if the attributes already exists in username */
34+
bool has_sdk = false;
35+
bool has_platform = false;
36+
bool has_query = false;
37+
38+
struct aws_byte_cursor sdk_str = aws_byte_cursor_from_c_str("SDK=");
39+
struct aws_byte_cursor platform_str = aws_byte_cursor_from_c_str("Platform=");
40+
struct aws_byte_cursor question_mark_str = aws_byte_cursor_from_c_str("?");
41+
struct aws_byte_cursor amp = aws_byte_cursor_from_c_str("&");
42+
43+
// TODO: we ignored the metadata field for now, need to add them later
44+
45+
if (original_username && original_username->len > 0) {
46+
struct aws_byte_cursor question_mark_find;
47+
has_query =
48+
AWS_OP_SUCCESS == aws_byte_cursor_find_exact(original_username, &question_mark_str, &question_mark_find);
49+
if (has_query) {
50+
struct aws_byte_cursor temp_cursor;
51+
has_sdk = AWS_OP_SUCCESS == aws_byte_cursor_find_exact(&question_mark_find, &sdk_str, &temp_cursor);
52+
has_platform =
53+
AWS_OP_SUCCESS == aws_byte_cursor_find_exact(&question_mark_find, &platform_str, &temp_cursor);
54+
}
55+
}
56+
57+
bool metrics_added = false;
58+
59+
/* Add SDK if not present */
60+
if (!has_sdk) {
61+
if (aws_byte_buf_append(&metrics_string, &sdk_str)) {
62+
goto error;
63+
}
64+
65+
struct aws_byte_cursor sdk_attr_value =
66+
metrics.library_name.len > 0 ? metrics.library_name : aws_byte_cursor_from_c_str("IoTDeviceSDK/C");
67+
if (aws_byte_buf_append(&metrics_string, &sdk_attr_value)) {
68+
goto error;
69+
}
70+
71+
metrics_added = true;
72+
}
73+
74+
/* Add Platform if not present */
75+
if (!has_platform) {
76+
struct aws_byte_cursor platform_cursor = aws_get_platform_build_os_string();
77+
if (platform_cursor.len > 0) {
78+
if (metrics_added) {
79+
if (aws_byte_buf_append(&metrics_string, &amp)) {
80+
goto error;
81+
}
82+
}
83+
84+
if (aws_byte_buf_append(&metrics_string, &platform_str) ||
85+
aws_byte_buf_append(&metrics_string, &platform_cursor)) {
86+
goto error;
87+
}
88+
metrics_added = true;
89+
}
90+
}
91+
92+
/* Build final output */
93+
// TODO: we should consider the case where total size extceeds MQTT username limit
94+
size_t total_size = (original_username ? original_username->len : 0) + metrics_string.len + 1;
95+
96+
if (aws_byte_buf_init(output_username, allocator, total_size)) {
97+
goto error;
98+
}
99+
100+
/* Add original username */
101+
if (original_username && original_username->len > 0) {
102+
if (aws_byte_buf_append(output_username, original_username)) {
103+
goto error_output;
104+
}
105+
}
106+
107+
/* Add metrics with separator */
108+
if (metrics_string.len > 0) {
109+
struct aws_byte_cursor separator = has_query ? amp : question_mark_str;
110+
if (aws_byte_buf_append(output_username, &separator)) {
111+
goto error_output;
112+
}
113+
struct aws_byte_cursor metrics_cursor = aws_byte_cursor_from_buf(&metrics_string);
114+
if (aws_byte_buf_append(output_username, &metrics_cursor)) {
115+
goto error_output;
116+
}
117+
}
118+
119+
aws_byte_buf_clean_up(&metrics_string);
117120
return AWS_OP_SUCCESS;
118121

119-
// error:
120-
// aws_byte_buf_clean_up(output_username);
121-
// return AWS_OP_ERR;
122+
error_output:
123+
aws_byte_buf_clean_up(output_username);
124+
error:
125+
aws_byte_buf_clean_up(&metrics_string);
126+
return AWS_OP_ERR;
122127
}

tests/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,13 @@ add_test_case(mqtt_operation_statistics_simple_callback)
123123
# Connection termination tests
124124
add_test_case(mqtt_connection_termination_callback_simple)
125125

126+
# IoT SDK metrics tests
127+
add_test_case(mqtt_append_sdk_metrics_basic)
128+
add_test_case(mqtt_append_sdk_metrics_empty)
129+
add_test_case(mqtt_append_sdk_metrics_existing_attributes)
130+
add_test_case(mqtt_append_sdk_metrics_special_chars)
131+
add_test_case(mqtt_append_sdk_metrics_long_strings)
132+
126133
# MQTT5 tests
127134

128135
# topic utilities
@@ -619,3 +626,4 @@ aws_set_common_properties(${TEST_IOT_CLIENT_BINARY_NAME})
619626
aws_add_sanitizers(${TEST_IOT_CLIENT_BINARY_NAME} ${${PROJECT_NAME}_SANITIZERS})
620627
target_compile_definitions(${TEST_IOT_CLIENT_BINARY_NAME} PRIVATE AWS_UNSTABLE_TESTING_API=1)
621628
target_include_directories(${TEST_IOT_CLIENT_BINARY_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
629+

0 commit comments

Comments
 (0)