4141/**
4242 * Builders for making MQTT5 clients with different connection methods for AWS IoT Core.
4343 */
44- public class AwsIotMqtt5ClientBuilder extends software . amazon . awssdk . crt . CrtResource {
44+ public class AwsIotMqtt5ClientBuilder implements AutoCloseable {
4545 private static Long DEFAULT_WEBSOCKET_MQTT_PORT = 443L ;
4646 private static Long DEFAULT_DIRECT_MQTT_PORT = 8883L ;
4747 private static Long DEFAULT_KEEP_ALIVE = 1200L ;
@@ -51,20 +51,14 @@ public class AwsIotMqtt5ClientBuilder extends software.amazon.awssdk.crt.CrtReso
5151 private TlsContextOptions configTls ;
5252 private MqttConnectCustomAuthConfig configCustomAuth ;
5353
54- private AwsIotMqtt5ClientBuilder (String hostName , Long port , TlsContextOptions tlsContext ) {
54+ private AwsIotMqtt5ClientBuilder (String hostName , Long port , TlsContextOptions tlsContextOptions ) {
5555 config = new Mqtt5ClientOptionsBuilder (hostName , port );
56- configTls = tlsContext ;
56+ configTls = tlsContextOptions ;
5757 configConnect = new ConnectPacketBuilder ();
5858 configConnect .withKeepAliveIntervalSeconds (DEFAULT_KEEP_ALIVE );
5959 config .withExtendedValidationAndFlowControlOptions (Mqtt5ClientOptions .ExtendedValidationAndFlowControlOptions .AWS_IOT_CORE_DEFAULTS );
60- addReferenceTo (configTls );
6160 }
6261
63- protected boolean canReleaseReferencesImmediately () {
64- return true ;
65- }
66- protected void releaseNativeHandle () {}
67-
6862 /**
6963 * Creates a new MQTT5 client builder with mTLS file paths.
7064 *
@@ -76,7 +70,6 @@ protected void releaseNativeHandle() {}
7670 public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromPath (String hostName , String certificatePath , String privateKeyPath ) {
7771 TlsContextOptions options = TlsContextOptions .createWithMtlsFromPath (certificatePath , privateKeyPath );
7872 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
79- options .close ();
8073 if (TlsContextOptions .isAlpnSupported ()) {
8174 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
8275 }
@@ -94,7 +87,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromPath(Stri
9487 public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromMemory (String hostName , String certificate , String privateKey ) {
9588 TlsContextOptions options = TlsContextOptions .createWithMtls (certificate , privateKey );
9689 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
97- options .close ();
9890 if (TlsContextOptions .isAlpnSupported ()) {
9991 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
10092 }
@@ -113,7 +105,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromMemory(St
113105 public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromPkcs11 (String hostName , TlsContextPkcs11Options pkcs11Options ) {
114106 TlsContextOptions options = TlsContextOptions .createWithMtlsPkcs11 (pkcs11Options );
115107 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
116- options .close ();
117108 if (TlsContextOptions .isAlpnSupported ()) {
118109 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
119110 }
@@ -132,7 +123,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromPkcs11(St
132123 public static AwsIotMqtt5ClientBuilder newDirectMtlsCustomKeyOperationsBuilder (String hostName , TlsContextCustomKeyOperationOptions operationOptions ) {
133124 TlsContextOptions options = TlsContextOptions .createWithMtlsCustomKeyOperations (operationOptions );
134125 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
135- options .close ();
136126 if (TlsContextOptions .isAlpnSupported ()) {
137127 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
138128 }
@@ -153,7 +143,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMtlsCustomKeyOperationsBuilder(S
153143 public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromWindowsCertStorePath (String hostName , String certificatePath ) {
154144 TlsContextOptions options = TlsContextOptions .createWithMtlsWindowsCertStorePath (certificatePath );
155145 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
156- options .close ();
157146 if (TlsContextOptions .isAlpnSupported ()) {
158147 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
159148 }
@@ -175,7 +164,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithCustomAuth(String
175164
176165 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_WEBSOCKET_MQTT_PORT , options );
177166 builder .configCustomAuth = customAuthConfig ;
178- options .close ();
179167
180168 return builder ;
181169 }
@@ -210,7 +198,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromPkcs11(St
210198 public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithMtlsFromPkcs12 (String hostName , String pkcs12Path , String pkcs12Password ) {
211199 TlsContextOptions options = TlsContextOptions .createWithMtlsPkcs12 (pkcs12Path , pkcs12Password );
212200 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
213- options .close ();
214201 if (TlsContextOptions .isAlpnSupported ()) {
215202 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
216203 }
@@ -230,7 +217,6 @@ public static AwsIotMqtt5ClientBuilder newWebsocketMqttBuilderWithSigv4Auth(Stri
230217 options .alpnList .clear ();
231218
232219 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_WEBSOCKET_MQTT_PORT , options );
233- options .close ();
234220
235221 CredentialsProvider provider = null ;
236222 if (config != null ) {
@@ -295,7 +281,6 @@ public static AwsIotMqtt5ClientBuilder newWebsocketMqttBuilderWithCustomAuth(Str
295281
296282 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_WEBSOCKET_MQTT_PORT , options );
297283 builder .configCustomAuth = customAuthConfig ;
298- options .close ();
299284
300285 Consumer <Mqtt5WebsocketHandshakeTransformArgs > websocketTransform = new Consumer <Mqtt5WebsocketHandshakeTransformArgs >() {
301286 @ Override
@@ -324,7 +309,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithJavaKeystore(
324309 String hostName , java .security .KeyStore keyStore , String certificateAlias , String certificatePassword ) {
325310 TlsContextOptions options = TlsContextOptions .createWithMtlsJavaKeystore (keyStore , certificateAlias , certificatePassword );
326311 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
327- options .close ();
328312 if (TlsContextOptions .isAlpnSupported ()) {
329313 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
330314 }
@@ -341,7 +325,6 @@ public static AwsIotMqtt5ClientBuilder newDirectMqttBuilderWithJavaKeystore(
341325 public static AwsIotMqtt5ClientBuilder newMqttBuilder (String hostName ) {
342326 TlsContextOptions options = TlsContextOptions .createDefaultClient ();
343327 AwsIotMqtt5ClientBuilder builder = new AwsIotMqtt5ClientBuilder (hostName , DEFAULT_DIRECT_MQTT_PORT , options );
344- options .close ();
345328 if (TlsContextOptions .isAlpnSupported ()) {
346329 builder .configTls .withAlpnList ("x-amzn-mqtt-ca" );
347330 }
@@ -843,13 +826,9 @@ public AwsIotMqtt5ClientBuilder withUserProperties(List<UserProperty> userProper
843826 public Mqtt5Client build () {
844827 if (this .configTls == null ) {
845828 this .configTls = TlsContextOptions .createDefaultClient ();
846- addReferenceTo (this .configTls );
847- this .configTls .close ();
848829 }
849830 TlsContext tlsContext = new TlsContext (this .configTls );
850831 this .config .withTlsContext (tlsContext );
851- addReferenceTo (tlsContext );
852- tlsContext .close ();
853832
854833 try {
855834 this .configConnect .withUsername (buildMqtt5FinalUsername (this .configCustomAuth ));
@@ -868,8 +847,14 @@ public Mqtt5Client build() {
868847
869848 Mqtt5Client returnClient = new Mqtt5Client (this .config .build ());
870849
871- // Keep a reference to the TLS configuration so any possible Websockets-related CrtResources are kept alive
850+ // Have the Mqtt5 Client hold a reference to the TlsContextOptions so any possible
851+ // Websockets-related CrtResources are kept alive.
872852 returnClient .addReferenceTo (this .configTls );
853+
854+ // remove the ref of TlsContext that was added upon creation within the builder
855+ // Their lifetime will be under control of the Mqtt5Client outside of the builder.
856+ tlsContext .close ();
857+
873858 return returnClient ;
874859 }
875860
@@ -1127,4 +1112,16 @@ private String buildMqtt5FinalUsername(MqttConnectCustomAuthConfig config) throw
11271112
11281113 return formUsernameFromParam (paramList );
11291114 }
1115+
1116+ /**
1117+ * Clear the ref held by the builder on the TlsContextOptions. We don't clear it on build()
1118+ * as it may be reused to create multiple Clients, each of which will retain its own ref on
1119+ * the TlsContextOptions.
1120+ */
1121+ @ Override
1122+ public void close (){
1123+ if (this .configTls != null ) {
1124+ this .configTls .close ();
1125+ }
1126+ }
11301127}
0 commit comments