From 924363ca1c0148c9de9ce7e4676c80e58fabb76f Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Fri, 20 Mar 2015 13:25:58 -0600 Subject: [PATCH] Sidecar reports true non-jvm app status to eureka. Added a LocalApplicationHealthCheckHandler that checks the local app and sends the appropriate status to eureka. fixes gh-251 --- .../LocalApplicationHealthCheckHandler.java | 54 ++++++++++++++ .../netflix/sidecar/SidecarConfiguration.java | 8 +++ ...calApplicationHealthCheckHandlerTests.java | 70 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java create mode 100644 spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java new file mode 100644 index 00000000..7a27f5b8 --- /dev/null +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandler.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.netflix.sidecar; + +import static com.netflix.appinfo.InstanceInfo.InstanceStatus.DOWN; +import static com.netflix.appinfo.InstanceInfo.InstanceStatus.OUT_OF_SERVICE; +import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UNKNOWN; +import static com.netflix.appinfo.InstanceInfo.InstanceStatus.UP; + +import com.netflix.appinfo.HealthCheckHandler; +import com.netflix.appinfo.InstanceInfo.InstanceStatus; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.health.Status; + +/** + * Eureka HealthCheckHandler that translates boot health status to + * InstanceStatus so the proper status of the non-JVM app is sent to Eureka. +* @author Spencer Gibb +*/ +class LocalApplicationHealthCheckHandler implements HealthCheckHandler { + + private final HealthIndicator healthIndicator; + + public LocalApplicationHealthCheckHandler(HealthIndicator healthIndicator) { + this.healthIndicator = healthIndicator; + } + + @Override + public InstanceStatus getStatus(InstanceStatus currentStatus) { + Status status = healthIndicator.health().getStatus(); + if (status.equals(Status.UP)) { + return UP; + } else if (status.equals(Status.OUT_OF_SERVICE)) { + return OUT_OF_SERVICE; + } else if (status.equals(Status.DOWN)) { + return DOWN; + } + return UNKNOWN; + } +} diff --git a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java index de587bf7..cdb90fee 100644 --- a/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java +++ b/spring-cloud-netflix-sidecar/src/main/java/org/springframework/cloud/netflix/sidecar/SidecarConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.netflix.appinfo.HealthCheckHandler; import com.netflix.discovery.EurekaClientConfig; /** @@ -63,6 +64,13 @@ public class SidecarConfiguration { + config.getHomePageUrlPath()); return config; } + + @Bean + public HealthCheckHandler healthCheckHandler( + final LocalApplicationHealthIndicator healthIndicator) { + return new LocalApplicationHealthCheckHandler(healthIndicator); + } + } @Bean diff --git a/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java new file mode 100644 index 00000000..2f077009 --- /dev/null +++ b/spring-cloud-netflix-sidecar/src/test/java/org/springframework/cloud/netflix/sidecar/LocalApplicationHealthCheckHandlerTests.java @@ -0,0 +1,70 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.netflix.sidecar; + +import static org.junit.Assert.assertEquals; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.BDDMockito.*; + +import com.netflix.appinfo.InstanceInfo.InstanceStatus; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; + +/** + * @author Spencer Gibb + */ +public class LocalApplicationHealthCheckHandlerTests { + + @Mock + private HealthIndicator healthIndicator; + + @Before + public void setup() { + initMocks(this); + } + + @Test + public void upMappingWorks() { + assertStatus(InstanceStatus.UP, Health.up()); + } + + @Test + public void downMappingWorks() { + assertStatus(InstanceStatus.DOWN, Health.down()); + } + + @Test + public void outOfServiceMappingWorks() { + assertStatus(InstanceStatus.OUT_OF_SERVICE, Health.outOfService()); + } + + @Test + public void unkownMappingWorks() { + assertStatus(InstanceStatus.UNKNOWN, Health.unknown()); + } + + private void assertStatus(InstanceStatus expected, Health.Builder builder) { + given(healthIndicator.health()).willReturn(builder.build()); + + LocalApplicationHealthCheckHandler handler = new LocalApplicationHealthCheckHandler(healthIndicator); + InstanceStatus status = handler.getStatus(InstanceStatus.UP); + assertEquals(expected, status); + } +}