Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1d8a7aa
binding metrics. Custom Auth related test should fail
xiazhvera Dec 30, 2025
77814a6
update custome auth tests and adapter
xiazhvera Dec 30, 2025
50a04aa
Merge branch 'main' of https://github.com/awslabs/aws-crt-java into i…
xiazhvera Dec 30, 2025
a3376ed
update test for adapter
xiazhvera Dec 30, 2025
129e2d1
cleanup
xiazhvera Jan 5, 2026
c52ba49
lint
xiazhvera Jan 5, 2026
1e935fe
Merge branch 'main' of https://github.com/awslabs/aws-crt-java into i…
xiazhvera Jan 5, 2026
9b506f3
update jni-config
xiazhvera Jan 5, 2026
6fb3333
Merge branch 'main' into iot_metrics
xiazhvera Jan 8, 2026
af9d6ab
Merge branch 'main' into iot_metrics
xiazhvera Jan 15, 2026
3066559
Merge branch 'main' into iot_metrics
xiazhvera Jan 15, 2026
a61572c
and retry
xiazhvera Jan 16, 2026
203d0e1
Merge branch 'main' into iot_metrics
xiazhvera Feb 12, 2026
63c143d
set metrics should not fail the connection
xiazhvera Feb 12, 2026
2bbb311
set metrics should not fail the connection
xiazhvera Feb 12, 2026
c8f1275
set metrics should not fail the mqtt5 client
xiazhvera Feb 12, 2026
a0c5f34
update metrics naming
xiazhvera Feb 13, 2026
67e3770
Merge branch 'main' into iot_metrics
xiazhvera Feb 16, 2026
21e2cb7
update mqtt library
xiazhvera Feb 17, 2026
07a0e42
Merge branch 'iot_metrics' of https://github.com/awslabs/aws-crt-java…
xiazhvera Feb 17, 2026
ceaf372
Merge branch 'main' into iot_metrics
xiazhvera Feb 19, 2026
8ec2d38
add metrics enabled tests
xiazhvera Mar 2, 2026
0d276ad
Merge branch 'iot_metrics' of https://github.com/awslabs/aws-crt-java…
xiazhvera Mar 2, 2026
20fa798
fix error
xiazhvera Mar 3, 2026
e67a0f4
catch error for connection failure
xiazhvera Mar 3, 2026
9258ac2
Merge branch 'main' into iot_metrics
xiazhvera Mar 3, 2026
63510f3
kick codebuild
xiazhvera Mar 3, 2026
aff778f
Merge branch 'iot_metrics' of https://github.com/awslabs/aws-crt-java…
xiazhvera Mar 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
package software.amazon.awssdk.crt.internal;

