Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jmnarloch committed Oct 24, 2015
1 parent 34b21d6 commit 8f3eb69
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 2 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ a backing service exists in the discovery service.

Add the Spring Cloud starter to your project:

```xml
<dependency>
<groupId>io.jmnarloch</groupId>
<artifactId>zuul-route-health-spring-cloud-starter</artifactId>
<version>1.0.0</version>
</dependency>
```

## Properties

Property `zuul.health.enabled` let's you enable this extension.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,41 @@
*/
public class ZuulRouteHealthIndicator implements HealthIndicator {

/**
* The available routes.
*/
private static final String AVAILABLE = "available";

/**
* The unavailable routes.
*/
private static final String UNAVAILABLE = "unavailable";

/**
* The local discovery client.
*/
private final DiscoveryClient discoveryClient;

/**
* The Zuul routing configuration.
*/
private final ZuulProperties zuulProperties;

/**
* Creates new instance of {@link ZuulRouteHealthIndicator} instance with the discovery client and Zuul properties.
* @param discoveryClient the discover client
* @param zuulProperties the zuul properties
*/
public ZuulRouteHealthIndicator(DiscoveryClient discoveryClient, ZuulProperties zuulProperties) {
Assert.notNull(discoveryClient, "Parameter 'discoveryClient' can not be null");
Assert.notNull(zuulProperties, "Parameter 'zuulPropertes' can not be null");
this.discoveryClient = discoveryClient;
this.zuulProperties = zuulProperties;
}

/**
* {@inheritDoc}
*/
@Override
public Health health() {

Expand All @@ -52,6 +73,10 @@ public Health health() {
return withAdditionalDetails(builder).build();
}

/**
* Retrieves the Zuul routes health status.
* @return the routes status
*/
private Status getRouteStatus() {
for (ZuulProperties.ZuulRoute route : zuulProperties.getRoutes().values()) {
if (route.getServiceId() != null && discoveryClient.getInstances(route.getServiceId()).isEmpty()) {
Expand All @@ -61,6 +86,12 @@ private Status getRouteStatus() {
return Status.UP;
}

/**
* Populates the health information with the list of available routes.
*
* @param builder the health builder
* @return the health builder
*/
private Health.Builder withAdditionalDetails(Health.Builder builder) {

final Set<String> available = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.jmnarloch.spring.cloud.zuul;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
Expand All @@ -26,7 +27,7 @@
* @author Jakub Narloch
*/
@Configuration
//@ConditionalOnClass()
@ConditionalOnClass({DiscoveryClient.class, ZuulProperties.class})
@ConditionalOnProperty(value = "zuul.health.enabled", matchIfMissing = true)
public class ZuulRouteHealthIndicatorAutoConfiguration {

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/spring.factories
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.jmnarloch.spring.cloud.feign.OkHttpClientAutoConfiguration
io.jmnarloch.spring.cloud.zuul.ZuulRouteHealthIndicatorAutoConfiguration
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/**
* Copyright (c) 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 io.jmnarloch.spring.cloud.zuul;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
* Tests the {@link ZuulRouteHealthIndicator}.
*
* @author Jakub Narloch
*/
@SpringApplicationConfiguration(classes = {ZuulRouteHealthIndicatorTest.Application.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class ZuulRouteHealthIndicatorTest {

@Autowired
private ZuulRouteHealthIndicator zuulRouteHealthIndicator;

@Autowired
private ZuulProperties zuulProperties;

@Autowired
private DiscoveryClient discoveryClient;

@Test
public void shouldReportUpStateForNoRoutes() {

// given
when(discoveryClient.getInstances(Mockito.any(String.class))).thenReturn(new ArrayList<ServiceInstance>());

// when
final Health health = zuulRouteHealthIndicator.health();

// then
assertNotNull(health);
assertEquals(Status.UP, health.getStatus());
}

@Test
public void shouldReportDownState() {

// given
final ZuulProperties.ZuulRoute route = new ZuulProperties.ZuulRoute("/zuul", "proxied-service");
zuulProperties.getRoutes().put(route.getId(), route);

// when
final Health health = zuulRouteHealthIndicator.health();

// then
assertNotNull(health);
assertEquals(Status.DOWN, health.getStatus());
assertTrue(((Collection) health.getDetails().get("available")).isEmpty());
assertFalse(((Collection) health.getDetails().get("unavailable")).isEmpty());
}

@Test
public void shouldReportUpState() {

// given
final ZuulProperties.ZuulRoute route = new ZuulProperties.ZuulRoute("/zuul", "proxied-service");
zuulProperties.getRoutes().put(route.getId(), route);

final List<ServiceInstance> services = new ArrayList<>();
services.add(mock(ServiceInstance.class));
when(discoveryClient.getInstances("proxied-service")).thenReturn(services);

// when
final Health health = zuulRouteHealthIndicator.health();

// then
assertNotNull(health);
assertEquals(Status.UP, health.getStatus());
assertFalse(((Collection) health.getDetails().get("available")).isEmpty());
assertTrue(((Collection) health.getDetails().get("unavailable")).isEmpty());
}

@EnableAutoConfiguration
@Configuration
public static class Application {

@Bean
public ZuulProperties zuulProperties() {
return new ZuulProperties();
}

@Bean
public DiscoveryClient discoveryClient() {
return mock(DiscoveryClient.class);
}
}
}

0 comments on commit 8f3eb69

Please sign in to comment.