66import javax .annotation .Nonnull ;
77import javax .annotation .Nullable ;
88
9+ import org .apache .commons .lang3 .reflect .FieldUtils ;
910import org .apache .http .client .HttpClient ;
11+ import org .apache .http .impl .client .CloseableHttpClient ;
12+ import org .apache .http .impl .conn .PoolingHttpClientConnectionManager ;
13+ import org .apache .http .pool .AbstractConnPool ;
1014
1115import com .github .benmanes .caffeine .cache .Cache ;
1216import com .sap .cloud .sdk .cloudplatform .cache .CacheKey ;
1317import com .sap .cloud .sdk .cloudplatform .connectivity .exception .HttpClientInstantiationException ;
1418
1519import io .vavr .control .Try ;
1620import lombok .extern .slf4j .Slf4j ;
21+ import lombok .val ;
1722
1823/**
1924 * Provides caching functionality to the {@code HttpClientAccessor}.
@@ -89,9 +94,16 @@ private Try<HttpClient> tryGetOrCreateHttpClient(
8994 final Cache <CacheKey , HttpClient > cache = maybeCache .get ();
9095 final CacheKey cacheKey = maybeKey .get ();
9196
92- final HttpClient httpClient ;
97+ HttpClient httpClient ;
9398 try {
9499 httpClient = cache .get (cacheKey , anyKey -> createHttpClient .get ());
100+
101+ if ( !isHealthy (httpClient ) ) {
102+ log .warn ("The HttpClient retrieved from the cache has a shutdown connection pool." );
103+ cache .invalidate (cacheKey );
104+ httpClient = cache .get (cacheKey , anyKey -> createHttpClient .get ());
105+ }
106+
95107 Objects
96108 .requireNonNull (
97109 httpClient ,
@@ -109,6 +121,22 @@ private Try<HttpClient> tryGetOrCreateHttpClient(
109121 return Try .success (httpClient );
110122 }
111123
124+ private static boolean isHealthy ( final HttpClient httpClient )
125+ throws IllegalArgumentException ,
126+ NullPointerException
127+ {
128+ try {
129+ val hc = (CloseableHttpClient ) FieldUtils .readField (httpClient , "httpClient" , true );
130+ val cm = (PoolingHttpClientConnectionManager ) FieldUtils .readField (hc , "connManager" , true );
131+ val cp = (AbstractConnPool <?, ?, ?>) FieldUtils .readField (cm , "pool" , true );
132+ return !cp .isShutdown ();
133+ }
134+ catch ( final Exception e ) {
135+ log .warn ("Failed to access connection manager." , e );
136+ return true ;
137+ }
138+ }
139+
112140 /**
113141 * Getter for the cache to be used.
114142 * <p>
0 commit comments