/**
* @internal
* IoT Device SDK Metrics Structure
*/
public class IoTDeviceSDKMetrics {
private String libraryName;

public IoTDeviceSDKMetrics() {
this.libraryName = "IoTDeviceSDK/Java";
}

public String getLibraryName() {
return libraryName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import software.amazon.awssdk.crt.mqtt5.Mqtt5Client;
import software.amazon.awssdk.crt.mqtt5.Mqtt5ClientOptions;
import software.amazon.awssdk.crt.mqtt5.packets.ConnectPacket;
import software.amazon.awssdk.crt.internal.IoTDeviceSDKMetrics;

import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
Expand Down Expand Up @@ -77,6 +78,7 @@ private static MqttConnectionConfig s_toMqtt3ConnectionConfig(Mqtt5ClientOptions
options.setProtocolOperationTimeoutMs(mqtt5options.getAckTimeoutSeconds() != null
? Math.toIntExact(mqtt5options.getAckTimeoutSeconds()) * 1000
: 0);
options.setMetricsEnabled(mqtt5options.getMetricsEnabled());
return options;
}

Expand Down Expand Up @@ -162,6 +164,10 @@ private void SetupConfig(MqttConnectionConfig config) throws MqttException {
mqttClientConnectionSetLogin(getNativeHandle(), config.getUsername(), config.getPassword());
}

if (config.getMetricsEnabled()) {
mqttClientConnectionSetMetrics(getNativeHandle(), new IoTDeviceSDKMetrics());
}

if (config.getMinReconnectTimeoutSecs() != 0L && config.getMaxReconnectTimeoutSecs() != 0L) {
mqttClientConnectionSetReconnectTimeout(getNativeHandle(), config.getMinReconnectTimeoutSecs(),
config.getMaxReconnectTimeoutSecs());
Expand Down Expand Up @@ -502,6 +508,9 @@ private static native boolean mqttClientConnectionSetWill(long connection, Strin
private static native void mqttClientConnectionSetLogin(long connection, String username, String password)
throws CrtRuntimeException;

private static native void mqttClientConnectionSetMetrics(long connection, IoTDeviceSDKMetrics metrics)
throws CrtRuntimeException;

private static native void mqttClientConnectionSetReconnectTimeout(long connection, long minTimeout,
long maxTimeout)
throws CrtRuntimeException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public final class MqttConnectionConfig extends CrtResource {
private HttpProxyOptions proxyOptions;
private Consumer<WebsocketHandshakeTransformArgs> websocketHandshakeTransform;

/* metrics */
private boolean metricsEnabled = true;

public MqttConnectionConfig() {}


Expand Down Expand Up @@ -538,6 +541,24 @@ public Consumer<WebsocketHandshakeTransformArgs> getWebsocketHandshakeTransform(
return websocketHandshakeTransform;
}

/**
* Enables or disables IoT Device SDK metrics collection
*
* @param enabled true to enable metrics, false to disable
*/
public void setMetricsEnabled(boolean enabled) {
this.metricsEnabled = enabled;
}

/**
* Queries whether IoT Device SDK metrics collection is enabled
*
* @return true if metrics are enabled, false if disabled
*/
public boolean getMetricsEnabled() {
return metricsEnabled;
}

/**
* Creates a (shallow) clone of this config object
*
Expand Down Expand Up @@ -567,6 +588,7 @@ public MqttConnectionConfig clone() {
clone.setWebsocketHandshakeTransform(getWebsocketHandshakeTransform());

clone.setReconnectTimeoutSecs(getMinReconnectTimeoutSecs(), getMaxReconnectTimeoutSecs());
clone.setMetricsEnabled(getMetricsEnabled());

// success, bump up the ref count so we can escape the try-with-resources block
clone.addRef();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import software.amazon.awssdk.crt.mqtt5.packets.ConnectPacket;
import software.amazon.awssdk.crt.mqtt.MqttConnectionConfig;
import software.amazon.awssdk.crt.internal.IoTDeviceSDKMetrics;

import java.util.Map;
import java.util.function.Function;
Expand Down Expand Up @@ -45,6 +46,11 @@ public class Mqtt5ClientOptions {
private Consumer<Mqtt5WebsocketHandshakeTransformArgs> websocketHandshakeTransform;
private PublishEvents publishEvents;
private TopicAliasingOptions topicAliasingOptions;
// Indicates whether AWS IoT Metrics are enabled for this client, default to true.
// We don't expose this setting in the builder for now.
private IoTDeviceSDKMetrics iotDeviceSDKMetrics;
private boolean metricsEnabled = true;


/**
* Returns the host name of the MQTT server to connect to.
Expand Down Expand Up @@ -263,6 +269,24 @@ public TopicAliasingOptions getTopicAliasingOptions() {
return this.topicAliasingOptions;
}

/**
* Returns whether AWS IoT Device SDK metrics collection is enabled
*
* @return true if metrics are enabled, false otherwise
*/
public boolean getMetricsEnabled() {
return this.metricsEnabled;
}

/**
* Enables or disables IoT Device SDK metrics collection
*
* @param enabled true to enable metrics, false to disable
*/
public void setMetricsEnabled(boolean enabled) {
this.metricsEnabled = enabled;
}

/**
* Creates a Mqtt5ClientOptionsBuilder instance
* @param builder The builder to get the Mqtt5ClientOptions values from
Expand All @@ -289,6 +313,8 @@ public Mqtt5ClientOptions(Mqtt5ClientOptionsBuilder builder) {
this.websocketHandshakeTransform = builder.websocketHandshakeTransform;
this.publishEvents = builder.publishEvents;
this.topicAliasingOptions = builder.topicAliasingOptions;
this.metricsEnabled = builder.metricsEnabled;
this.iotDeviceSDKMetrics = new IoTDeviceSDKMetrics();
}

/*******************************************************************************
Expand Down Expand Up @@ -583,6 +609,7 @@ static final public class Mqtt5ClientOptionsBuilder {
private Consumer<Mqtt5WebsocketHandshakeTransformArgs> websocketHandshakeTransform;
private PublishEvents publishEvents;
private TopicAliasingOptions topicAliasingOptions;
private boolean metricsEnabled = true;

/**
* Sets the host name of the MQTT server to connect to.
Expand Down Expand Up @@ -850,6 +877,17 @@ public Mqtt5ClientOptionsBuilder withTopicAliasingOptions(TopicAliasingOptions o
return this;
}

/**
* Enables or disables IoT Device SDK metrics collection
*
* @param enabled true to enable metrics, false to disable
* @return The Mqtt5ClientOptionsBuilder after setting the metrics option
*/
public Mqtt5ClientOptionsBuilder withMetricsEnabled(boolean enabled) {
this.metricsEnabled = enabled;
return this;
}

/**
* Creates a new Mqtt5ClientOptionsBuilder instance
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,14 @@
}
]
},
{
"name": "software.amazon.awssdk.crt.internal.IoTDeviceSDKMetrics",
"fields": [
{
"name": "libraryName"
}
]
},
{
"name": "software.amazon.awssdk.crt.mqtt5.Mqtt5ClientOptions",
"fields": [
Expand Down Expand Up @@ -1306,6 +1314,12 @@
},
{
"name": "topicAliasingOptions"
},
{
"name": "iotDeviceSDKMetrics"
},
{
"name": "metricsEnabled"
}
],
"methods": [
Expand Down
76 changes: 76 additions & 0 deletions src/native/iot_device_sdk_metrics.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <jni.h>

#include "iot_device_sdk_metrics.h"
#include "mqtt5_packets.h"
#include <aws/mqtt/mqtt.h>
#include <crt.h>
#include <java_class_ids.h>

static char s_iot_device_sdk_metrics_string[] = "IoTDeviceSDKMetrics";

void aws_mqtt_iot_metrics_java_jni_destroy(
JNIEnv *env,
struct aws_allocator *allocator,
struct aws_mqtt_iot_metrics_java_jni *java_metrics) {
(void)env;

if (!java_metrics) {
return;
}
AWS_LOGF_DEBUG(AWS_LS_MQTT_GENERAL, "id=%p: Destroying IoTDeviceSDKMetrics", (void *)java_metrics);

if (aws_byte_buf_is_valid(&java_metrics->library_name_buf)) {
aws_byte_buf_clean_up(&java_metrics->library_name_buf);
}

aws_mem_release(allocator, java_metrics);
}

struct aws_mqtt_iot_metrics_java_jni *aws_mqtt_iot_metrics_java_jni_create_from_java(
JNIEnv *env,
struct aws_allocator *allocator,
jobject java_iot_device_sdk_metrics) {

struct aws_mqtt_iot_metrics_java_jni *java_metrics =
aws_mem_calloc(allocator, 1, sizeof(struct aws_mqtt_iot_metrics_java_jni));
if (java_metrics == NULL) {
AWS_LOGF_ERROR(
AWS_LS_MQTT_GENERAL, "IoTDeviceSDKMetrics create_from_java: Creating new IoTDeviceSDKMetrics failed");
return NULL;
}

if (aws_get_string_from_jobject(
env,
java_iot_device_sdk_metrics,
iot_device_sdk_metrics_properties.library_name_field_id,
s_iot_device_sdk_metrics_string,
"library name",
&java_metrics->library_name_buf,
&java_metrics->library_name_cursor,
false,
NULL) == AWS_OP_ERR) {
AWS_LOGF_ERROR(AWS_LS_MQTT_GENERAL, "IoTDeviceSDKMetrics create_from_java: No library name found");
goto on_error;
}
java_metrics->metrics.library_name = java_metrics->library_name_cursor;

return java_metrics;

on_error:
/* Clean up */
aws_mqtt_iot_metrics_java_jni_destroy(env, allocator, java_metrics);
return NULL;
}

struct aws_mqtt_iot_metrics *aws_mqtt_iot_metrics_java_jni_get_metrics(
struct aws_mqtt_iot_metrics_java_jni *java_metrics) {
if (java_metrics) {
return &java_metrics->metrics;
} else {
return NULL;
}
}
31 changes: 31 additions & 0 deletions src/native/iot_device_sdk_metrics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#ifndef AWS_JNI_IOT_DEVICE_SDK_METRICS_H
#define AWS_JNI_IOT_DEVICE_SDK_METRICS_H

#include <aws/mqtt/mqtt.h>
#include <crt.h>
#include <jni.h>

struct aws_mqtt_iot_metrics_java_jni {
struct aws_mqtt_iot_metrics metrics;
struct aws_byte_buf library_name_buf;
struct aws_byte_cursor library_name_cursor;
};

void aws_mqtt_iot_metrics_java_jni_destroy(
JNIEnv *env,
struct aws_allocator *allocator,
struct aws_mqtt_iot_metrics_java_jni *java_metrics);

struct aws_mqtt_iot_metrics_java_jni *aws_mqtt_iot_metrics_java_jni_create_from_java(
JNIEnv *env,
struct aws_allocator *allocator,
jobject java_iot_device_sdk_metrics);

struct aws_mqtt_iot_metrics *aws_mqtt_iot_metrics_java_jni_get_metrics(
struct aws_mqtt_iot_metrics_java_jni *java_metrics);

#endif /* AWS_JNI_IOT_DEVICE_SDK_METRICS_H */
23 changes: 23 additions & 0 deletions src/native/java_class_ids.c
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,15 @@ static void s_cache_mqtt5_client_options(JNIEnv *env) {
"topicAliasingOptions",
"Lsoftware/amazon/awssdk/crt/mqtt5/TopicAliasingOptions;");
AWS_FATAL_ASSERT(mqtt5_client_options_properties.topic_aliasing_options_field_id);
mqtt5_client_options_properties.metrics_enabled_field_id =
(*env)->GetFieldID(env, mqtt5_client_options_properties.client_options_class, "metricsEnabled", "Z");
AWS_FATAL_ASSERT(mqtt5_client_options_properties.metrics_enabled_field_id);
mqtt5_client_options_properties.iot_device_sdk_metrics_field_id = (*env)->GetFieldID(
env,
mqtt5_client_options_properties.client_options_class,
"iotDeviceSDKMetrics",
"Lsoftware/amazon/awssdk/crt/internal/IoTDeviceSDKMetrics;");
AWS_FATAL_ASSERT(mqtt5_client_options_properties.iot_device_sdk_metrics_field_id);
}

struct java_aws_mqtt5_topic_aliasing_options_properties mqtt5_topic_aliasing_options_properties;
Expand Down Expand Up @@ -2635,6 +2644,19 @@ static void s_cache_cognito_credentials_provider(JNIEnv *env) {
AWS_FATAL_ASSERT(cognito_credentials_provider_properties.create_chained_future_method_id != NULL);
}

struct java_iot_device_sdk_metrics_properties iot_device_sdk_metrics_properties;

static void s_cache_iot_device_sdk_metrics(JNIEnv *env) {
jclass cls = (*env)->FindClass(env, "software/amazon/awssdk/crt/internal/IoTDeviceSDKMetrics");
AWS_FATAL_ASSERT(cls);
iot_device_sdk_metrics_properties.iot_device_sdk_metrics_class = (*env)->NewGlobalRef(env, cls);
AWS_FATAL_ASSERT(iot_device_sdk_metrics_properties.iot_device_sdk_metrics_class);

iot_device_sdk_metrics_properties.library_name_field_id = (*env)->GetFieldID(
env, iot_device_sdk_metrics_properties.iot_device_sdk_metrics_class, "libraryName", "Ljava/lang/String;");
AWS_FATAL_ASSERT(iot_device_sdk_metrics_properties.library_name_field_id);
}

// Update jni-config.json when adding or modifying JNI classes for GraalVM support.
static void s_cache_java_class_ids(void *user_data) {
JNIEnv *env = user_data;
Expand Down Expand Up @@ -2752,6 +2774,7 @@ static void s_cache_java_class_ids(void *user_data) {
s_cache_consumer_properties(env);
s_cache_cognito_login_token_source(env);
s_cache_cognito_credentials_provider(env);
s_cache_iot_device_sdk_metrics(env);
}

static aws_thread_once s_cache_once_init = AWS_THREAD_ONCE_STATIC_INIT;
Expand Down
9 changes: 9 additions & 0 deletions src/native/java_class_ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,8 @@ struct java_aws_mqtt5_client_options_properties {
jfieldID publish_events_field_id;
jfieldID lifecycle_events_field_id;
jfieldID topic_aliasing_options_field_id;
jfieldID metrics_enabled_field_id;
jfieldID iot_device_sdk_metrics_field_id;
};
extern struct java_aws_mqtt5_client_options_properties mqtt5_client_options_properties;

Expand Down Expand Up @@ -1107,6 +1109,13 @@ struct java_cognito_credentials_provider_properties {

extern struct java_cognito_credentials_provider_properties cognito_credentials_provider_properties;

/* IoTDeviceSDKMetrics */
struct java_iot_device_sdk_metrics_properties {
jclass iot_device_sdk_metrics_class;
jfieldID library_name_field_id;
};
extern struct java_iot_device_sdk_metrics_properties iot_device_sdk_metrics_properties;

/**
* All functions bound to JNI MUST call this before doing anything else.
* This caches all JNI IDs the first time it is called. Any further calls are no-op; it is thread-safe.
Expand Down
Loading