diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponse.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponse.java index 435850fce6..6b1a9361aa 100644 --- a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponse.java +++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponse.java @@ -24,19 +24,42 @@ public class BlockResponse { /** - * HTTP status code. + * HTTP status code used for the actual HTTP response. + */ + private int status; + + /** + * Business code carried in the response body, independent of {@link #status}. */ private int code; private String message; private String route; + /** + * @deprecated use {@link #BlockResponse(int, int, String, String)} instead. + * The given {@code code} will be used as both the HTTP status and the body code. + */ + @Deprecated public BlockResponse(int code, String message, String route) { + this(code, code, message, route); + } + + public BlockResponse(int status, int code, String message, String route) { + this.status = status; this.code = code; this.message = message; this.route = route; } + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + public int getCode() { return code; } diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelZuulPreFilter.java b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelZuulPreFilter.java index 95e643281d..ed26232468 100644 --- a/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelZuulPreFilter.java +++ b/sentinel-adapter/sentinel-zuul-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/filters/SentinelZuulPreFilter.java @@ -142,7 +142,7 @@ public Object run() throws ZuulException { // Set fallback response. ctx.setResponseBody(blockResponse.toString()); - ctx.setResponseStatusCode(blockResponse.getCode()); + ctx.setResponseStatusCode(blockResponse.getStatus()); // Set Response ContentType ctx.getResponse().setContentType("application/json; charset=utf-8"); } finally { diff --git a/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponseTest.java b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponseTest.java new file mode 100644 index 0000000000..9bdb4fbed9 --- /dev/null +++ b/sentinel-adapter/sentinel-zuul-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/gateway/zuul/fallback/BlockResponseTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * 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 com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test cases for {@link BlockResponse}. + */ +public class BlockResponseTest { + + @Test + public void testDeprecatedConstructorKeepsStatusAndCodeInSync() { + BlockResponse response = new BlockResponse(429, "blocked", "/foo"); + + Assert.assertEquals(429, response.getStatus()); + Assert.assertEquals(429, response.getCode()); + } + + @Test + public void testStatusAndCodeCanBeCustomizedIndependently() { + // Body code can differ from the actual HTTP status, see issue #2985. + BlockResponse response = new BlockResponse(200, 10018, "blocked", "/foo"); + + Assert.assertEquals(200, response.getStatus()); + Assert.assertEquals(10018, response.getCode()); + Assert.assertTrue(response.toString().contains("\"code\":10018")); + } +} diff --git a/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponse.java b/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponse.java index 5209f2329a..dc35b69f85 100644 --- a/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponse.java +++ b/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponse.java @@ -24,19 +24,42 @@ public class BlockResponse { /** - * HTTP status code. + * HTTP status code used for the actual HTTP response. + */ + private int status; + + /** + * Business code carried in the response body, independent of {@link #status}. */ private int code; private String message; private String route; + /** + * @deprecated use {@link #BlockResponse(int, int, String, String)} instead. + * The given {@code code} will be used as both the HTTP status and the body code. + */ + @Deprecated public BlockResponse(int code, String message, String route) { + this(code, code, message, route); + } + + public BlockResponse(int status, int code, String message, String route) { + this.status = status; this.code = code; this.message = message; this.route = route; } + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + public int getCode() { return code; } diff --git a/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/filters/endpoint/SentinelZuulEndpoint.java b/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/filters/endpoint/SentinelZuulEndpoint.java index 6713127415..0c6ca95ff5 100644 --- a/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/filters/endpoint/SentinelZuulEndpoint.java +++ b/sentinel-adapter/sentinel-zuul2-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/filters/endpoint/SentinelZuulEndpoint.java @@ -42,7 +42,7 @@ public HttpResponseMessage apply(HttpRequestMessage request) { ZuulBlockFallbackProvider zuulBlockFallbackProvider = ZuulBlockFallbackManager .getFallbackProvider(fallBackRoute); BlockResponse response = zuulBlockFallbackProvider.fallbackResponse(fallBackRoute, throwable); - HttpResponseMessage resp = new HttpResponseMessageImpl(context, request, response.getCode()); + HttpResponseMessage resp = new HttpResponseMessageImpl(context, request, response.getStatus()); resp.setBodyAsText(response.toString()); return resp; } diff --git a/sentinel-adapter/sentinel-zuul2-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponseTest.java b/sentinel-adapter/sentinel-zuul2-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponseTest.java new file mode 100644 index 0000000000..a811a75148 --- /dev/null +++ b/sentinel-adapter/sentinel-zuul2-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/gateway/zuul2/fallback/BlockResponseTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * 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 com.alibaba.csp.sentinel.adapter.gateway.zuul2.fallback; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test cases for {@link BlockResponse}. + */ +public class BlockResponseTest { + + @Test + public void testDeprecatedConstructorKeepsStatusAndCodeInSync() { + BlockResponse response = new BlockResponse(429, "blocked", "/foo"); + + Assert.assertEquals(429, response.getStatus()); + Assert.assertEquals(429, response.getCode()); + } + + @Test + public void testStatusAndCodeCanBeCustomizedIndependently() { + // Body code can differ from the actual HTTP status, see issue #2985. + BlockResponse response = new BlockResponse(200, 10018, "blocked", "/foo"); + + Assert.assertEquals(200, response.getStatus()); + Assert.assertEquals(10018, response.getCode()); + Assert.assertTrue(response.toString().contains("\"code\":10018")); + } +}