Last active
June 16, 2020 17:43
-
-
Save jkuipers/d4964ea41e2e02409591fc84ce18a77e to your computer and use it in GitHub Desktop.
Ensures unhealthy status in case a PoolingHttpClientConnectionManager is shut down, e.g. as result of OOM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | |
import org.springframework.boot.actuate.health.Health; | |
import org.springframework.boot.actuate.health.HealthIndicator; | |
import org.springframework.boot.actuate.health.Status; | |
import org.springframework.util.ReflectionUtils; | |
import java.lang.reflect.Field; | |
import java.util.LinkedHashMap; | |
import java.util.Map; | |
import java.util.concurrent.atomic.AtomicBoolean; | |
/** | |
* Checks if none of the available {@link PoolingHttpClientConnectionManager} beans | |
* are shut down, which can happen after an out-of-memory error, thus requiring | |
* the application to be restarted. | |
*/ | |
public class HttpConnectionPoolHealthIndicator implements HealthIndicator { | |
private Map<String, AtomicBoolean> shutDownPerConnManager = new LinkedHashMap<>(); | |
public HttpConnectionPoolHealthIndicator(Map<String, PoolingHttpClientConnectionManager> connectionManagers) { | |
if (connectionManagers.isEmpty()) return; | |
Field isShutDownField = ReflectionUtils.findField(PoolingHttpClientConnectionManager.class, "isShutDown"); | |
ReflectionUtils.makeAccessible(isShutDownField); | |
for (Map.Entry<String, PoolingHttpClientConnectionManager> entry : connectionManagers.entrySet()) { | |
AtomicBoolean isShutdown = (AtomicBoolean) ReflectionUtils.getField(isShutDownField, entry.getValue()); | |
shutDownPerConnManager.put(entry.getKey(), isShutdown); | |
} | |
} | |
@Override | |
public Health health() { | |
Health.Builder health = new Health.Builder(Status.UP); | |
for (Map.Entry<String, AtomicBoolean> entry : shutDownPerConnManager.entrySet()) { | |
String bean = entry.getKey(); | |
if (entry.getValue().get()) { | |
health.down().withDetail(bean, "shutdown"); | |
} else { | |
health.withDetail(bean, "running"); | |
} | |
} | |
return health.build(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment