Browse Source

Change DiscoveryHealthIndicator to an interface and create a DiscoveryCompositeHealthIndicator

fixes gh-1
pull/5/head
Spencer Gibb 10 years ago
parent
commit
a4d461aae0
  1. 14
      src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java
  2. 2
      src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java
  3. 61
      src/main/java/org/springframework/cloud/client/discovery/DiscoveryClientHealthIndicator.java
  4. 36
      src/main/java/org/springframework/cloud/client/discovery/DiscoveryCompositeHealthIndicator.java
  5. 39
      src/main/java/org/springframework/cloud/client/discovery/DiscoveryHealthIndicator.java
  6. 71
      src/test/java/org/springframework/cloud/client/discovery/DiscoveryCompositeHealthIndicatorTests.java

14
src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java

@ -1,12 +1,17 @@ @@ -1,12 +1,17 @@
package org.springframework.cloud.client;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.client.discovery.DiscoveryClientHealthIndicator;
import org.springframework.cloud.client.discovery.DiscoveryCompositeHealthIndicator;
import org.springframework.cloud.client.discovery.DiscoveryHealthIndicator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import java.util.List;
/**
* @author Spencer Gibb
*/
@ -15,8 +20,13 @@ import org.springframework.core.annotation.Order; @@ -15,8 +20,13 @@ import org.springframework.core.annotation.Order;
@Order(0)
public class CommonsClientAutoConfiguration {
@Bean
public DiscoveryClientHealthIndicator instancesHealthIndicator() {
return new DiscoveryClientHealthIndicator();
}
@Bean
public DiscoveryHealthIndicator discoveryHealthIndicator() {
return new DiscoveryHealthIndicator();
public DiscoveryCompositeHealthIndicator discoveryHealthIndicator(HealthAggregator aggregator, List<DiscoveryHealthIndicator> indicators) {
return new DiscoveryCompositeHealthIndicator(aggregator, indicators);
}
}

2
src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java

@ -9,6 +9,8 @@ import java.util.List; @@ -9,6 +9,8 @@ import java.util.List;
*/
//TODO: merge with LoadBalancerClient?
public interface DiscoveryClient {
public String description();
/**
* @return ServiceInstance with information used to register the local service
*/

61
src/main/java/org/springframework/cloud/client/discovery/DiscoveryClientHealthIndicator.java

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
package org.springframework.cloud.client.discovery;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.Ordered;
/**
* @author Spencer Gibb
*/
@Slf4j
public class DiscoveryClientHealthIndicator implements ApplicationContextAware, DiscoveryHealthIndicator, Ordered {
private ApplicationContext context;
private int order = Ordered.HIGHEST_PRECEDENCE;
@Override
public Health health() {
Health.Builder builder = new Health.Builder();
try {
DiscoveryClient client = context.getBean(DiscoveryClient.class);
if (client == null) {
builder.unknown().withDetail("warning", "No DiscoveryClient found");
return builder.build();
}
List<String> services = client.getServices();
builder.status(new Status("UP", client.description()))
.withDetail("services", services);
} catch (Exception e) {
log.error("Error", e);
builder.down(e);
}
return builder.build();
}
@Override
public String getName() {
return "discoveryClient";
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
@Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}

36
src/main/java/org/springframework/cloud/client/discovery/DiscoveryCompositeHealthIndicator.java

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
package org.springframework.cloud.client.discovery;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.*;
/**
* @author Spencer Gibb
*/
@Slf4j
public class DiscoveryCompositeHealthIndicator extends CompositeHealthIndicator {
@Autowired
public DiscoveryCompositeHealthIndicator(HealthAggregator healthAggregator, List<DiscoveryHealthIndicator> indicators) {
super(healthAggregator);
for (DiscoveryHealthIndicator indicator : indicators) {
addHealthIndicator(indicator.getName(), new Holder(indicator));
}
}
public static class Holder implements HealthIndicator {
DiscoveryHealthIndicator delegate;
public Holder(DiscoveryHealthIndicator delegate) {
this.delegate = delegate;
}
@Override
public Health health() {
return delegate.health();
}
}
}

39
src/main/java/org/springframework/cloud/client/discovery/DiscoveryHealthIndicator.java

@ -1,42 +1,15 @@ @@ -1,42 +1,15 @@
package org.springframework.cloud.client.discovery;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* @author Spencer Gibb
*/
@Slf4j
public class DiscoveryHealthIndicator extends AbstractHealthIndicator implements ApplicationContextAware {
private ApplicationContext context;
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
try {
DiscoveryClient client = context.getBean(DiscoveryClient.class);
if (client == null) {
builder.unknown().withDetail("warning", "No DiscoveryClient found");
return;
}
List<ServiceInstance> instances = client.getAllInstances();
builder.up().withDetail("instances", instances);
} catch (Exception e) {
log.error("Error", e);
builder.down(e);
}
}
public interface DiscoveryHealthIndicator {
public String getName();
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.context = context;
}
/**
* @return an indication of health
*/
Health health();
}

71
src/test/java/org/springframework/cloud/client/discovery/DiscoveryCompositeHealthIndicatorTests.java

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
package org.springframework.cloud.client.discovery;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
/**
* @author Spencer Gibb
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DiscoveryCompositeHealthIndicatorTests.Config.class, CommonsClientAutoConfiguration.class})
public class DiscoveryCompositeHealthIndicatorTests {
@Autowired
DiscoveryCompositeHealthIndicator healthIndicator;
@Configuration
public static class Config {
@Bean
public HealthAggregator healthAggregator() {
return new OrderedHealthAggregator();
}
@Bean
public DiscoveryClient discoveryClient() {
DiscoveryClient mock = mock(DiscoveryClient.class);
when(mock.description()).thenReturn("TestDiscoveryClient");
when(mock.getServices()).thenReturn(Lists.newArrayList("TestService1"));
return mock;
}
@Bean
public DiscoveryHealthIndicator discoveryHealthIndicator() {
return new DiscoveryHealthIndicator() {
@Override
public String getName() {
return "testDiscoveryHealthIndicator";
}
@Override
public Health health() {
return new Health.Builder().up().build();
}
};
}
}
@Test
public void testHealthIndicator() {
assertNotNull("healthIndicator was null", healthIndicator);
Health health = healthIndicator.health();
assertNotNull("health was null", health);
Status status = health.getStatus();
assertNotNull("status was null", status);
assertEquals("status code was wrong", "UP", status.getCode());
assertEquals("status desciption was wrong", "TestDiscoveryClient", status.getDescription());
}
}
Loading…
Cancel
Save