From 16f66c2e68ff9d89363e9aca850ff856cb49f456 Mon Sep 17 00:00:00 2001 From: Rakshil Modi Date: Wed, 9 Sep 2026 10:00:17 -0700 Subject: [PATCH 1/4] updating v2 client --- .github/workflows/ci.yml | 4 +- documents/MIGRATION_GUIDE.md | 140 +++++++++++++++-------------------- 2 files changed, 60 insertions(+), 84 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bd93b957..45380f19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: - 'docs' env: - BUILDER_VERSION: v0.9.95 + BUILDER_VERSION: latest BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-iot-device-sdk-java-v2 @@ -263,7 +263,7 @@ jobs: cd sdk/tests/android/testapp/src/main/assets python3 -m pip install boto3 python3 ./android_file_creation.py - + - name: Set Android keystore home run: | echo "ANDROID_SDK_HOME=$GITHUB_WORKSPACE/.android-home" >> "$GITHUB_ENV" diff --git a/documents/MIGRATION_GUIDE.md b/documents/MIGRATION_GUIDE.md index b83a6d9c..22a0328a 100644 --- a/documents/MIGRATION_GUIDE.md +++ b/documents/MIGRATION_GUIDE.md @@ -677,13 +677,13 @@ provides access to thing shadows (sometimes referred to as device shadows). It a which allows developers to exchange data with their shadows by just using `getter` and `setter` methods without having to serialize or deserialize any JSON documents. -The v2 SDK also supports device shadow service, but with completely different APIs. -First, you subscribe to special topics to get data and feedback from a service. The service client provides API for that. -For example, `SubscribeToGetShadowAccepted` subscribes to a topic to which AWS IoT Core will publish a shadow document. The server will notify you if it cannot send you a requested document via `SubscribeToGetShadowRejected`.\ -After subscribing to all the required topics, the service client can start interacting with the server, for example, update -the status or request for data. These actions are also performed via client API calls. For example, `PublishGetShadow` -sends a request to AWS IoT Core to get a shadow document. The requested shadow document will be received in a callback -specified in the `SubscribeToGetShadowAccepted` call. +The v2 SDK also supports the device shadow service, but with completely different APIs. +The v2 service client exposes a request-response API: each operation (for example, `getShadow` or `updateShadow`) +is a single method call that returns a `CompletableFuture` completing with the modeled response, or completing +exceptionally with a `V2ErrorResponseException` that carries the modeled error. The client handles the underlying +MQTT topic subscriptions for you, so you no longer subscribe to accepted/rejected topics manually. +For change notifications that are not tied to a specific request (for example, `ShadowUpdated` and `ShadowDeltaUpdated` +events), the client provides streaming operations that you open once and receive events from continuously. AWS IoT Core [documentation for Device Shadow](https://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-mqtt.html) service provides detailed descriptions for the topics used to interact with the service. @@ -723,10 +723,18 @@ MyDevice device = new MyDevice(thingName); A thing name in v2 SDK shadow client is specified for the operations with shadow documents. +The v2 SDK shadow client is created directly from an MQTT5 client using `IotShadowV2Client.newFromMqtt5`. + ```java -MqttClientConnection connection = new MqttClientConnection(mqtt5Client, null); -shadowClient = new IotShadowClient(connection); mqtt5Client.start(); + +MqttRequestResponseClientOptions rrClientOptions = MqttRequestResponseClientOptions.builder() + .withMaxRequestResponseSubscriptions(5) + .withMaxStreamingSubscriptions(2) + .withOperationTimeoutSeconds(30) + .build(); + +IotShadowV2Client shadowClient = IotShadowV2Client.newFromMqtt5(mqtt5Client, rrClientOptions); ``` #### Example of getting a shadow document in the v1 SDK @@ -773,41 +781,22 @@ String state = device.getSomeValue(); #### Example of getting a shadow document in the v2 SDK ```java -static void onGetShadowAccepted(GetShadowResponse response) { - // Called when a get request succeeded. - // The `response` object contains the shadow document. -} - -static void onGetShadowRejected(ErrorResponse response) { - // Called when a get request failed. -} - -GetShadowSubscriptionRequest requestGetShadow = new GetShadowSubscriptionRequest(); -requestGetShadow.thingName = ""; - -// Subscribe to the topic providing shadow documents. -CompletableFuture accepted = shadowClient.SubscribeToGetShadowAccepted( - requestGetShadow, - QualityOfService.AT_LEAST_ONCE, - onGetShadowAccepted); -// Subscribe to the topic reporting errors. -CompletableFuture rejected = shadowClient.SubscribeToGetShadowRejected( - requestGetShadow, - QualityOfService.AT_LEAST_ONCE, - onGetShadowRejected); - -accepted.get(); -rejected.get(); - -// Send request for a shadow document. -// On success, the document will be received on `onGetShadowAccepted` callback. -// On failure, the `onGetShadowRejected` callback will be called. +// The v2 service client uses a request-response API: a single call sends the +// request and returns a future that completes with the modeled response. GetShadowRequest getShadowRequest = new GetShadowRequest(); getShadowRequest.thingName = ""; -CompletableFuture published = shadowClient.PublishGetShadow( - getShadowRequest, - QualityOfService.AT_LEAST_ONCE); -published.get(); + +try { + GetShadowResponse response = shadowClient.getShadow(getShadowRequest).get(); + // On success, the `response` object contains the shadow document. +} catch (ExecutionException ex) { + // On failure, the cause is a V2ErrorResponseException carrying the modeled error. + Throwable cause = ex.getCause(); + if (cause instanceof V2ErrorResponseException) { + V2ErrorResponseException v2Error = (V2ErrorResponseException) cause; + // v2Error.getModeledError() contains the error details. + } +} ``` #### Example of updating a shadow document in the v1 SDK @@ -826,32 +815,8 @@ device.setSomeValue("{\"state\":{\"reported\":{\"sensor\":3.0}}}"); #### Example of updating a shadow document in the v2 SDK ```java -static void onUpdateShadowAccepted(UpdateShadowResponse response) { - // Called when an update request succeeded. -} - -static void onUpdateShadowRejected(ErrorResponse response) { - // Called when an update request failed. -} - -UpdateShadowSubscriptionRequest requestUpdateShadow = new UpdateShadowSubscriptionRequest(); -requestUpdateShadow.thingName = ""; - -// Subscribe to update responses. -CompletableFuture accepted = shadowClient.SubscribeToUpdateShadowAccepted( - requestUpdateShadow, - QualityOfService.AT_LEAST_ONCE, - onUpdateShadowAccepted); - -// Subscribe to the topic reporting errors. -CompletableFuture rejected = shadowClient.SubscribeToUpdateShadowRejected( - requestUpdateShadow, - QualityOfService.AT_LEAST_ONCE, - onUpdateShadowRejected); -accepted.get(); -rejected.get(); - -// Update shadow document +// The v2 service client uses a request-response API: a single call sends the +// update and returns a future that completes with the modeled response. UpdateShadowRequest request = new UpdateShadowRequest(); request.thingName = ""; request.state = new ShadowState(); @@ -859,13 +824,24 @@ request.state.reported = new HashMap() { { put("sensor", 3.0); } +}; + +try { + UpdateShadowResponse response = shadowClient.updateShadow(request).get(); + // On success, `response` contains the accepted update. +} catch (ExecutionException ex) { + // On failure, the cause is a V2ErrorResponseException carrying the modeled error. + Throwable cause = ex.getCause(); + if (cause instanceof V2ErrorResponseException) { + V2ErrorResponseException v2Error = (V2ErrorResponseException) cause; + // v2Error.getModeledError() contains the error details. + } } -shadowClient.PublishUpdateShadow(request, QualityOfService.AT_LEAST_ONCE); ``` -For more information, see API documentation for the v2 SDK [Device Shadow](https://aws.github.io/aws-iot-device-sdk-java-v2/software/amazon/awssdk/iot/iotshadow/IotShadowClient.html). +For more information, see API documentation for the v2 SDK [Device Shadow](https://aws.github.io/aws-iot-device-sdk-java-v2/software/amazon/awssdk/iot/iotshadow/IotShadowV2Client.html). -For code examples, see the v2 SDK [Device Shadow](https://github.com/aws/aws-iot-device-sdk-java-v2/tree/main/samples/Shadow). +For code examples, see the v2 SDK [Device Shadow](https://github.com/aws/aws-iot-device-sdk-java-v2/tree/main/samples/ServiceClients/ShadowSandbox). ### Client for AWS IoT Jobs @@ -873,16 +849,16 @@ The v2 SDK expands support of AWS IoT Core services implementing a service clien service. The Jobs service helps with defining a set of remote operations that can be sent to and run on one or more devices connected to AWS IoT. -The Jobs service client provides API similar to API provided by [Client for AWS IoT Device Shadow](#client-for-device-shadow-service). -First, you subscribe to special topics to get data and feedback from a service. The service client provides API for that. -After subscribing to all the required topics, the service client can start interacting with the server, for example, update -the status or request for data. These actions are also performed via client API calls. +The Jobs service client provides an API similar to the API provided by [Client for AWS IoT Device Shadow](#client-for-device-shadow-service). +It exposes a request-response API where each operation is a single method call returning a `CompletableFuture`, and the +client manages the underlying MQTT topic subscriptions for you. Notifications that are not tied to a specific request are +delivered through streaming operations. For detailed descriptions for the topics used to interact with the Jobs service, see AWS IoT Core documentation for the [Jobs](https://docs.aws.amazon.com/iot/latest/developerguide/jobs-mqtt-api.html) service. -For more information about the service clients, see API documentation for the v2 SDK [Jobs](https://aws.github.io/aws-iot-device-sdk-java-v2/software/amazon/awssdk/iot/iotjobs/IotJobsClient.html). +For more information about the service clients, see API documentation for the v2 SDK [Jobs](https://aws.github.io/aws-iot-device-sdk-java-v2/software/amazon/awssdk/iot/iotjobs/IotJobsV2Client.html). -For code example, see the v2 SDK [Jobs](https://github.com/aws/aws-iot-device-sdk-java-v2/tree/main/samples/Jobs) samples. +For code example, see the v2 SDK [Jobs](https://github.com/aws/aws-iot-device-sdk-java-v2/tree/main/samples/ServiceClients/JobsSandbox) samples. ### Client for AWS IoT fleet provisioning @@ -891,15 +867,15 @@ For code example, see the v2 SDK [Jobs](https://github.com/aws/aws-iot-device-sd certificates and private keys to your devices when they connect to AWS IoT for the first time. The fleet provisioning service client provides an API similar to the APIs provided by [Client for AWS IoT Device Shadow](#client-for-device-shadow-service). -First, you subscribe to special topics to get data and feedback from a service. The service client provides API for that. -After subscribing to all the required topics, the service client can start interacting with the server, for example, update -the status or request for data. These actions are also performed via client API calls. +It exposes a request-response API where each operation is a single method call returning a `CompletableFuture`, and the +client manages the underlying MQTT topic subscriptions for you. Notifications that are not tied to a specific request are +delivered through streaming operations. For detailed descriptions for the topics used to interact with the Fleet Provisioning service, see AWS IoT Core documentation for [Fleet Provisioning](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html). -For more information about the Fleet Provisioning service client, see API documentation for the v2 SDK [Fleet Provisioning](https://aws.github.io/aws-iot-device-sdk-java-v2/software/amazon/awssdk/iot/iotidentity/IotIdentityClient.html). +For more information about the Fleet Provisioning service client, see API documentation for the v2 SDK [Fleet Provisioning](https://aws.github.io/aws-iot-device-sdk-java-v2/software/amazon/awssdk/iot/iotidentity/IotIdentityV2Client.html). -For code examples, see the v2 SDK [Fleet Provisioning](https://github.com/aws/aws-iot-device-sdk-java-v2/tree/main/samples/FleetProvisioning) +For code examples, see the v2 SDK [Fleet Provisioning](https://github.com/aws/aws-iot-device-sdk-java-v2/tree/main/samples/ServiceClients/Provisioning/Basic) samples. ### Example From 3968314a5629aa51f5c47d1ba9ed24d5f6cb71bc Mon Sep 17 00:00:00 2001 From: Rakshil Modi Date: Wed, 9 Sep 2026 10:17:28 -0700 Subject: [PATCH 2/4] making builde consistent --- documents/MIGRATION_GUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documents/MIGRATION_GUIDE.md b/documents/MIGRATION_GUIDE.md index 22a0328a..86875a81 100644 --- a/documents/MIGRATION_GUIDE.md +++ b/documents/MIGRATION_GUIDE.md @@ -149,7 +149,7 @@ client.connect(); #### Example of connecting to a server in the v2 SDK ```java -Mqtt5Client client = clientBuilder.build(); +Mqtt5Client client = builder.build(); client.start(); ``` From c88f72d46e6361bc67f9f9303523ddb6eaf65ded Mon Sep 17 00:00:00 2001 From: Rakshil Modi Date: Wed, 9 Sep 2026 11:24:19 -0700 Subject: [PATCH 3/4] reworded comments --- documents/MIGRATION_GUIDE.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/documents/MIGRATION_GUIDE.md b/documents/MIGRATION_GUIDE.md index 86875a81..a820e67b 100644 --- a/documents/MIGRATION_GUIDE.md +++ b/documents/MIGRATION_GUIDE.md @@ -5,7 +5,7 @@ such as improved consistency, ease of use, more detailed information about clien control. This guide describes the major features that are new in the v2 SDK, and provides guidance on how to migrate your code to v2 from v1 of the AWS IoT SDK for Java. -> [!NOTE] +> [!NOTE] > If you can't find the information you need in this guide, visit the [How to get help](#how-to-get-help) section for more help and guidance. * [What's new in AWS IoT Device SDK for Java v2](#whats-new-in-aws-iot-device-sdk-for-java-v2) @@ -287,7 +287,7 @@ class MyLifecycleEvents implements Mqtt5ClientOptions.LifecycleEvents { @Override public void onConnectionSuccess(Mqtt5Client client, OnConnectionSuccessReturn onConnectionSuccessReturn) { } - + @Override public void onConnectionFailure(Mqtt5Client client, OnConnectionFailureReturn onConnectionFailureReturn) { } @@ -398,7 +398,7 @@ to. With this callback, you can process messages made to subscribed topics. #### Example of subscribing in the v1 SDK ```java -public class MyTopic extends AWSIotTopic { +public class MyTopic extends AWSIotTopic { public MyTopic(String topic, AWSIotQos qos) { super(topic, qos); } @@ -467,7 +467,7 @@ client.unsubscribe("another/topic"); ```java // Non-blocking API. -public class MyTopic extends AWSIotTopic { +public class MyTopic extends AWSIotTopic { public MyTopic(String topic, AWSIotQos qos) { super(topic, qos); } @@ -476,7 +476,7 @@ public class MyTopic extends AWSIotTopic { public void onSuccess() { // Called when unsubscribing succeeds. } - + @Override public void onFailure() { // Called when unsubscribing fails. @@ -590,7 +590,7 @@ builder.withOfflineQueueBehavior(ClientOfflineQueueBehavior.FAIL_QOS0_PUBLISH_ON Mqtt5Client client = builder.build(); ``` -> [!NOTE] +> [!NOTE] > AWS IoT Core [limits the number of allowed operations per second](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#message-broker-limits). The [`getOperationStatistics`](https://awslabs.github.io/aws-crt-java/software/amazon/awssdk/crt/mqtt5/Mqtt5Client.html#getOperationStatistics()) method returns the current state of an `Mqtt5Client` object's queue of operations, which may help with tracking the number @@ -679,7 +679,7 @@ or deserialize any JSON documents. The v2 SDK also supports the device shadow service, but with completely different APIs. The v2 service client exposes a request-response API: each operation (for example, `getShadow` or `updateShadow`) -is a single method call that returns a `CompletableFuture` completing with the modeled response, or completing +is a single method call that returns a `CompletableFuture`. On operation success, this future is completed with the modeled response, while on operation failure, it is completed exceptionally with a `V2ErrorResponseException` that carries the modeled error. The client handles the underlying MQTT topic subscriptions for you, so you no longer subscribe to accepted/rejected topics manually. For change notifications that are not tied to a specific request (for example, `ShadowUpdated` and `ShadowDeltaUpdated` @@ -930,7 +930,7 @@ class. Publishers can request a response be sent by the receiver to a publisher-specified topic upon reception. Use [withResponseTopic](https://awslabs.github.io/aws-crt-java/software/amazon/awssdk/crt/mqtt5/packets/PublishPacket.PublishPacketBuilder.html#withResponseTopic(java.lang.String)) method in the `PublishPacketBuilder` class. **Maximum Packet Size**\ -Client and Server can independently specify the maximum packet size that they support. For more information, see the [connectPacketBuilder.withMaximumPacketSizeBytes](https://awslabs.github.io/aws-crt-java/software/amazon/awssdk/crt/mqtt5/packets/ConnectPacket.ConnectPacketBuilder.html#withMaximumPacketSizeBytes(java.lang.Long)), the +Client and Server can independently specify the maximum packet size that they support. For more information, see the [connectPacketBuilder.withMaximumPacketSizeBytes](https://awslabs.github.io/aws-crt-java/software/amazon/awssdk/crt/mqtt5/packets/ConnectPacket.ConnectPacketBuilder.html#withMaximumPacketSizeBytes(java.lang.Long)), the [NegotiatedSettings.getMaximumPacketSizeToServer](https://awslabs.github.io/aws-crt-java/software/amazon/awssdk/crt/mqtt5/NegotiatedSettings.html#getMaximumPacketSizeToServer()), and the [ConnAckPacket.getMaximumPacketSize](https://awslabs.github.io/aws-crt-java/software/amazon/awssdk/crt/mqtt5/packets/ConnAckPacket.html#getMaximumPacketSize()) methods. @@ -943,5 +943,5 @@ method in the `PublishPacketBuilder` class. Shared Subscriptions allow multiple clients to share a subscription to a topic and only one client will receive messages published to that topic using a random distribution. -> [!NOTE] +> [!NOTE] > AWS IoT Core supports Shared Subscriptions for both MQTT3 and MQTT5. For more information, see [Shared Subscriptions](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html#mqtt5-shared-subscription) from the AWS IoT Core developer guide. From e2964f094c6222bd728c6441ae9056f9b5839a8a Mon Sep 17 00:00:00 2001 From: Rakshil Modi Date: Wed, 9 Sep 2026 14:50:22 -0700 Subject: [PATCH 4/4] Generated files --- .../amazon/awssdk/iot/iotidentity/IotIdentityClient.java | 2 +- .../software/amazon/awssdk/iot/iotjobs/IotJobsClient.java | 4 ++-- .../software/amazon/awssdk/iot/iotshadow/IotShadowClient.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/src/main/java/software/amazon/awssdk/iot/iotidentity/IotIdentityClient.java b/sdk/src/main/java/software/amazon/awssdk/iot/iotidentity/IotIdentityClient.java index cde478b0..33dc073b 100644 --- a/sdk/src/main/java/software/amazon/awssdk/iot/iotidentity/IotIdentityClient.java +++ b/sdk/src/main/java/software/amazon/awssdk/iot/iotidentity/IotIdentityClient.java @@ -40,7 +40,7 @@ /** *

Deprecated. We strongly recommend using {@link software.amazon.awssdk.iot.iotidentity.IotIdentityV2Client }.

* - *

There are no current plans to ully deprecate IotIdentityClient but it is highly recommended customers + *

There are no current plans to fully deprecate IotIdentityClient but it is highly recommended customers * migrate to IotIdentityV2Client. More details can be found in the GitHub Repo FAQ.

* * An AWS IoT service that assists with provisioning a device and installing unique client certificates on it diff --git a/sdk/src/main/java/software/amazon/awssdk/iot/iotjobs/IotJobsClient.java b/sdk/src/main/java/software/amazon/awssdk/iot/iotjobs/IotJobsClient.java index 02583ec7..46ebf071 100644 --- a/sdk/src/main/java/software/amazon/awssdk/iot/iotjobs/IotJobsClient.java +++ b/sdk/src/main/java/software/amazon/awssdk/iot/iotjobs/IotJobsClient.java @@ -52,7 +52,7 @@ /** *

Deprecated. We strongly recommend using {@link software.amazon.awssdk.iot.iotjobs.IotJobsV2Client }.

* - *

There are no current plans to ully deprecate IotJobsClient but it is highly recommended customers + *

There are no current plans to fully deprecate IotJobsClient but it is highly recommended customers * migrate to IotJobsV2Client. More details can be found in the GitHub Repo FAQ.

* * The AWS IoT jobs service can be used to define a set of remote operations that are sent to and executed on one or more devices connected to AWS IoT. @@ -83,8 +83,8 @@ private Gson getGson() { } private void addTypeAdapters(GsonBuilder gson) { - gson.registerTypeAdapter(JobStatus.class, new EnumSerializer()); gson.registerTypeAdapter(RejectedErrorCode.class, new EnumSerializer()); + gson.registerTypeAdapter(JobStatus.class, new EnumSerializer()); } /** diff --git a/sdk/src/main/java/software/amazon/awssdk/iot/iotshadow/IotShadowClient.java b/sdk/src/main/java/software/amazon/awssdk/iot/iotshadow/IotShadowClient.java index 03f64a85..586434c5 100644 --- a/sdk/src/main/java/software/amazon/awssdk/iot/iotshadow/IotShadowClient.java +++ b/sdk/src/main/java/software/amazon/awssdk/iot/iotshadow/IotShadowClient.java @@ -58,7 +58,7 @@ /** *

Deprecated. We strongly recommend using {@link software.amazon.awssdk.iot.iotshadow.IotShadowV2Client }.

* - *

There are no current plans to ully deprecate IotShadowClient but it is highly recommended customers + *

There are no current plans to fully deprecate IotShadowClient but it is highly recommended customers * migrate to IotShadowV2Client. More details can be found in the GitHub Repo FAQ.

* * The AWS IoT Device Shadow service adds shadows to AWS IoT thing objects. Shadows are a simple data store for device properties and state. Shadows can make a device’s state available to apps and other services whether the device is connected to AWS IoT or not.