Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-cloud-netflix
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
spring-cloud-netflix
Commits
834dfe22
Commit
834dfe22
authored
Feb 09, 2016
by
Spencer Gibb
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle ClientException.SERVER_THROTTLED as 503
fixes gh-406
parent
1b190a32
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
77 additions
and
14 deletions
+77
-14
SendErrorFilter.java
...work/cloud/netflix/zuul/filters/post/SendErrorFilter.java
+14
-4
RibbonRoutingFilter.java
...cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java
+22
-7
SampleZuulProxyApplicationTests.java
...k/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java
+41
-3
No files found.
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/post/SendErrorFilter.java
View file @
834dfe22
...
...
@@ -17,6 +17,7 @@
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
post
;
import
javax.servlet.RequestDispatcher
;
import
javax.servlet.http.HttpServletRequest
;
import
lombok.extern.apachecommons.CommonsLog
;
...
...
@@ -59,19 +60,28 @@ public class SendErrorFilter extends ZuulFilter {
public
Object
run
()
{
try
{
RequestContext
ctx
=
RequestContext
.
getCurrentContext
();
HttpServletRequest
request
=
ctx
.
getRequest
();
int
statusCode
=
(
Integer
)
ctx
.
get
(
"error.status_code"
);
request
.
setAttribute
(
"javax.servlet.error.status_code"
,
statusCode
);
if
(
ctx
.
containsKey
(
"error.exception"
))
{
Object
e
=
ctx
.
get
(
"error.exception"
);
log
.
warn
(
"Error during filtering"
,
Throwable
.
class
.
cast
(
e
));
ctx
.
getRequest
()
.
setAttribute
(
"javax.servlet.error.exception"
,
e
);
request
.
setAttribute
(
"javax.servlet.error.exception"
,
e
);
}
ctx
.
getRequest
().
setAttribute
(
"javax.servlet.error.status_code"
,
statusCode
);
RequestDispatcher
dispatcher
=
ctx
.
getRequest
().
getRequestDispatcher
(
if
(
ctx
.
containsKey
(
"error.message"
))
{
String
message
=
(
String
)
ctx
.
get
(
"error.message"
);
request
.
setAttribute
(
"javax.servlet.error.message"
,
message
);
}
RequestDispatcher
dispatcher
=
request
.
getRequestDispatcher
(
this
.
errorPath
);
if
(
dispatcher
!=
null
)
{
ctx
.
set
(
SEND_ERROR_FILTER_RAN
,
true
);
if
(!
ctx
.
getResponse
().
isCommitted
())
{
dispatcher
.
forward
(
ctx
.
getRequest
()
,
ctx
.
getResponse
());
dispatcher
.
forward
(
request
,
ctx
.
getResponse
());
}
}
}
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/RibbonRoutingFilter.java
View file @
834dfe22
...
...
@@ -79,6 +79,7 @@ public class RibbonRoutingFilter extends ZuulFilter {
}
catch
(
ZuulException
ex
)
{
context
.
set
(
"error.status_code"
,
ex
.
nStatusCode
);
context
.
set
(
"error.message"
,
ex
.
errorCause
);
context
.
set
(
"error.exception"
,
ex
);
}
catch
(
Exception
ex
)
{
...
...
@@ -127,13 +128,14 @@ public class RibbonRoutingFilter extends ZuulFilter {
}
catch
(
HystrixRuntimeException
ex
)
{
info
.
put
(
"status"
,
"500"
);
if
(
ex
.
getFallbackException
()
!=
null
&&
ex
.
getFallbackException
().
getCause
()
!=
null
&&
ex
.
getFallbackException
().
getCause
()
instanceof
ClientException
)
{
ClientException
cause
=
(
ClientException
)
ex
.
getFallbackException
()
.
getCause
();
throw
new
ZuulException
(
cause
,
"Forwarding error"
,
500
,
cause
.
getErrorType
().
toString
());
ClientException
clientException
=
findClientException
(
ex
);
if
(
clientException
!=
null
)
{
int
statusCode
=
500
;
if
(
clientException
.
getErrorType
()
==
ClientException
.
ErrorType
.
SERVER_THROTTLED
)
{
statusCode
=
503
;
}
throw
new
ZuulException
(
clientException
,
"Forwarding error"
,
statusCode
,
clientException
.
getErrorType
().
toString
());
}
throw
new
ZuulException
(
ex
,
"Forwarding error"
,
500
,
ex
.
getFailureType
().
toString
());
...
...
@@ -141,6 +143,19 @@ public class RibbonRoutingFilter extends ZuulFilter {
}
protected
ClientException
findClientException
(
HystrixRuntimeException
ex
)
{
if
(
ex
.
getCause
()
!=
null
&&
ex
.
getCause
()
instanceof
ClientException
)
{
return
(
ClientException
)
ex
.
getCause
();
}
if
(
ex
.
getFallbackException
()
!=
null
&&
ex
.
getFallbackException
().
getCause
()
!=
null
&&
ex
.
getFallbackException
().
getCause
()
instanceof
ClientException
)
{
return
(
ClientException
)
ex
.
getFallbackException
().
getCause
();
}
return
null
;
}
private
InputStream
getRequestBody
(
HttpServletRequest
request
)
{
InputStream
requestEntity
=
null
;
// ApacheHttpClient4Handler does not support body in delete requests
...
...
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/SampleZuulProxyApplicationTests.java
View file @
834dfe22
...
...
@@ -16,12 +16,16 @@
package
org
.
springframework
.
cloud
.
netflix
.
zuul
;
import
java.io.InputStream
;
import
java.net.URISyntaxException
;
import
java.util.UUID
;
import
javax.servlet.http.HttpServletRequest
;
import
com.netflix.client.ClientException
;
import
com.netflix.client.http.HttpRequest
;
import
com.netflix.loadbalancer.Server
;
import
com.netflix.loadbalancer.ServerList
;
import
com.netflix.
zuul.exception.ZuulException
;
import
com.netflix.
niws.client.http.RestClient
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
...
...
@@ -44,9 +48,12 @@ import org.springframework.http.HttpEntity;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.client.ClientHttpResponse
;
import
org.springframework.mock.http.client.MockClientHttpResponse
;
import
org.springframework.test.annotation.DirtiesContext
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.context.web.WebAppConfiguration
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
...
...
@@ -85,6 +92,14 @@ public class SampleZuulProxyApplicationTests extends ZuulProxyTestBase {
}
@Test
public
void
ribbonCommandServiceUnavailable
()
{
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
"/simple/throwexception/503"
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
SERVICE_UNAVAILABLE
,
result
.
getStatusCode
());
}
@Test
public
void
ribbonCommandBadHost
()
{
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
"/badhost/1"
,
...
...
@@ -133,18 +148,41 @@ class SampleZuulProxyApplication extends ZuulProxyTestBase.AbstractZuulProxyAppl
}
@Override
@SuppressWarnings
(
"deprecation"
)
@SneakyThrows
public
RestClientRibbonCommand
create
(
RibbonCommandContext
context
)
{
String
uri
=
context
.
getUri
();
if
(
uri
.
startsWith
(
"/throwexception/"
))
{
String
code
=
uri
.
replace
(
"/throwexception/"
,
""
);
throw
new
ZuulException
(
new
RuntimeException
(),
Integer
.
parseInt
(
code
),
"test error"
);
RestClient
restClient
=
getClientFactory
().
getClient
(
context
.
getServiceId
(),
RestClient
.
class
);
return
new
MyCommand
(
Integer
.
parseInt
(
code
),
context
.
getServiceId
(),
restClient
,
getVerb
(
context
.
getVerb
()),
context
.
getUri
(),
context
.
getRetryable
(),
context
.
getHeaders
(),
context
.
getParams
(),
context
.
getRequestEntity
());
}
return
super
.
create
(
context
);
}
}
static
class
MyCommand
extends
RestClientRibbonCommand
{
private
int
errorCode
;
public
MyCommand
(
int
errorCode
,
String
commandKey
,
RestClient
restClient
,
HttpRequest
.
Verb
verb
,
String
uri
,
Boolean
retryable
,
MultiValueMap
<
String
,
String
>
headers
,
MultiValueMap
<
String
,
String
>
params
,
InputStream
requestEntity
)
throws
URISyntaxException
{
super
(
commandKey
,
restClient
,
verb
,
uri
,
retryable
,
headers
,
params
,
requestEntity
);
this
.
errorCode
=
errorCode
;
}
@Override
protected
ClientHttpResponse
forward
()
throws
Exception
{
if
(
errorCode
==
503
)
{
throw
new
ClientException
(
ClientException
.
ErrorType
.
SERVER_THROTTLED
);
}
return
new
MockClientHttpResponse
((
byte
[])
null
,
HttpStatus
.
valueOf
(
this
.
errorCode
));
}
}
// Load balancer with fixed server list for "simple" pointing to localhost
@Configuration
static
class
BadHostRibbonClientConfiguration
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment