Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jkuipers
Last active June 16, 2020 17:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkuipers/d4964ea41e2e02409591fc84ce18a77e to your computer and use it in GitHub Desktop.
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
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