14
14
import java .util .TreeSet ;
15
15
import java .util .Map ;
16
16
import java .util .HashMap ;
17
- import java .util .concurrent .ConcurrentHashMap ;
17
+ import java .util .concurrent .* ;
18
18
19
19
class AadInstanceDiscoveryProvider {
20
20
@@ -31,6 +31,8 @@ class AadInstanceDiscoveryProvider {
31
31
private static final String DEFAULT_API_VERSION = "2020-06-01" ;
32
32
private static final String IMDS_ENDPOINT = "https://169.254.169.254/metadata/instance/compute/location?" + DEFAULT_API_VERSION + "&format=text" ;
33
33
34
+ private static final int IMDS_TIMEOUT = 2 ;
35
+ private static final TimeUnit IMDS_TIMEOUT_UNIT = TimeUnit .SECONDS ;
34
36
static final TreeSet <String > TRUSTED_HOSTS_SET = new TreeSet <>(String .CASE_INSENSITIVE_ORDER );
35
37
static final TreeSet <String > TRUSTED_SOVEREIGN_HOSTS_SET = new TreeSet <>(String .CASE_INSENSITIVE_ORDER );
36
38
@@ -71,8 +73,8 @@ static InstanceDiscoveryMetadataEntry getMetadataEntry(URL authorityUrl,
71
73
//If region autodetection is enabled and a specific region not already set,
72
74
// set the application's region to the discovered region so that future requests can skip the IMDS endpoint call
73
75
if (null == msalRequest .application ().azureRegion () && msalRequest .application ().autoDetectRegion ()
74
- && null != detectedRegion ) {
75
- msalRequest .application ().azureRegion = detectedRegion ;
76
+ && null != detectedRegion ) {
77
+ msalRequest .application ().azureRegion = detectedRegion ;
76
78
}
77
79
cacheRegionInstanceMetadata (authorityUrl .getHost (), msalRequest .application ().azureRegion ());
78
80
serviceBundle .getServerSideTelemetry ().getCurrentRequest ().regionOutcome (
@@ -291,33 +293,39 @@ private static String discoverRegion(MsalRequest msalRequest, ServiceBundle serv
291
293
return System .getenv (REGION_NAME );
292
294
}
293
295
294
- try {
295
- //Check the IMDS endpoint to retrieve current region (will only work if application is running in an Azure VM)
296
- Map <String , String > headers = new HashMap <>();
297
- headers .put ("Metadata" , "true" );
298
- IHttpResponse httpResponse = executeRequest (IMDS_ENDPOINT , headers , msalRequest , serviceBundle );
296
+ //Check the IMDS endpoint to retrieve current region (will only work if application is running in an Azure VM)
297
+ Map <String , String > headers = new HashMap <>();
298
+ headers .put ("Metadata" , "true" );
299
+
300
+ ExecutorService executor = Executors .newSingleThreadExecutor ();
301
+ Future <IHttpResponse > future = executor .submit (() -> executeRequest (IMDS_ENDPOINT , headers , msalRequest , serviceBundle ));
299
302
303
+ try {
304
+ log .info ("Starting call to IMDS endpoint." );
305
+ IHttpResponse httpResponse = future .get (IMDS_TIMEOUT , IMDS_TIMEOUT_UNIT );
300
306
//If call to IMDS endpoint was successful, return region from response body
301
307
if (httpResponse .statusCode () == HttpHelper .HTTP_STATUS_200 && !httpResponse .body ().isEmpty ()) {
302
- log .info ("Region retrieved from IMDS endpoint: " + httpResponse .body ());
308
+ log .info (String . format ( "Region retrieved from IMDS endpoint: %s" , httpResponse .body () ));
303
309
currentRequest .regionSource (RegionTelemetry .REGION_SOURCE_IMDS .telemetryValue );
304
310
305
311
return httpResponse .body ();
306
312
}
307
-
308
313
log .warn (String .format ("Call to local IMDS failed with status code: %s, or response was empty" , httpResponse .statusCode ()));
309
314
currentRequest .regionSource (RegionTelemetry .REGION_SOURCE_FAILED_AUTODETECT .telemetryValue );
310
-
311
- return null ;
312
- } catch (Exception e ) {
315
+ } catch (Exception ex ) {
316
+ // handle other exceptions
313
317
//IMDS call failed, cannot find region
314
318
//The IMDS endpoint is only available from within an Azure environment, so the most common cause of this
315
319
// exception will likely be java.net.SocketException: Network is unreachable: connect
316
- log .warn (String .format ("Exception during call to local IMDS endpoint: %s" , e .getMessage ()));
320
+ log .warn (String .format ("Exception during call to local IMDS endpoint: %s" , ex .getMessage ()));
317
321
currentRequest .regionSource (RegionTelemetry .REGION_SOURCE_FAILED_AUTODETECT .telemetryValue );
322
+ future .cancel (true );
318
323
319
- return null ;
324
+ } finally {
325
+ executor .shutdownNow ();
320
326
}
327
+
328
+ return null ;
321
329
}
322
330
323
331
private static void doInstanceDiscoveryAndCache (URL authorityUrl ,
0 commit comments