Changes from ResponseStatus annotation to ResponseStatusException.

This allows to change the status without requiring another exception type.
This commit is contained in:
Spencer Gibb
2019-02-06 17:08:11 -05:00
parent 8cb0549a1b
commit 1233a6290e
4 changed files with 58 additions and 35 deletions

View File

@@ -24,6 +24,7 @@ import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
@@ -44,17 +45,24 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G
@Configuration
@ConditionalOnMissingClass("org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration")
@ConditionalOnMissingBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerProperties.class)
@AutoConfigureAfter(GatewayLoadBalancerClientAutoConfiguration.class)
public class GatewayNoLoadBalancerClientAutoConfiguration {
@Bean
@ConditionalOnMissingBean(LoadBalancerClientFilter.class)
public NoLoadBalancerClientFilter noLoadBalancerClientFilter() {
return new NoLoadBalancerClientFilter();
}
public NoLoadBalancerClientFilter noLoadBalancerClientFilter(LoadBalancerProperties properties) {
return new NoLoadBalancerClientFilter(properties.isUse404());
}
protected static class NoLoadBalancerClientFilter implements GlobalFilter, Ordered {
private final boolean use404;
public NoLoadBalancerClientFilter(boolean use404) {
this.use404 = use404;
}
@Override
public int getOrder() {
return LOAD_BALANCER_CLIENT_FILTER_ORDER;
@@ -69,7 +77,7 @@ public class GatewayNoLoadBalancerClientAutoConfiguration {
return chain.filter(exchange);
}
throw new NotFoundException("Unable to find instance for " + url.getHost());
throw NotFoundException.create(use404, "Unable to find instance for " + url.getHost());
}
}
}

View File

@@ -22,21 +22,18 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.core.Ordered;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.addOriginalRequestUrl;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
@@ -77,11 +74,7 @@ public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
final ServiceInstance instance = choose(exchange);
if (instance == null) {
String msg = "Unable to find instance for " + url.getHost();
if(properties.isUse404()) {
throw new FourOFourNotFoundException(msg);
}
throw new NotFoundException(msg);
throw NotFoundException.create(properties.isUse404(), "Unable to find instance for " + url.getHost());
}
URI uri = exchange.getRequest().getURI();
@@ -103,12 +96,6 @@ public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
protected ServiceInstance choose(ServerWebExchange exchange) {
return loadBalancer.choose(((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost());
}
@ResponseStatus(value = NOT_FOUND, reason = "The service was not found.")
static class FourOFourNotFoundException extends RuntimeException {
public FourOFourNotFoundException(String msg) {
super(msg);
}
}
class DelegatingServiceInstance implements ServiceInstance {
final ServiceInstance delegate;

View File

@@ -17,20 +17,37 @@
package org.springframework.cloud.gateway.support;
import org.springframework.web.bind.annotation.ResponseStatus;
import static org.springframework.http.HttpStatus.SERVICE_UNAVAILABLE;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
/**
* @author Spencer Gibb
*/
@ResponseStatus(value = SERVICE_UNAVAILABLE, reason = "The service or item was not found.")
public class NotFoundException extends RuntimeException {
public class NotFoundException extends ResponseStatusException {
public NotFoundException(String message) {
super(message);
this(HttpStatus.SERVICE_UNAVAILABLE, message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause);
this(HttpStatus.SERVICE_UNAVAILABLE, message, cause);
}
private NotFoundException(HttpStatus httpStatus, String message) {
super(httpStatus, message);
}
private NotFoundException(HttpStatus httpStatus, String message, Throwable cause) {
super(httpStatus, message, cause);
}
public static NotFoundException create(boolean with404, String message) {
HttpStatus httpStatus = with404? HttpStatus.NOT_FOUND: HttpStatus.SERVICE_UNAVAILABLE;
return new NotFoundException(httpStatus, message);
}
public static NotFoundException create(boolean with404, String message, Throwable cause) {
HttpStatus httpStatus = with404? HttpStatus.NOT_FOUND: HttpStatus.SERVICE_UNAVAILABLE;
return new NotFoundException(httpStatus, message, cause);
}
}

View File

@@ -9,19 +9,20 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import reactor.core.publisher.Mono;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.gateway.config.LoadBalancerProperties;
import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerContext;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
import org.springframework.mock.web.server.MockServerWebExchange;
import org.springframework.util.StringUtils;
@@ -39,8 +40,6 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.G
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR;
import reactor.core.publisher.Mono;
/**
* @author Spencer Gibb
* @author Tim Ysewyn
@@ -88,20 +87,32 @@ public class LoadBalancerClientFilterTests {
verifyZeroInteractions(loadBalancerClient);
}
@Test(expected = NotFoundException.class)
@Test
public void shouldThrowExceptionWhenNoServiceInstanceIsFound() {
URI uri = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri);
loadBalancerClientFilter.filter(exchange, chain);
try {
loadBalancerClientFilter.filter(exchange, chain);
} catch (NotFoundException e) {
assertThat(e.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE);
} catch (Exception e) {
throw e;
}
}
@Test(expected = LoadBalancerClientFilter.FourOFourNotFoundException.class)
@Test
public void shouldThrow4O4ExceptionWhenNoServiceInstanceIsFound() {
URI uri = UriComponentsBuilder.fromUriString("lb://myservice").build().toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, uri);
properties.setUse404(true);
loadBalancerClientFilter.filter(exchange, chain);
try {
loadBalancerClientFilter.filter(exchange, chain);
} catch (NotFoundException e) {
assertThat(e.getStatus()).isEqualTo(HttpStatus.NOT_FOUND);
} catch (Exception e) {
throw e;
}
}
@Test