From 60a4f769cf5c126809f4a47e5252f63df58e3ddb Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 10 Oct 2017 13:02:04 -0400 Subject: [PATCH] If hystrix timesout, return status 504 gateway timeout. fixes gh-82 --- .../factory/HystrixWebFilterFactory.java | 23 +++++++++++++++---- .../factory/HystrixWebFilterFactoryTests.java | 2 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactory.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactory.java index 75f42fd3..f85a893d 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactory.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactory.java @@ -17,6 +17,11 @@ package org.springframework.cloud.gateway.filter.factory; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import org.springframework.http.HttpStatus; import org.springframework.tuple.Tuple; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; @@ -25,15 +30,16 @@ import org.springframework.web.server.WebFilterChain; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixObservableCommand; +import com.netflix.hystrix.exception.HystrixRuntimeException; + +import static com.netflix.hystrix.exception.HystrixRuntimeException.FailureType.TIMEOUT; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setResponseStatus; import reactor.core.publisher.Mono; import rx.Observable; import rx.RxReactiveStreams; import rx.Subscription; -import java.util.Arrays; -import java.util.List; - /** * @author Spencer Gibb */ @@ -61,7 +67,16 @@ public class HystrixWebFilterFactory implements WebFilterFactory { return Mono.create(s -> { Subscription sub = command.toObservable().subscribe(s::success, s::error, s::success); s.onCancel(sub::unsubscribe); - }); + }).onErrorResume((Function>) throwable -> { + if (throwable instanceof HystrixRuntimeException) { + HystrixRuntimeException e = (HystrixRuntimeException) throwable; + if (e.getFailureType() == TIMEOUT) { //TODO: optionally set status + setResponseStatus(exchange, HttpStatus.GATEWAY_TIMEOUT); + return exchange.getResponse().setComplete(); + } + } + return Mono.empty(); + }).then(); }; } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactoryTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactoryTests.java index 94a87fed..1b43b543 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactoryTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory/HystrixWebFilterFactoryTests.java @@ -70,7 +70,7 @@ public class HystrixWebFilterFactoryTests extends BaseWebClientTests { StepVerifier.create(result) .consumeNextWith( - response -> assertStatus(response, HttpStatus.INTERNAL_SERVER_ERROR)) + response -> assertStatus(response, HttpStatus.GATEWAY_TIMEOUT)) .expectComplete() .verify(DURATION); }