20
20
import static com .github .tomakehurst .wiremock .client .WireMock .urlMatching ;
21
21
import static com .github .tomakehurst .wiremock .core .WireMockConfiguration .wireMockConfig ;
22
22
import static org .assertj .core .api .Assertions .assertThat ;
23
+ import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
23
24
import static org .assertj .core .api .Assertions .assertThatThrownBy ;
24
25
import static software .amazon .awssdk .utils .JavaSystemSetting .SSL_KEY_STORE ;
25
26
import static software .amazon .awssdk .utils .JavaSystemSetting .SSL_KEY_STORE_PASSWORD ;
56
57
import software .amazon .awssdk .http .SdkHttpRequest ;
57
58
import software .amazon .awssdk .http .TlsKeyManagersProvider ;
58
59
import software .amazon .awssdk .http .apache5 .internal .conn .SdkTlsSocketFactory ;
60
+ import software .amazon .awssdk .http .apache5 .internal .conn .SslSocketFactoryToTlsStrategyAdapter ;
59
61
import software .amazon .awssdk .internal .http .NoneTlsKeyManagersProvider ;
60
62
61
63
/**
@@ -258,26 +260,28 @@ private HttpExecuteResponse makeRequestWithHttpClient(SdkHttpClient httpClient)
258
260
return httpClient .prepareRequest (request ).call ();
259
261
}
260
262
261
-
262
263
@ Test
263
- public void build_settingTlsStrategy_configuresClientWithGivenStrategy () throws Exception {
264
- TlsKeyManagersProvider provider = FileStoreTlsKeyManagersProvider .create (clientKeyStore ,
265
- CLIENT_STORE_TYPE ,
266
- STORE_PASSWORD );
267
- KeyManager [] keyManagers = provider .keyManagers ();
268
-
264
+ public void tls_strategy_configuration () throws Exception {
265
+ // Setup TLS context
266
+ KeyManager [] keyManagers = keyManagersProvider .keyManagers ();
269
267
SSLContext sslContext = SSLContext .getInstance ("TLS" );
270
268
sslContext .init (keyManagers , null , null );
271
269
272
- SdkTlsSocketFactory socketFactory = new SdkTlsSocketFactory (sslContext , NoopHostnameVerifier .INSTANCE );
273
- SdkTlsSocketFactory socketFactorySpy = Mockito .spy (socketFactory );
270
+ // Create and spy on TlsSocketStrategy
271
+ TlsSocketStrategy tlsStrategy = new SdkTlsSocketFactory (sslContext , NoopHostnameVerifier .INSTANCE );
272
+ TlsSocketStrategy tlsStrategySpy = Mockito .spy (tlsStrategy );
274
273
274
+ // Build client with TLS strategy
275
275
client = Apache5HttpClient .builder ()
276
- .tlsSocketStrategy (socketFactorySpy ) // Modern approach
276
+ .tlsSocketStrategy (tlsStrategySpy )
277
277
.build ();
278
- makeRequestWithHttpClient (client );
279
278
280
- Mockito .verify (socketFactorySpy ).upgrade (
279
+ // Make request and verify
280
+ HttpExecuteResponse response = makeRequestWithHttpClient (client );
281
+ assertThat (response .httpResponse ().isSuccessful ()).isTrue ();
282
+
283
+ // Verify upgrade method was called
284
+ Mockito .verify (tlsStrategySpy ).upgrade (
281
285
Mockito .any (Socket .class ),
282
286
Mockito .anyString (),
283
287
Mockito .anyInt (),
@@ -286,36 +290,111 @@ public void build_settingTlsStrategy_configuresClientWithGivenStrategy() throws
286
290
);
287
291
}
288
292
289
-
290
293
@ Test
291
- public void build_settingLegacySocketFactory_configuresClientWithAdapter () throws IOException ,
292
- NoSuchAlgorithmException ,
293
- KeyManagementException {
294
- TlsKeyManagersProvider provider = FileStoreTlsKeyManagersProvider .create (clientKeyStore ,
295
- CLIENT_STORE_TYPE ,
296
- STORE_PASSWORD );
297
- KeyManager [] keyManagers = provider .keyManagers ();
298
-
294
+ public void testTlsStrategyOverridesLegacyFactory () throws Exception {
295
+ // Setup TLS context
296
+ KeyManager [] keyManagers = keyManagersProvider .keyManagers ();
299
297
SSLContext sslContext = SSLContext .getInstance ("TLS" );
300
298
sslContext .init (keyManagers , null , null );
301
299
302
- // Create a legacy SSLConnectionSocketFactory
303
- SSLConnectionSocketFactory legacyFactory = new SSLConnectionSocketFactory (sslContext , NoopHostnameVerifier .INSTANCE );
300
+ // Create spies for both approaches
301
+ SSLConnectionSocketFactory legacyFactory = new SSLConnectionSocketFactory (
302
+ sslContext ,
303
+ NoopHostnameVerifier .INSTANCE
304
+ );
304
305
SSLConnectionSocketFactory legacyFactorySpy = Mockito .spy (legacyFactory );
305
306
307
+ TlsSocketStrategy tlsStrategy = new SdkTlsSocketFactory (
308
+ sslContext ,
309
+ NoopHostnameVerifier .INSTANCE
310
+ );
311
+ TlsSocketStrategy tlsStrategySpy = Mockito .spy (tlsStrategy );
312
+
313
+ // Build client with both - TLS strategy should take precedence
306
314
client = Apache5HttpClient .builder ()
307
- .socketFactory (legacyFactorySpy ) // Legacy approach
315
+ .socketFactory (legacyFactorySpy )
316
+ .tlsSocketStrategy (tlsStrategySpy ) // This should override
308
317
.build ();
309
- makeRequestWithHttpClient (client );
310
318
311
- Mockito .verify (legacyFactorySpy ).createLayeredSocket (
319
+ // Make request
320
+ HttpExecuteResponse response = makeRequestWithHttpClient (client );
321
+ assertThat (response .httpResponse ().isSuccessful ()).isTrue ();
322
+
323
+ // Verify only TLS strategy was used, not legacy
324
+ Mockito .verify (tlsStrategySpy ).upgrade (
312
325
Mockito .any (Socket .class ),
313
326
Mockito .anyString (),
314
327
Mockito .anyInt (),
328
+ Mockito .any (),
315
329
Mockito .any (HttpContext .class )
316
330
);
331
+
332
+ Mockito .verifyNoInteractions (legacyFactorySpy );
333
+ }
334
+
335
+ @ Test
336
+ public void testAdapterConvertsNonSslSocketException () throws Exception {
337
+ // Create mock that returns a regular Socket (not SSLSocket)
338
+ SSLConnectionSocketFactory mockFactory = Mockito .mock (SSLConnectionSocketFactory .class );
339
+ Socket nonSslSocket = Mockito .mock (Socket .class );
340
+
341
+ // Setup mock to return non-SSL socket
342
+ Mockito .when (mockFactory .createLayeredSocket (
343
+ Mockito .any (Socket .class ),
344
+ Mockito .eq ("example.com" ),
345
+ Mockito .eq (443 ),
346
+ Mockito .any ()
347
+ )).thenReturn (nonSslSocket );
348
+
349
+ // Create adapter
350
+ SslSocketFactoryToTlsStrategyAdapter adapter =
351
+ new SslSocketFactoryToTlsStrategyAdapter (mockFactory );
352
+
353
+ // Test should throw IOException
354
+ Socket plainSocket = Mockito .mock (Socket .class );
355
+
356
+ assertThatExceptionOfType (IOException .class )
357
+ .isThrownBy (() -> adapter .upgrade (plainSocket , "example.com" , 443 , null , null ))
358
+ .withMessageContaining ("did not return an SSLSocket" )
359
+ .withMessageContaining (nonSslSocket .getClass ().getName ());
317
360
}
318
361
319
362
363
+ @ Test
364
+ public void testAdapterHandlesNullSocket () throws Exception {
365
+ // Create mock that returns null
366
+ SSLConnectionSocketFactory mockFactory = Mockito .mock (SSLConnectionSocketFactory .class );
367
+
368
+ Mockito .when (mockFactory .createLayeredSocket (
369
+ Mockito .any (Socket .class ),
370
+ Mockito .anyString (),
371
+ Mockito .anyInt (),
372
+ Mockito .any (HttpContext .class )
373
+ )).thenReturn (null );
374
+
375
+ // Create adapter
376
+ SslSocketFactoryToTlsStrategyAdapter adapter =
377
+ new SslSocketFactoryToTlsStrategyAdapter (mockFactory );
378
+
379
+ // Test should throw IOException
380
+ Socket plainSocket = Mockito .mock (Socket .class );
381
+
382
+ assertThatExceptionOfType (IOException .class )
383
+ .isThrownBy (() -> adapter .upgrade (plainSocket , "example.com" , 443 , null , null ))
384
+ .withMessageContaining ("returned null" );
385
+ }
386
+
387
+ @ Test
388
+ public void testNullTlsStrategyFallsBackToDefault () throws Exception {
389
+ // Test that setting tlsSocketStrategy(null) works correctly
390
+ client = Apache5HttpClient .builder ()
391
+ .tlsSocketStrategy (null )
392
+ .tlsKeyManagersProvider (keyManagersProvider )
393
+ .build ();
394
+
395
+ HttpExecuteResponse response = makeRequestWithHttpClient (client );
396
+ assertThat (response .httpResponse ().isSuccessful ()).isTrue ();
397
+ }
398
+
320
399
321
400
}
0 commit comments