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
7e6c7ee2
Commit
7e6c7ee2
authored
Feb 09, 2017
by
Ryan Baxter
Committed by
GitHub
Feb 09, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1680 from ryanjbaxter/zuul-retry
Add Retry Logic To Zuul Using Spring Retry. Fixes #1295
parents
ee953bef
f1fb32cf
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
615 additions
and
36 deletions
+615
-36
RibbonClientConfiguration.java
...ework/cloud/netflix/ribbon/RibbonClientConfiguration.java
+6
-4
RibbonLoadBalancingHttpClient.java
.../netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java
+36
-18
OkHttpLoadBalancingClient.java
...loud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java
+38
-11
ContextAwareRequest.java
...ork/cloud/netflix/ribbon/support/ContextAwareRequest.java
+27
-1
RetryableLoadBalancingClient.java
.../netflix/ribbon/support/RetryableLoadBalancingClient.java
+111
-0
RibbonLoadBalancingHttpClientTests.java
...lix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java
+0
-0
ContextAwareRequestTest.java
...cloud/netflix/ribbon/support/ContextAwareRequestTest.java
+108
-0
HttpClientRibbonRetryIntegrationTests.java
...s/route/apache/HttpClientRibbonRetryIntegrationTests.java
+54
-0
OkHttpRibbonRetryIntegrationTests.java
...lters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java
+55
-0
RibbonCommandFallbackTests.java
...uul/filters/route/support/RibbonCommandFallbackTests.java
+0
-1
RibbonRetryIntegrationTestBase.java
...filters/route/support/RibbonRetryIntegrationTestBase.java
+170
-0
ZuulProxyTestBase.java
...netflix/zuul/filters/route/support/ZuulProxyTestBase.java
+0
-1
pom.xml
spring-cloud-netflix-eureka-client/pom.xml
+10
-0
No files found.
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java
View file @
7e6c7ee2
...
...
@@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory
;
import
org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient
;
import
org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient
;
import
org.springframework.context.annotation.Bean
;
...
...
@@ -126,9 +127,10 @@ public class RibbonClientConfiguration {
@ConditionalOnMissingBean
(
AbstractLoadBalancerAwareClient
.
class
)
public
RibbonLoadBalancingHttpClient
ribbonLoadBalancingHttpClient
(
IClientConfig
config
,
ServerIntrospector
serverIntrospector
,
ILoadBalancer
loadBalancer
,
RetryHandler
retryHandler
)
{
ILoadBalancer
loadBalancer
,
RetryHandler
retryHandler
,
LoadBalancedRetryPolicyFactory
loadBalancedRetryPolicyFactory
)
{
RibbonLoadBalancingHttpClient
client
=
new
RibbonLoadBalancingHttpClient
(
config
,
serverIntrospector
);
config
,
serverIntrospector
,
loadBalancedRetryPolicyFactory
);
client
.
setLoadBalancer
(
loadBalancer
);
client
.
setRetryHandler
(
retryHandler
);
Monitors
.
registerObject
(
"Client_"
+
this
.
name
,
client
);
...
...
@@ -147,9 +149,9 @@ public class RibbonClientConfiguration {
@ConditionalOnMissingBean
(
AbstractLoadBalancerAwareClient
.
class
)
public
OkHttpLoadBalancingClient
okHttpLoadBalancingClient
(
IClientConfig
config
,
ServerIntrospector
serverIntrospector
,
ILoadBalancer
loadBalancer
,
RetryHandler
retryHandler
)
{
RetryHandler
retryHandler
,
LoadBalancedRetryPolicyFactory
loadBalancedRetryPolicyFactory
)
{
OkHttpLoadBalancingClient
client
=
new
OkHttpLoadBalancingClient
(
config
,
serverIntrospector
);
serverIntrospector
,
loadBalancedRetryPolicyFactory
);
client
.
setLoadBalancer
(
loadBalancer
);
client
.
setRetryHandler
(
retryHandler
);
Monitors
.
registerObject
(
"Client_"
+
this
.
name
,
client
);
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClient.java
View file @
7e6c7ee2
...
...
@@ -23,12 +23,15 @@ import org.apache.http.client.HttpClient;
import
org.apache.http.client.config.RequestConfig
;
import
org.apache.http.client.methods.HttpUriRequest
;
import
org.apache.http.impl.client.HttpClientBuilder
;
import
org.springframework.cloud.client.ServiceInstance
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory
;
import
org.springframework.cloud.netflix.ribbon.ServerIntrospector
;
import
org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient
;
import
org.springframework.cloud.netflix.ribbon.support.RetryableLoadBalancingClient
;
import
org.springframework.retry.RetryCallback
;
import
org.springframework.retry.RetryContext
;
import
org.springframework.web.util.UriComponentsBuilder
;
import
com.netflix.client.RequestSpecificRetryHandler
;
import
com.netflix.client.RetryHandler
;
import
com.netflix.client.config.CommonClientConfigKey
;
import
com.netflix.client.config.IClientConfig
;
import
com.netflix.loadbalancer.ILoadBalancer
;
...
...
@@ -38,11 +41,11 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
/**
* @author Christian Lohmann
* @author Ryan Baxter
*/
//TODO: rename (ie new class that extends this in Dalston) to ApacheHttpLoadBalancingClient
public
class
RibbonLoadBalancingHttpClient
extends
AbstractLoadBalancingClient
<
RibbonApacheHttpRequest
,
RibbonApacheHttpResponse
,
HttpClient
>
{
extends
RetryableLoadBalancingClient
<
RibbonApacheHttpRequest
,
RibbonApacheHttpResponse
,
HttpClient
>
{
@Deprecated
public
RibbonLoadBalancingHttpClient
()
{
...
...
@@ -62,6 +65,11 @@ public class RibbonLoadBalancingHttpClient
super
(
delegate
,
config
,
serverIntrospector
);
}
public
RibbonLoadBalancingHttpClient
(
IClientConfig
iClientConfig
,
ServerIntrospector
serverIntrospector
,
LoadBalancedRetryPolicyFactory
loadBalancedRetryPolicyFactory
)
{
super
(
iClientConfig
,
serverIntrospector
,
loadBalancedRetryPolicyFactory
);
}
protected
HttpClient
createDelegate
(
IClientConfig
config
)
{
return
HttpClientBuilder
.
create
()
// already defaults to 0 in builder, so resetting to 0 won't hurt
...
...
@@ -74,7 +82,7 @@ public class RibbonLoadBalancingHttpClient
}
@Override
public
RibbonApacheHttpResponse
execute
(
RibbonApacheHttpRequest
request
,
public
RibbonApacheHttpResponse
execute
(
final
RibbonApacheHttpRequest
request
,
final
IClientConfig
configOverride
)
throws
Exception
{
final
RequestConfig
.
Builder
builder
=
RequestConfig
.
custom
();
IClientConfig
config
=
configOverride
!=
null
?
configOverride
:
this
.
config
;
...
...
@@ -86,27 +94,37 @@ public class RibbonLoadBalancingHttpClient
CommonClientConfigKey
.
FollowRedirects
,
this
.
followRedirects
));
final
RequestConfig
requestConfig
=
builder
.
build
();
return
this
.
executeWithRetry
(
request
,
new
RetryCallback
()
{
@Override
public
RibbonApacheHttpResponse
doWithRetry
(
RetryContext
context
)
throws
Exception
{
//on retries the policy will choose the server and set it in the context
//extract the server and update the request being made
RibbonApacheHttpRequest
newRequest
=
request
;
if
(
context
instanceof
LoadBalancedRetryContext
)
{
ServiceInstance
service
=
((
LoadBalancedRetryContext
)
context
).
getServiceInstance
();
if
(
service
!=
null
)
{
//Reconstruct the request URI using the host and port set in the retry context
newRequest
=
newRequest
.
withNewUri
(
new
URI
(
service
.
getUri
().
getScheme
(),
newRequest
.
getURI
().
getUserInfo
(),
service
.
getHost
(),
service
.
getPort
(),
newRequest
.
getURI
().
getPath
(),
newRequest
.
getURI
().
getQuery
(),
newRequest
.
getURI
().
getFragment
()));
}
}
if
(
isSecure
(
configOverride
))
{
final
URI
secureUri
=
UriComponentsBuilder
.
fromUri
(
r
equest
.
getUri
())
final
URI
secureUri
=
UriComponentsBuilder
.
fromUri
(
newR
equest
.
getUri
())
.
scheme
(
"https"
).
build
().
toUri
();
request
=
r
equest
.
withNewUri
(
secureUri
);
newRequest
=
newR
equest
.
withNewUri
(
secureUri
);
}
final
HttpUriRequest
httpUriRequest
=
request
.
toRequest
(
requestConfig
);
final
HttpResponse
httpResponse
=
this
.
delegate
.
execute
(
httpUriRequest
);
HttpUriRequest
httpUriRequest
=
newRequest
.
toRequest
(
requestConfig
);
final
HttpResponse
httpResponse
=
RibbonLoadBalancingHttpClient
.
this
.
delegate
.
execute
(
httpUriRequest
);
return
new
RibbonApacheHttpResponse
(
httpResponse
,
httpUriRequest
.
getURI
());
}
});
}
@Override
public
URI
reconstructURIWithServer
(
Server
server
,
URI
original
)
{
URI
uri
=
updateToHttpsIfNeeded
(
original
,
this
.
config
,
this
.
serverIntrospector
,
server
);
return
super
.
reconstructURIWithServer
(
server
,
uri
);
}
@Override
public
RequestSpecificRetryHandler
getRequestSpecificRetryHandler
(
RibbonApacheHttpRequest
request
,
IClientConfig
requestConfig
)
{
return
new
RequestSpecificRetryHandler
(
false
,
false
,
RetryHandler
.
DEFAULT
,
null
);
}
}
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/OkHttpLoadBalancingClient.java
View file @
7e6c7ee2
...
...
@@ -19,8 +19,13 @@ package org.springframework.cloud.netflix.ribbon.okhttp;
import
java.net.URI
;
import
java.util.concurrent.TimeUnit
;
import
org.springframework.cloud.client.ServiceInstance
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory
;
import
org.springframework.cloud.netflix.ribbon.ServerIntrospector
;
import
org.springframework.cloud.netflix.ribbon.support.AbstractLoadBalancingClient
;
import
org.springframework.cloud.netflix.ribbon.support.RetryableLoadBalancingClient
;
import
org.springframework.retry.RetryCallback
;
import
org.springframework.retry.RetryContext
;
import
org.springframework.web.util.UriComponentsBuilder
;
import
com.netflix.client.config.CommonClientConfigKey
;
...
...
@@ -36,9 +41,10 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
/**
* @author Spencer Gibb
* @author Ryan Baxter
*/
public
class
OkHttpLoadBalancingClient
extends
Abstract
LoadBalancingClient
<
OkHttpRibbonRequest
,
OkHttpRibbonResponse
,
OkHttpClient
>
{
extends
Retryable
LoadBalancingClient
<
OkHttpRibbonRequest
,
OkHttpRibbonResponse
,
OkHttpClient
>
{
@Deprecated
public
OkHttpLoadBalancingClient
()
{
...
...
@@ -55,6 +61,12 @@ public class OkHttpLoadBalancingClient
super
(
config
,
serverIntrospector
);
}
public
OkHttpLoadBalancingClient
(
IClientConfig
config
,
ServerIntrospector
serverIntrospector
,
LoadBalancedRetryPolicyFactory
loadBalancedRetryPolicyFactory
)
{
super
(
config
,
serverIntrospector
,
loadBalancedRetryPolicyFactory
);
}
public
OkHttpLoadBalancingClient
(
OkHttpClient
delegate
,
IClientConfig
config
,
ServerIntrospector
serverIntrospector
)
{
super
(
delegate
,
config
,
serverIntrospector
);
...
...
@@ -66,21 +78,36 @@ public class OkHttpLoadBalancingClient
}
@Override
public
OkHttpRibbonResponse
execute
(
OkHttpRibbonRequest
ribbonRequest
,
public
OkHttpRibbonResponse
execute
(
final
OkHttpRibbonRequest
ribbonRequest
,
final
IClientConfig
configOverride
)
throws
Exception
{
boolean
secure
=
isSecure
(
configOverride
);
if
(
secure
)
{
final
URI
secureUri
=
UriComponentsBuilder
.
fromUri
(
ribbonRequest
.
getUri
())
return
this
.
executeWithRetry
(
ribbonRequest
,
new
RetryCallback
()
{
@Override
public
OkHttpRibbonResponse
doWithRetry
(
RetryContext
context
)
throws
Exception
{
//on retries the policy will choose the server and set it in the context
//extract the server and update the request being made
OkHttpRibbonRequest
newRequest
=
ribbonRequest
;
if
(
context
instanceof
LoadBalancedRetryContext
)
{
ServiceInstance
service
=
((
LoadBalancedRetryContext
)
context
).
getServiceInstance
();
if
(
service
!=
null
)
{
//Reconstruct the request URI using the host and port set in the retry context
newRequest
=
newRequest
.
withNewUri
(
new
URI
(
service
.
getUri
().
getScheme
(),
newRequest
.
getURI
().
getUserInfo
(),
service
.
getHost
(),
service
.
getPort
(),
newRequest
.
getURI
().
getPath
(),
newRequest
.
getURI
().
getQuery
(),
newRequest
.
getURI
().
getFragment
()));
}
}
if
(
isSecure
(
configOverride
))
{
final
URI
secureUri
=
UriComponentsBuilder
.
fromUri
(
newRequest
.
getUri
())
.
scheme
(
"https"
).
build
().
toUri
();
ribbonRequest
=
ribbon
Request
.
withNewUri
(
secureUri
);
newRequest
=
new
Request
.
withNewUri
(
secureUri
);
}
OkHttpClient
httpClient
=
getOkHttpClient
(
configOverride
,
secure
);
final
Request
request
=
ribbon
Request
.
toRequest
();
final
Request
request
=
new
Request
.
toRequest
();
Response
response
=
httpClient
.
newCall
(
request
).
execute
();
return
new
OkHttpRibbonResponse
(
response
,
ribbonRequest
.
getUri
());
return
new
OkHttpRibbonResponse
(
response
,
newRequest
.
getUri
());
}
});
}
OkHttpClient
getOkHttpClient
(
IClientConfig
configOverride
,
boolean
secure
)
{
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequest.java
View file @
7e6c7ee2
...
...
@@ -18,18 +18,29 @@
package
org
.
springframework
.
cloud
.
netflix
.
ribbon
.
support
;
import
com.netflix.client.ClientRequest
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.HttpRequest
;
import
org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext
;
import
org.springframework.util.MultiValueMap
;
import
java.net.URI
;
/**
* @author Spencer Gibb
* @author Ryan Baxter
*/
public
abstract
class
ContextAwareRequest
extends
ClientRequest
{
public
abstract
class
ContextAwareRequest
extends
ClientRequest
implements
HttpRequest
{
protected
final
RibbonCommandContext
context
;
private
HttpHeaders
httpHeaders
;
public
ContextAwareRequest
(
RibbonCommandContext
context
)
{
this
.
context
=
context
;
MultiValueMap
<
String
,
String
>
headers
=
context
.
getHeaders
();
this
.
httpHeaders
=
new
HttpHeaders
();
for
(
String
key
:
headers
.
keySet
())
{
this
.
httpHeaders
.
put
(
key
,
headers
.
get
(
key
));
}
this
.
uri
=
context
.
uri
();
this
.
isRetriable
=
context
.
getRetryable
();
}
...
...
@@ -38,6 +49,21 @@ public abstract class ContextAwareRequest extends ClientRequest {
return
context
;
}
@Override
public
HttpMethod
getMethod
()
{
return
HttpMethod
.
valueOf
(
context
.
getMethod
());
}
@Override
public
URI
getURI
()
{
return
this
.
getUri
();
}
@Override
public
HttpHeaders
getHeaders
()
{
return
httpHeaders
;
}
protected
RibbonCommandContext
newContext
(
URI
uri
)
{
RibbonCommandContext
commandContext
=
new
RibbonCommandContext
(
this
.
context
.
getServiceId
(),
this
.
context
.
getMethod
(),
uri
.
toString
(),
this
.
context
.
getRetryable
(),
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/support/RetryableLoadBalancingClient.java
0 → 100644
View file @
7e6c7ee2
/*
*
* Copyright 2013-2016 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
org
.
springframework
.
cloud
.
netflix
.
ribbon
.
support
;
import
java.io.IOException
;
import
org.apache.commons.lang.BooleanUtils
;
import
org.springframework.cloud.client.ServiceInstance
;
import
org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy
;
import
org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory
;
import
org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser
;
import
org.springframework.cloud.netflix.feign.ribbon.FeignRetryPolicy
;
import
org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient
;
import
org.springframework.cloud.netflix.ribbon.ServerIntrospector
;
import
org.springframework.http.HttpRequest
;
import
org.springframework.retry.RetryCallback
;
import
org.springframework.retry.policy.NeverRetryPolicy
;
import
org.springframework.retry.support.RetryTemplate
;
import
com.netflix.client.IResponse
;
import
com.netflix.client.RequestSpecificRetryHandler
;
import
com.netflix.client.RetryHandler
;
import
com.netflix.client.config.IClientConfig
;
import
com.netflix.loadbalancer.ILoadBalancer
;
import
com.netflix.loadbalancer.Server
;
/**
* A load balancing client which uses Spring Retry to retry failed requests.
* @author Ryan Baxter
*/
public
abstract
class
RetryableLoadBalancingClient
<
S
extends
ContextAwareRequest
,
T
extends
IResponse
,
D
>
extends
AbstractLoadBalancingClient
<
S
,
T
,
D
>
implements
ServiceInstanceChooser
{
protected
LoadBalancedRetryPolicyFactory
loadBalancedRetryPolicyFactory
=
new
LoadBalancedRetryPolicyFactory
.
NeverRetryFactory
();
@Deprecated
public
RetryableLoadBalancingClient
()
{
super
();
}
@Deprecated
public
RetryableLoadBalancingClient
(
final
ILoadBalancer
lb
)
{
super
(
lb
);
}
public
RetryableLoadBalancingClient
(
IClientConfig
config
,
ServerIntrospector
serverIntrospector
)
{
super
(
config
,
serverIntrospector
);
}
public
RetryableLoadBalancingClient
(
D
delegate
,
IClientConfig
config
,
ServerIntrospector
serverIntrospector
)
{
super
(
delegate
,
config
,
serverIntrospector
);
}
public
RetryableLoadBalancingClient
(
IClientConfig
iClientConfig
,
ServerIntrospector
serverIntrospector
,
LoadBalancedRetryPolicyFactory
loadBalancedRetryPolicyFactory
)
{
this
(
iClientConfig
,
serverIntrospector
);
this
.
loadBalancedRetryPolicyFactory
=
loadBalancedRetryPolicyFactory
;
}
/**
* Executes a {@link S} using Spring Retry.
* @param request The request to execute.
* @param callback The retry callback to use.
* @return The response.
* @throws Exception Thrown if there is an error making the request and a retry cannot be completed successfully.
*/
protected
T
executeWithRetry
(
S
request
,
RetryCallback
<
T
,
IOException
>
callback
)
throws
Exception
{
LoadBalancedRetryPolicy
retryPolicy
=
loadBalancedRetryPolicyFactory
.
create
(
this
.
getClientName
(),
this
);
RetryTemplate
retryTemplate
=
new
RetryTemplate
();
boolean
retryable
=
request
.
getContext
()
==
null
?
true
:
BooleanUtils
.
toBooleanDefaultIfNull
(
request
.
getContext
().
getRetryable
(),
true
);
retryTemplate
.
setRetryPolicy
(
retryPolicy
==
null
||
!
retryable
?
new
NeverRetryPolicy
()
:
new
RetryPolicy
(
request
,
retryPolicy
,
this
,
this
.
getClientName
()));
return
retryTemplate
.
execute
(
callback
);
}
@Override
public
ServiceInstance
choose
(
String
serviceId
)
{
Server
server
=
this
.
getLoadBalancer
().
chooseServer
(
serviceId
);
return
new
RibbonLoadBalancerClient
.
RibbonServer
(
serviceId
,
server
);
}
@Override
public
RequestSpecificRetryHandler
getRequestSpecificRetryHandler
(
S
request
,
IClientConfig
requestConfig
)
{
return
new
RequestSpecificRetryHandler
(
false
,
false
,
RetryHandler
.
DEFAULT
,
null
);
}
static
class
RetryPolicy
extends
FeignRetryPolicy
{
public
RetryPolicy
(
HttpRequest
request
,
LoadBalancedRetryPolicy
policy
,
ServiceInstanceChooser
serviceInstanceChooser
,
String
serviceName
)
{
super
(
request
,
policy
,
serviceInstanceChooser
,
serviceName
);
}
}
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java
View file @
7e6c7ee2
This diff is collapsed.
Click to expand it.
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/support/ContextAwareRequestTest.java
0 → 100644
View file @
7e6c7ee2
/*
*
* * Copyright 2013-2016 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
org
.
springframework
.
cloud
.
netflix
.
ribbon
.
support
;
import
java.net.URI
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
mockito
.
Mockito
.
doReturn
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* @author Ryan Baxter
*/
public
class
ContextAwareRequestTest
{
private
RibbonCommandContext
context
;
private
ContextAwareRequest
request
;
@Before
public
void
setUp
()
throws
Exception
{
context
=
mock
(
RibbonCommandContext
.
class
);
doReturn
(
"GET"
).
when
(
context
).
getMethod
();
MultiValueMap
<
String
,
String
>
headers
=
new
LinkedMultiValueMap
<>();
headers
.
put
(
"header1"
,
Collections
.<
String
>
emptyList
());
headers
.
put
(
"header2"
,
Arrays
.
asList
(
"value1"
,
"value2"
));
headers
.
put
(
"header3"
,
Arrays
.
asList
(
"value1"
));
doReturn
(
headers
).
when
(
context
).
getHeaders
();
doReturn
(
new
URI
(
"http://foo"
)).
when
(
context
).
uri
();
doReturn
(
"foo"
).
when
(
context
).
getServiceId
();
doReturn
(
new
LinkedMultiValueMap
<>()).
when
(
context
).
getParams
();
request
=
new
TestContextAwareRequest
(
context
);
}
@After
public
void
tearDown
()
throws
Exception
{
context
=
null
;
request
=
null
;
}
@Test
public
void
getContext
()
throws
Exception
{
assertEquals
(
context
,
request
.
getContext
());
}
@Test
public
void
getMethod
()
throws
Exception
{
assertEquals
(
HttpMethod
.
GET
,
request
.
getMethod
());
}
@Test
public
void
getURI
()
throws
Exception
{
assertEquals
(
new
URI
(
"http://foo"
),
request
.
getURI
());
RibbonCommandContext
badUriContext
=
mock
(
RibbonCommandContext
.
class
);
doReturn
(
new
LinkedMultiValueMap
()).
when
(
badUriContext
).
getHeaders
();
doReturn
(
"foobar"
).
when
(
badUriContext
).
getUri
();
ContextAwareRequest
badUriRequest
=
new
TestContextAwareRequest
(
badUriContext
);
assertNull
(
badUriRequest
.
getURI
());
}
@Test
public
void
getHeaders
()
throws
Exception
{
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
put
(
"header1"
,
Collections
.<
String
>
emptyList
());
headers
.
put
(
"header2"
,
Arrays
.
asList
(
"value1"
,
"value2"
));
headers
.
put
(
"header3"
,
Arrays
.
asList
(
"value1"
));
assertEquals
(
headers
,
request
.
getHeaders
());
}
static
class
TestContextAwareRequest
extends
ContextAwareRequest
{
public
TestContextAwareRequest
(
RibbonCommandContext
context
)
{
super
(
context
);
}
}
}
\ No newline at end of file
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/apache/HttpClientRibbonRetryIntegrationTests.java
0 → 100644
View file @
7e6c7ee2
/*
*
* * Copyright 2013-2016 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
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
route
.
apache
;
import
org.junit.runner.RunWith
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase
;
import
org.springframework.test.annotation.DirtiesContext
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
/**
* @author Ryan Baxter
*/
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
RibbonRetryIntegrationTestBase
.
RetryableTestConfig
.
class
,
webEnvironment
=
SpringBootTest
.
WebEnvironment
.
RANDOM_PORT
,
value
=
{
"zuul.retryable: false"
,
/* Disable retry by default, have each route enable it */
"hystrix.command.default.execution.timeout.enabled: false"
,
/* Disable hystrix so its timeout doesnt get in the way */
"ribbon.ReadTimeout: 1000"
,
/* Make sure ribbon will timeout before the thread is done sleeping */
"zuul.routes.retryable: /retryable/**"
,
"zuul.routes.retryable.retryable: true"
,
"retryable.ribbon.OkToRetryOnAllOperations: true"
,
"retryable.ribbon.MaxAutoRetries: 1"
,
"retryable.ribbon.MaxAutoRetriesNextServer: 1"
,
"zuul.routes.getretryable: /getretryable/**"
,
"zuul.routes.getretryable.retryable: true"
,
"getretryable.ribbon.MaxAutoRetries: 1"
,
"getretryable.ribbon.MaxAutoRetriesNextServer: 1"
,
"zuul.routes.disableretry: /disableretry/**"
,
"zuul.routes.disableretry.retryable: false"
,
/* This will override the global */
"disableretry.ribbon.MaxAutoRetries: 1"
,
"disableretry.ribbon.MaxAutoRetriesNextServer: 1"
,
"zuul.routes.globalretrydisabled: /globalretrydisabled/**"
,
"globalretrydisabled.ribbon.MaxAutoRetries: 1"
,
"globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1"
})
@DirtiesContext
public
class
HttpClientRibbonRetryIntegrationTests
extends
RibbonRetryIntegrationTestBase
{
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonRetryIntegrationTests.java
0 → 100644
View file @
7e6c7ee2
/*
*
* * Copyright 2013-2016 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
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
route
.
okhttp
;
import
org.junit.runner.RunWith
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase
;
import
org.springframework.test.annotation.DirtiesContext
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
/**
* @author Ryan Baxter
*/
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringBootTest
(
classes
=
RibbonRetryIntegrationTestBase
.
RetryableTestConfig
.
class
,
webEnvironment
=
SpringBootTest
.
WebEnvironment
.
RANDOM_PORT
,
value
=
{
"zuul.retryable: false"
,
/* Disable retry by default, have each route enable it */
"ribbon.okhttp.enabled: true"
,
"hystrix.command.default.execution.timeout.enabled: false"
,
/* Disable hystrix so its timeout doesnt get in the way */
"ribbon.ReadTimeout: 1000"
,
/* Make sure ribbon will timeout before the thread is done sleeping */
"zuul.routes.retryable: /retryable/**"
,
"zuul.routes.retryable.retryable: true"
,
"retryable.ribbon.OkToRetryOnAllOperations: true"
,
"retryable.ribbon.MaxAutoRetries: 1"
,
"retryable.ribbon.MaxAutoRetriesNextServer: 1"
,
"zuul.routes.getretryable: /getretryable/**"
,
"zuul.routes.getretryable.retryable: true"
,
"getretryable.ribbon.MaxAutoRetries: 1"
,
"getretryable.ribbon.MaxAutoRetriesNextServer: 1"
,
"zuul.routes.disableretry: /disableretry/**"
,
"zuul.routes.disableretry.retryable: false"
,
/* This will override the global */
"disableretry.ribbon.MaxAutoRetries: 1"
,
"disableretry.ribbon.MaxAutoRetriesNextServer: 1"
,
"zuul.routes.globalretrydisabled: /globalretrydisabled/**"
,
"globalretrydisabled.ribbon.MaxAutoRetries: 1"
,
"globalretrydisabled.ribbon.MaxAutoRetriesNextServer: 1"
})
@DirtiesContext
public
class
OkHttpRibbonRetryIntegrationTests
extends
RibbonRetryIntegrationTestBase
{
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonCommandFallbackTests.java
View file @
7e6c7ee2
...
...
@@ -52,7 +52,6 @@ public abstract class RibbonCommandFallbackTests {
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
System
.
out
.
println
(
"no fallback body: "
+
result
.
getBody
());
assertEquals
(
HttpStatus
.
INTERNAL_SERVER_ERROR
,
result
.
getStatusCode
());
}
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java
0 → 100644
View file @
7e6c7ee2
/*
*
* * Copyright 2013-2016 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
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
route
.
support
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.test.web.client.TestRestTemplate
;
import
org.springframework.cloud.netflix.ribbon.RibbonClient
;
import
org.springframework.cloud.netflix.ribbon.RibbonClients
;
import
org.springframework.cloud.netflix.ribbon.StaticServerList
;
import
org.springframework.cloud.netflix.zuul.EnableZuulProxy
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpEntity
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RestController
;
import
com.netflix.loadbalancer.Server
;
import
com.netflix.loadbalancer.ServerList
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
/**
* @author Ryan Baxter
*/
public
abstract
class
RibbonRetryIntegrationTestBase
{
@Value
(
"${local.server.port}"
)
protected
int
port
;
@Before
public
void
setup
()
{
String
uri
=
"/resetError"
;
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
}
@Test
public
void
retryable
()
{
String
uri
=
"/retryable/everyothererror"
;
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
result
.
getStatusCode
());
}
@Test
public
void
postRetryOK
()
{
String
uri
=
"/retryable/posteveryothererror"
;
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
POST
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
result
.
getStatusCode
());
}
@Test
public
void
getRetryable
()
{
String
uri
=
"/getretryable/everyothererror"
;
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
result
.
getStatusCode
());
}
@Test
public
void
postNotRetryable
()
{
String
uri
=
"/getretryable/posteveryothererror"
;
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
POST
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
INTERNAL_SERVER_ERROR
,
result
.
getStatusCode
());
}
@Test
public
void
disbaleRetry
()
{
String
uri
=
"/disableretry/everyothererror"
;
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
INTERNAL_SERVER_ERROR
,
result
.
getStatusCode
());
}
@Test
public
void
globalRetryDisabled
()
{
String
uri
=
"/globalretrydisabled/everyothererror"
;
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
uri
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
INTERNAL_SERVER_ERROR
,
result
.
getStatusCode
());
}
// Don't use @SpringBootApplication because we don't want to component scan
@Configuration
@EnableAutoConfiguration
@RestController
@EnableZuulProxy
@RibbonClients
({
@RibbonClient
(
name
=
"retryable"
,
configuration
=
RibbonClientConfiguration
.
class
),
@RibbonClient
(
name
=
"disableretry"
,
configuration
=
RibbonClientConfiguration
.
class
),
@RibbonClient
(
name
=
"globalretrydisabled"
,
configuration
=
RibbonClientConfiguration
.
class
),
@RibbonClient
(
name
=
"getretryable"
,
configuration
=
RibbonClientConfiguration
.
class
)})
public
static
class
RetryableTestConfig
{
private
boolean
error
=
true
;
@RequestMapping
(
"/resetError"
)
public
void
resetError
()
{
error
=
true
;
}
@RequestMapping
(
"/everyothererror"
)
public
ResponseEntity
<
String
>
timeout
()
{
boolean
shouldError
=
error
;
error
=
!
error
;
try
{
if
(
shouldError
)
{
Thread
.
sleep
(
80000
);
}
}
catch
(
InterruptedException
e
)
{
e
.
printStackTrace
();
}
return
new
ResponseEntity
<
String
>(
"no error"
,
HttpStatus
.
OK
);
}
@RequestMapping
(
path
=
"/posteveryothererror"
,
method
=
RequestMethod
.
POST
)
public
ResponseEntity
<
String
>
postTimeout
()
{
return
timeout
();
}
}
@Configuration
public
static
class
RibbonClientConfiguration
{
@Value
(
"${local.server.port}"
)
private
int
port
;
@Bean
public
ServerList
<
Server
>
ribbonServerList
()
{
return
new
StaticServerList
<>(
new
Server
(
"localhost"
,
this
.
port
));
}
}
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java
View file @
7e6c7ee2
...
...
@@ -375,7 +375,6 @@ public abstract class ZuulProxyTestBase {
e
.
printStackTrace
();
}
return
"slow"
;
}
@Bean
...
...
spring-cloud-netflix-eureka-client/pom.xml
View file @
7e6c7ee2
...
...
@@ -123,5 +123,15 @@
<artifactId>
spring-boot-starter-test
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework.retry
</groupId>
<artifactId>
spring-retry
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.springframework
</groupId>
<artifactId>
spring-aop
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
</project>
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