1414import java .util .TreeSet ;
1515import java .util .Map ;
1616import java .util .HashMap ;
17- import java .util .concurrent .ConcurrentHashMap ;
17+ import java .util .concurrent .* ;
1818
1919class AadInstanceDiscoveryProvider {
2020
@@ -31,6 +31,8 @@ class AadInstanceDiscoveryProvider {
3131 private static final String DEFAULT_API_VERSION = "2020-06-01" ;
3232 private static final String IMDS_ENDPOINT = "https://169.254.169.254/metadata/instance/compute/location?" + DEFAULT_API_VERSION + "&format=text" ;
3333
34+ private static final int IMDS_TIMEOUT = 2 ;
35+ private static final TimeUnit IMDS_TIMEOUT_UNIT = TimeUnit .SECONDS ;
3436 static final TreeSet <String > TRUSTED_HOSTS_SET = new TreeSet <>(String .CASE_INSENSITIVE_ORDER );
3537 static final TreeSet <String > TRUSTED_SOVEREIGN_HOSTS_SET = new TreeSet <>(String .CASE_INSENSITIVE_ORDER );
3638
@@ -71,8 +73,8 @@ static InstanceDiscoveryMetadataEntry getMetadataEntry(URL authorityUrl,
7173 //If region autodetection is enabled and a specific region not already set,
7274 // set the application's region to the discovered region so that future requests can skip the IMDS endpoint call
7375 if (null == msalRequest .application ().azureRegion () && msalRequest .application ().autoDetectRegion ()
74- && null != detectedRegion ) {
75- msalRequest .application ().azureRegion = detectedRegion ;
76+ && null != detectedRegion ) {
77+ msalRequest .application ().azureRegion = detectedRegion ;
7678 }
7779 cacheRegionInstanceMetadata (authorityUrl .getHost (), msalRequest .application ().azureRegion ());
7880 serviceBundle .getServerSideTelemetry ().getCurrentRequest ().regionOutcome (
@@ -291,33 +293,39 @@ private static String discoverRegion(MsalRequest msalRequest, ServiceBundle serv
291293 return System .getenv (REGION_NAME );
292294 }
293295
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 ));
299302
303+ try {
304+ log .info ("Starting call to IMDS endpoint." );
305+ IHttpResponse httpResponse = future .get (IMDS_TIMEOUT , IMDS_TIMEOUT_UNIT );
300306 //If call to IMDS endpoint was successful, return region from response body
301307 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 () ));
303309 currentRequest .regionSource (RegionTelemetry .REGION_SOURCE_IMDS .telemetryValue );
304310
305311 return httpResponse .body ();
306312 }
307-
308313 log .warn (String .format ("Call to local IMDS failed with status code: %s, or response was empty" , httpResponse .statusCode ()));
309314 currentRequest .regionSource (RegionTelemetry .REGION_SOURCE_FAILED_AUTODETECT .telemetryValue );
310-
311- return null ;
312- } catch (Exception e ) {
315+ } catch (Exception ex ) {
316+ // handle other exceptions
313317 //IMDS call failed, cannot find region
314318 //The IMDS endpoint is only available from within an Azure environment, so the most common cause of this
315319 // 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 ()));
317321 currentRequest .regionSource (RegionTelemetry .REGION_SOURCE_FAILED_AUTODETECT .telemetryValue );
322+ future .cancel (true );
318323
319- return null ;
324+ } finally {
325+ executor .shutdownNow ();
320326 }
327+
328+ return null ;
321329 }
322330
323331 private static void doInstanceDiscoveryAndCache (URL authorityUrl ,
0 commit comments