package com.netflix.discovery; import com.netflix.appinfo.HealthCheckCallback; import com.netflix.appinfo.HealthCheckHandler; import com.netflix.appinfo.InstanceInfo; import com.netflix.config.ConfigurationManager; import org.junit.Assert; import org.junit.Test; /** * @author Nitesh Kant */ public class DiscoveryClientHealthTest extends AbstractDiscoveryClientTester { @Override protected void setupProperties() { super.setupProperties(); ConfigurationManager.getConfigInstance().setProperty("eureka.registration.enabled", "true"); } @Override protected InstanceInfo.Builder newInstanceInfoBuilder(int renewalIntervalInSecs) { InstanceInfo.Builder builder = super.newInstanceInfoBuilder(renewalIntervalInSecs); builder.setStatus(InstanceInfo.InstanceStatus.STARTING); return builder; } @Test public void testCallback() throws Exception { MyHealthCheckCallback myCallback = new MyHealthCheckCallback(true); client.registerHealthCheckCallback(myCallback); Assert.assertTrue(client instanceof DiscoveryClient); DiscoveryClient clientImpl = (DiscoveryClient) client; InstanceInfoReplicator instanceInfoReplicator = clientImpl.getInstanceInfoReplicator(); instanceInfoReplicator.run(); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.STARTING, clientImpl.getInstanceInfo().getStatus()); Assert.assertFalse("Healthcheck callback invoked when status is STARTING.", myCallback.isInvoked()); clientImpl.getInstanceInfo().setStatus(InstanceInfo.InstanceStatus.OUT_OF_SERVICE); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.OUT_OF_SERVICE, clientImpl.getInstanceInfo().getStatus()); myCallback.reset(); instanceInfoReplicator.run(); Assert.assertFalse("Healthcheck callback invoked when status is OOS.", myCallback.isInvoked()); clientImpl.getInstanceInfo().setStatus(InstanceInfo.InstanceStatus.DOWN); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.DOWN, clientImpl.getInstanceInfo().getStatus()); myCallback.reset(); instanceInfoReplicator.run(); Assert.assertTrue("Healthcheck callback not invoked.", myCallback.isInvoked()); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.UP, clientImpl.getInstanceInfo().getStatus()); } @Test public void testHandler() throws Exception { MyHealthCheckHandler myHealthCheckHandler = new MyHealthCheckHandler(InstanceInfo.InstanceStatus.UP); client.registerHealthCheck(myHealthCheckHandler); Assert.assertTrue(client instanceof DiscoveryClient); DiscoveryClient clientImpl = (DiscoveryClient) client; InstanceInfoReplicator instanceInfoReplicator = clientImpl.getInstanceInfoReplicator(); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.STARTING, clientImpl.getInstanceInfo().getStatus()); instanceInfoReplicator.run(); Assert.assertTrue("Healthcheck callback not invoked when status is STARTING.", myHealthCheckHandler.isInvoked()); Assert.assertEquals("Instance info status not as expected post healthcheck.", InstanceInfo.InstanceStatus.UP, clientImpl.getInstanceInfo().getStatus()); clientImpl.getInstanceInfo().setStatus(InstanceInfo.InstanceStatus.OUT_OF_SERVICE); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.OUT_OF_SERVICE, clientImpl.getInstanceInfo().getStatus()); myHealthCheckHandler.reset(); instanceInfoReplicator.run(); Assert.assertTrue("Healthcheck callback not invoked when status is OUT_OF_SERVICE.", myHealthCheckHandler.isInvoked()); Assert.assertEquals("Instance info status not as expected post healthcheck.", InstanceInfo.InstanceStatus.UP, clientImpl.getInstanceInfo().getStatus()); clientImpl.getInstanceInfo().setStatus(InstanceInfo.InstanceStatus.DOWN); Assert.assertEquals("Instance info status not as expected.", InstanceInfo.InstanceStatus.DOWN, clientImpl.getInstanceInfo().getStatus()); myHealthCheckHandler.reset(); instanceInfoReplicator.run(); Assert.assertTrue("Healthcheck callback not invoked when status is DOWN.", myHealthCheckHandler.isInvoked()); Assert.assertEquals("Instance info status not as expected post healthcheck.", InstanceInfo.InstanceStatus.UP, clientImpl.getInstanceInfo().getStatus()); clientImpl.getInstanceInfo().setStatus(InstanceInfo.InstanceStatus.UP); myHealthCheckHandler.reset(); myHealthCheckHandler.shouldException = true; instanceInfoReplicator.run(); Assert.assertTrue("Healthcheck callback not invoked when status is UP.", myHealthCheckHandler.isInvoked()); Assert.assertEquals("Instance info status not as expected post healthcheck.", InstanceInfo.InstanceStatus.DOWN, clientImpl.getInstanceInfo().getStatus()); } private static class MyHealthCheckCallback implements HealthCheckCallback { private final boolean health; private volatile boolean invoked; private MyHealthCheckCallback(boolean health) { this.health = health; } @Override public boolean isHealthy() { invoked = true; return health; } public boolean isInvoked() { return invoked; } public void reset() { invoked = false; } } private static class MyHealthCheckHandler implements HealthCheckHandler { private final InstanceInfo.InstanceStatus health; private volatile boolean invoked; volatile boolean shouldException; private MyHealthCheckHandler(InstanceInfo.InstanceStatus health) { this.health = health; } public boolean isInvoked() { return invoked; } public void reset() { shouldException = false; invoked = false; } @Override public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus currentStatus) { invoked = true; if (shouldException) { throw new RuntimeException("test induced exception"); } return health; } } }