@@ -623,8 +623,32 @@ static void s_mqtt_client_init(
623623 & connect , topic_cur , connection -> will .qos , connection -> will .retain , payload_cur );
624624 }
625625
626- if (connection -> username ) {
627- struct aws_byte_cursor username_cur = aws_byte_cursor_from_string (connection -> username );
626+ if (connection -> username || connection -> metrics ) {
627+ struct aws_byte_cursor username_cur ;
628+ if (connection -> username ) {
629+ username_cur = aws_byte_cursor_from_string (connection -> username );
630+ } else {
631+ /* Create empty username cursor when username is null but metrics is set */
632+ username_cur = aws_byte_cursor_from_c_str ("" );
633+ }
634+
635+ aws_byte_buf_clean_up (& connection -> username_with_metrics_buf );
636+
637+ /* Apply metrics to username if configured */
638+ if (connection -> metrics ) {
639+ if (aws_mqtt_append_sdk_metrics_to_username (
640+ connection -> allocator ,
641+ & username_cur ,
642+ connection -> metrics -> storage_view ,
643+ & connection -> username_with_metrics_buf ) == AWS_OP_SUCCESS ) {
644+ username_cur = aws_byte_cursor_from_buf (& connection -> username_with_metrics_buf );
645+ } else {
646+ AWS_LOGF_WARN (
647+ AWS_LS_MQTT_CLIENT ,
648+ "id=%p: Failed to apply metrics to username, using original" ,
649+ (void * )connection );
650+ }
651+ }
628652
629653 AWS_LOGF_DEBUG (
630654 AWS_LS_MQTT_CLIENT ,
@@ -844,6 +868,14 @@ static void s_mqtt_client_connection_destroy_final(struct aws_mqtt_client_connec
844868 connection -> http_proxy_config = NULL ;
845869 }
846870
871+ /* Clean up metrics */
872+ if (connection -> metrics ) {
873+ aws_mqtt_iot_sdk_metrics_storage_clean_up (connection -> metrics );
874+ connection -> metrics = NULL ;
875+ }
876+
877+ aws_byte_buf_clean_up (& connection -> username_with_metrics_buf );
878+
847879 aws_mqtt_client_release (connection -> client );
848880
849881 /* Frees all allocated memory */
@@ -3341,6 +3373,46 @@ int aws_mqtt_client_connection_set_on_operation_statistics_handler(
33413373 return AWS_OP_SUCCESS ;
33423374}
33433375
3376+ static int s_aws_mqtt_client_connection_311_set_metrics (void * impl , const struct aws_mqtt_iot_sdk_metrics * metrics ) {
3377+
3378+ struct aws_mqtt_client_connection_311_impl * connection = impl ;
3379+
3380+ AWS_PRECONDITION (connection );
3381+ if (s_check_connection_state_for_configuration (connection )) {
3382+ return aws_raise_error (AWS_ERROR_INVALID_STATE );
3383+ }
3384+
3385+ if (metrics != NULL && aws_mqtt_validate_iot_sdk_metrics_utf8 (metrics ) == AWS_OP_ERR ) {
3386+ AWS_LOGF_DEBUG (
3387+ AWS_LS_MQTT_CLIENT , "id=%p: Invalid utf8 or forbidden codepoints in metrics." , (void * )connection );
3388+ return aws_raise_error (AWS_ERROR_INVALID_UTF8 );
3389+ }
3390+
3391+ // TODO: Validate metadata value, when we had metadata in place.
3392+
3393+ AWS_LOGF_TRACE (AWS_LS_MQTT_CLIENT , "id=%p: Setting IoT SDK metrics" , (void * )connection );
3394+
3395+ /* Clean up existing metrics if any */
3396+ if (connection -> metrics ) {
3397+ aws_mqtt_iot_sdk_metrics_storage_clean_up (connection -> metrics );
3398+ connection -> metrics = NULL ;
3399+ }
3400+
3401+ if (metrics ) {
3402+ /* Allocate metrics storage */
3403+ connection -> metrics = aws_mem_calloc (connection -> allocator , 1 , sizeof (struct aws_mqtt_iot_sdk_metrics_storage ));
3404+
3405+ /* Initialize metrics storage */
3406+ if (aws_mqtt_iot_sdk_metrics_storage_init (connection -> metrics , connection -> allocator , metrics )) {
3407+ aws_mem_release (connection -> allocator , connection -> metrics );
3408+ connection -> metrics = NULL ;
3409+ return AWS_OP_ERR ;
3410+ }
3411+ }
3412+
3413+ return AWS_OP_SUCCESS ;
3414+ }
3415+
33443416static struct aws_mqtt_client_connection * s_aws_mqtt_client_connection_311_acquire (void * impl ) {
33453417 struct aws_mqtt_client_connection_311_impl * connection = impl ;
33463418
@@ -3390,6 +3462,7 @@ static struct aws_mqtt_client_connection_vtable s_aws_mqtt_client_connection_311
33903462 .unsubscribe_fn = s_aws_mqtt_client_connection_311_unsubscribe ,
33913463 .publish_fn = s_aws_mqtt_client_connection_311_publish ,
33923464 .get_stats_fn = s_aws_mqtt_client_connection_311_get_stats ,
3465+ .set_metrics_fn = s_aws_mqtt_client_connection_311_set_metrics ,
33933466 .get_impl_type = s_aws_mqtt_client_connection_311_get_impl ,
33943467 .get_event_loop = s_aws_mqtt_client_connection_311_get_event_loop ,
33953468};
@@ -3493,6 +3566,8 @@ struct aws_mqtt_client_connection *aws_mqtt_client_connection_new(struct aws_mqt
34933566 connection -> handler .vtable = aws_mqtt_get_client_channel_vtable ();
34943567 connection -> handler .impl = connection ;
34953568
3569+ aws_byte_buf_init (& connection -> username_with_metrics_buf , connection -> allocator , 0 );
3570+
34963571 aws_mqtt311_callback_set_manager_init (& connection -> callback_manager , connection -> allocator , & connection -> base );
34973572
34983573 return & connection -> base ;
@@ -3511,3 +3586,11 @@ struct aws_mqtt_client_connection *aws_mqtt_client_connection_new(struct aws_mqt
35113586
35123587 return NULL ;
35133588}
3589+
3590+ int aws_mqtt_client_connection_set_metrics (
3591+ struct aws_mqtt_client_connection * connection ,
3592+ const struct aws_mqtt_iot_sdk_metrics * metrics ) {
3593+
3594+ AWS_PRECONDITION (connection );
3595+ return connection -> vtable -> set_metrics_fn (connection -> impl , metrics );
3596+ }
0 commit comments