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
e100207e
Commit
e100207e
authored
Jan 29, 2015
by
Dave Syer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Clarify and document some Feign stuff
parent
a7398842
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
128 additions
and
128 deletions
+128
-128
spring-cloud-netflix.adoc
docs/src/main/asciidoc/spring-cloud-netflix.adoc
+2
-2
FeignClientFactoryBean.java
...framework/cloud/netflix/feign/FeignClientFactoryBean.java
+87
-1
FeignClientScanRegistrar.java
...amework/cloud/netflix/feign/FeignClientScanRegistrar.java
+2
-2
FeignConfiguration.java
...ringframework/cloud/netflix/feign/FeignConfiguration.java
+0
-111
RibbonClient.java
...rg/springframework/cloud/netflix/ribbon/RibbonClient.java
+24
-0
FeignClientTests.java
...springframework/cloud/netflix/feign/FeignClientTests.java
+12
-11
SpringDecoderTests.java
...ringframework/cloud/netflix/feign/SpringDecoderTests.java
+1
-1
No files found.
docs/src/main/asciidoc/spring-cloud-netflix.adoc
View file @
e100207e
...
...
@@ -226,7 +226,7 @@ exclude it manually, e.g. in Maven
The Eureka server does not have a backend store, but the service
instances in the registry all have to send heartbeats to keep their
re
s
istrations up to date (so this can be done in memory). Clients also
re
g
istrations up to date (so this can be done in memory). Clients also
have an in-memory cache of eureka registrations (so they don't have to
go to the registry for every single request to a service).
...
...
@@ -481,7 +481,7 @@ configured server list, and you can supply the configuration like this
----
stores:
ribbon:
listOf
Client
s: example.com,google.com
listOf
Server
s: example.com,google.com
----
[[spring-cloud-ribbon]]
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java
View file @
e100207e
...
...
@@ -16,17 +16,33 @@
package
org
.
springframework
.
cloud
.
netflix
.
feign
;
import
java.util.List
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
org.springframework.beans.factory.FactoryBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
feign.Client
;
import
feign.Contract
;
import
feign.Feign
;
import
feign.Logger
;
import
feign.Request
;
import
feign.RequestInterceptor
;
import
feign.Retryer
;
import
feign.codec.Decoder
;
import
feign.codec.Encoder
;
import
feign.codec.ErrorDecoder
;
import
feign.ribbon.LoadBalancingTarget
;
import
feign.slf4j.Slf4jLogger
;
/**
* @author Spencer Gibb
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
class
FeignClientFactoryBean
extends
FeignConfiguration
implements
FactoryBean
<
Object
>
{
class
FeignClientFactoryBean
implements
FactoryBean
<
Object
>
{
private
boolean
loadbalance
;
...
...
@@ -34,6 +50,76 @@ class FeignClientFactoryBean extends FeignConfiguration implements FactoryBean<O
private
String
schemeName
;
@Autowired
private
Decoder
decoder
;
@Autowired
private
Encoder
encoder
;
@Autowired
private
Logger
logger
;
@Autowired
private
Contract
contract
;
@Autowired
(
required
=
false
)
private
Logger
.
Level
logLevel
;
@Autowired
(
required
=
false
)
private
Retryer
retryer
;
@Autowired
(
required
=
false
)
private
ErrorDecoder
errorDecoder
;
@Autowired
(
required
=
false
)
private
Request
.
Options
options
;
@Autowired
(
required
=
false
)
private
Client
ribbonClient
;
@Autowired
(
required
=
false
)
private
List
<
RequestInterceptor
>
requestInterceptors
;
protected
Feign
.
Builder
feign
()
{
Feign
.
Builder
builder
=
Feign
.
builder
()
// required values
.
logger
(
this
.
logger
).
encoder
(
this
.
encoder
).
decoder
(
this
.
decoder
)
.
contract
(
this
.
contract
);
// optional values
if
(
this
.
logLevel
!=
null
)
{
builder
.
logLevel
(
this
.
logLevel
);
}
if
(
this
.
retryer
!=
null
)
{
builder
.
retryer
(
this
.
retryer
);
}
if
(
this
.
errorDecoder
!=
null
)
{
builder
.
errorDecoder
(
this
.
errorDecoder
);
}
if
(
this
.
options
!=
null
)
{
builder
.
options
(
this
.
options
);
}
if
(
this
.
requestInterceptors
!=
null
)
{
builder
.
requestInterceptors
(
this
.
requestInterceptors
);
}
return
builder
;
}
protected
<
T
>
T
loadBalance
(
Class
<
T
>
type
,
String
schemeName
)
{
return
loadBalance
(
feign
(),
type
,
schemeName
);
}
protected
<
T
>
T
loadBalance
(
Feign
.
Builder
builder
,
Class
<
T
>
type
,
String
schemeName
)
{
builder
.
logger
(
new
Slf4jLogger
(
type
));
// TODO: how to have choice here?
if
(
this
.
ribbonClient
!=
null
)
{
return
builder
.
client
(
this
.
ribbonClient
).
target
(
type
,
schemeName
);
}
else
{
return
builder
.
target
(
LoadBalancingTarget
.
create
(
type
,
schemeName
));
}
}
@Override
public
Object
getObject
()
throws
Exception
{
if
(!
this
.
schemeName
.
startsWith
(
"http"
))
{
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientScanRegistrar.java
View file @
e100207e
...
...
@@ -41,8 +41,8 @@ import org.springframework.util.StringUtils;
/**
* @author Spencer Gibb
*/
public
class
FeignClientScanRegistrar
extends
FeignConfiguration
implements
ImportBeanDefinitionRegistrar
,
ResourceLoaderAware
,
BeanClassLoaderAware
{
public
class
FeignClientScanRegistrar
implements
ImportBeanDefinitionRegistrar
,
ResourceLoaderAware
,
BeanClassLoaderAware
{
// patterned after Spring Integration IntegrationComponentScanRegistrar
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignConfiguration.java
deleted
100644 → 0
View file @
a7398842
/*
* Copyright 2013-2015 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
.
feign
;
import
java.util.List
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cloud.netflix.archaius.ConfigurableEnvironmentConfiguration
;
import
org.springframework.context.annotation.Configuration
;
import
feign.*
;
import
feign.codec.Decoder
;
import
feign.codec.Encoder
;
import
feign.codec.ErrorDecoder
;
import
feign.ribbon.LoadBalancingTarget
;
import
feign.slf4j.Slf4jLogger
;
/**
* @author Spencer Gibb
*/
@Configuration
public
class
FeignConfiguration
{
@Autowired
ConfigurableEnvironmentConfiguration
envConfig
;
// FIXME: howto enforce this?
@Autowired
private
Decoder
decoder
;
@Autowired
private
Encoder
encoder
;
@Autowired
private
Logger
logger
;
@Autowired
private
Contract
contract
;
@Autowired
(
required
=
false
)
private
Logger
.
Level
logLevel
;
@Autowired
(
required
=
false
)
private
Retryer
retryer
;
@Autowired
(
required
=
false
)
private
ErrorDecoder
errorDecoder
;
@Autowired
(
required
=
false
)
private
Request
.
Options
options
;
@Autowired
(
required
=
false
)
private
Client
ribbonClient
;
@Autowired
(
required
=
false
)
private
List
<
RequestInterceptor
>
requestInterceptors
;
protected
Feign
.
Builder
feign
()
{
Feign
.
Builder
builder
=
Feign
.
builder
()
// required values
.
logger
(
this
.
logger
).
encoder
(
this
.
encoder
).
decoder
(
this
.
decoder
)
.
contract
(
this
.
contract
);
// optional values
if
(
this
.
logLevel
!=
null
)
{
builder
.
logLevel
(
this
.
logLevel
);
}
if
(
this
.
retryer
!=
null
)
{
builder
.
retryer
(
this
.
retryer
);
}
if
(
this
.
errorDecoder
!=
null
)
{
builder
.
errorDecoder
(
this
.
errorDecoder
);
}
if
(
this
.
options
!=
null
)
{
builder
.
options
(
this
.
options
);
}
if
(
this
.
requestInterceptors
!=
null
)
{
builder
.
requestInterceptors
(
requestInterceptors
);
}
return
builder
;
}
protected
<
T
>
T
loadBalance
(
Class
<
T
>
type
,
String
schemeName
)
{
return
loadBalance
(
feign
(),
type
,
schemeName
);
}
protected
<
T
>
T
loadBalance
(
Feign
.
Builder
builder
,
Class
<
T
>
type
,
String
schemeName
)
{
builder
.
logger
(
new
Slf4jLogger
(
type
));
// TODO: how to have choice here?
if
(
this
.
ribbonClient
!=
null
)
{
return
builder
.
client
(
this
.
ribbonClient
).
target
(
type
,
schemeName
);
}
else
{
return
builder
.
target
(
LoadBalancingTarget
.
create
(
type
,
schemeName
));
}
}
}
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonClient.java
View file @
e100207e
...
...
@@ -25,7 +25,15 @@ import java.lang.annotation.Target;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Import
;
import
com.netflix.loadbalancer.ILoadBalancer
;
import
com.netflix.loadbalancer.IRule
;
import
com.netflix.loadbalancer.ServerListFilter
;
/**
* Declarative configuration for a ribbon client. Add this annotation to any
* <code>@Configuration</code> and then inject a {@link SpringClientFactory} to access the
* client that is created.
*
* @author Dave Syer
*/
@Configuration
...
...
@@ -35,10 +43,26 @@ import org.springframework.context.annotation.Import;
@Documented
public
@interface
RibbonClient
{
/**
* Synonym for name (the name of the client)
*
* @see #name()
*/
String
value
()
default
""
;
/**
* The name of the ribbon client, uniquely identifying a set of client resources,
* including a load balancer.
*/
String
name
()
default
""
;
/**
* A custom <code>@Configuration</code> for the ribbon client. Can contain override
* <code>@Bean</code> definition for the pieces that make up the client, for instance
* {@link ILoadBalancer}, {@link ServerListFilter}, {@link IRule}.
*
* @see RibbonClientConfiguration for the defaults
*/
Class
<?>[]
configuration
()
default
{};
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/FeignClientTests.java
View file @
e100207e
...
...
@@ -16,9 +16,6 @@
package
org
.
springframework
.
cloud
.
netflix
.
feign
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.lang.reflect.InvocationHandler
;
import
java.lang.reflect.Proxy
;
import
java.util.ArrayList
;
...
...
@@ -55,7 +52,9 @@ import com.netflix.loadbalancer.Server;
import
feign.RequestInterceptor
;
import
feign.RequestTemplate
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
/**
* @author Spencer Gibb
...
...
@@ -65,7 +64,7 @@ import static org.junit.Assert.*;
@WebAppConfiguration
@IntegrationTest
({
"server.port=0"
,
"spring.application.name=feignclienttest"
})
@DirtiesContext
public
class
FeignClientTests
extends
FeignConfiguration
{
public
class
FeignClientTests
{
@Value
(
"${local.server.port}"
)
private
int
port
=
0
;
...
...
@@ -169,24 +168,26 @@ public class FeignClientTests extends FeignConfiguration {
@Test
public
void
testSimpleType
()
{
Hello
hello
=
testClient
.
getHello
();
Hello
hello
=
t
his
.
t
estClient
.
getHello
();
assertNotNull
(
"hello was null"
,
hello
);
assertEquals
(
"first hello didn't match"
,
new
Hello
(
"hello world 1"
),
hello
);
}
@Test
public
void
testGenericType
()
{
List
<
Hello
>
hellos
=
testClient
.
getHellos
();
List
<
Hello
>
hellos
=
t
his
.
t
estClient
.
getHellos
();
assertNotNull
(
"hellos was null"
,
hellos
);
assertEquals
(
"hellos didn't match"
,
hellos
,
getHelloList
());
}
@Test
public
void
testRequestInterceptors
()
{
List
<
String
>
headers
=
testClient
.
getHelloHeaders
();
List
<
String
>
headers
=
t
his
.
t
estClient
.
getHelloHeaders
();
assertNotNull
(
"headers was null"
,
headers
);
assertTrue
(
"headers didn't contain myheader1value"
,
headers
.
contains
(
"myheader1value"
));
assertTrue
(
"headers didn't contain myheader2value"
,
headers
.
contains
(
"myheader2value"
));
assertTrue
(
"headers didn't contain myheader1value"
,
headers
.
contains
(
"myheader1value"
));
assertTrue
(
"headers didn't contain myheader2value"
,
headers
.
contains
(
"myheader2value"
));
}
@Data
...
...
@@ -207,7 +208,7 @@ class LocalRibbonClientConfiguration {
@Bean
public
ILoadBalancer
ribbonLoadBalancer
()
{
BaseLoadBalancer
balancer
=
new
BaseLoadBalancer
();
balancer
.
setServersList
(
Arrays
.
asList
(
new
Server
(
"localhost"
,
port
)));
balancer
.
setServersList
(
Arrays
.
asList
(
new
Server
(
"localhost"
,
this
.
port
)));
return
balancer
;
}
...
...
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/SpringDecoderTests.java
View file @
e100207e
...
...
@@ -50,7 +50,7 @@ import static org.junit.Assert.assertNotNull;
@IntegrationTest
({
"server.port=0"
,
"spring.application.name=springdecodertest"
,
"spring.jmx.enabled=true"
})
@DirtiesContext
public
class
SpringDecoderTests
extends
FeignC
onfiguratio
n
{
public
class
SpringDecoderTests
extends
FeignC
lientFactoryBea
n
{
@Value
(
"${local.server.port}"
)
private
int
port
=
0
;
...
...
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