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
4a52a7f8
Commit
4a52a7f8
authored
Dec 10, 2015
by
Stéphane Leroy
Committed by
Spencer Gibb
Dec 16, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Zuul Proxy regex serviceId to route mapping
fixes gh-693
parent
9f994870
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
394 additions
and
17 deletions
+394
-17
spring-cloud-netflix.adoc
docs/src/main/asciidoc/spring-cloud-netflix.adoc
+20
-0
ZuulProxyConfiguration.java
...gframework/cloud/netflix/zuul/ZuulProxyConfiguration.java
+31
-3
ProxyRouteLocator.java
...amework/cloud/netflix/zuul/filters/ProxyRouteLocator.java
+14
-2
ServiceRouteMapper.java
...mework/cloud/netflix/zuul/filters/ServiceRouteMapper.java
+18
-0
SimpleServiceRouteMapper.java
.../cloud/netflix/zuul/filters/SimpleServiceRouteMapper.java
+13
-0
ZuulProperties.java
...gframework/cloud/netflix/zuul/filters/ZuulProperties.java
+16
-4
RegExServiceRouteMapper.java
...d/netflix/zuul/filters/regex/RegExServiceRouteMapper.java
+70
-0
ProxyRouteLocatorTests.java
...rk/cloud/netflix/zuul/filters/ProxyRouteLocatorTests.java
+37
-8
RegExServiceRouteMapperIntegrationTests.java
...ilters/regex/RegExServiceRouteMapperIntegrationTests.java
+127
-0
RegExServiceRouteMapperTests.java
...flix/zuul/filters/regex/RegExServiceRouteMapperTests.java
+48
-0
No files found.
docs/src/main/asciidoc/spring-cloud-netflix.adoc
View file @
4a52a7f8
...
...
@@ -1093,6 +1093,26 @@ users:
listOfServers: example.com,google.com
----
You can provide convention between serviceId and routes using regexmapper.
It uses regular expression named group to extract variables from serviceId and inject them
into a route pattern.
.application.yml
[source,yaml]
----
zuul:
regexMapper:
enabled: true
servicePattern: "(?<name>^.+)-(?<version>v.+$)"
routePattern: "${version}/${name}"
----
This means that a serviceId "myusers-v1" will be mapped to route "/v1/myusers/**".
Any regular expression is accepted but all named group must be present in both servicePattern and routePattern.
If servicePattern do not match a serviceId, the default behavior is used. In exemple above,
a serviceId "myusers" will be mapped to route "/myusers/**" (no version detected)
These feature is disable by default and is only applied to discovered services.
To add a prefix to all mappings, set `zuul.prefix` to a value, such as
`/api`. The proxy prefix is stripped from the request before the
request is forwarded by default (switch this behaviour off with
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulProxyConfiguration.java
View file @
4a52a7f8
...
...
@@ -21,6 +21,7 @@ import org.springframework.boot.actuate.endpoint.Endpoint;
import
org.springframework.boot.actuate.trace.TraceRepository
;
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.autoconfigure.web.ServerProperties
;
import
org.springframework.cloud.client.actuator.HasFeatures
;
import
org.springframework.cloud.client.discovery.DiscoveryClient
;
...
...
@@ -32,8 +33,11 @@ import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEven
import
org.springframework.cloud.netflix.ribbon.SpringClientFactory
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator
;
import
org.springframework.cloud.netflix.zuul.filters.ServiceRouteMapper
;
import
org.springframework.cloud.netflix.zuul.filters.SimpleServiceRouteMapper
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties
;
import
org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter
;
import
org.springframework.cloud.netflix.zuul.filters.regex.RegExServiceRouteMapper
;
import
org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonCommandFactory
;
import
org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory
;
import
org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter
;
...
...
@@ -66,6 +70,9 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
@Autowired
private
ServerProperties
server
;
@Autowired
private
ServiceRouteMapper
serviceRouteMapper
;
@Override
public
HasFeatures
zuulFeature
()
{
return
HasFeatures
.
namedFeature
(
"Zuul (Discovery)"
,
ZuulProxyConfiguration
.
class
);
...
...
@@ -75,7 +82,7 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
@Override
public
ProxyRouteLocator
routeLocator
()
{
return
new
ProxyRouteLocator
(
this
.
server
.
getServletPrefix
(),
this
.
discovery
,
this
.
zuulProperties
);
this
.
zuulProperties
,
serviceRouteMapper
);
}
@Bean
...
...
@@ -86,8 +93,8 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
// pre filters
@Bean
public
PreDecorationFilter
preDecorationFilter
()
{
return
new
PreDecorationFilter
(
routeLocator
()
,
public
PreDecorationFilter
preDecorationFilter
(
ProxyRouteLocator
routeLocator
)
{
return
new
PreDecorationFilter
(
routeLocator
,
this
.
zuulProperties
.
isAddProxyHeaders
());
}
...
...
@@ -118,6 +125,27 @@ public class ZuulProxyConfiguration extends ZuulConfiguration {
}
@Configuration
@ConditionalOnProperty
(
name
=
"zuul.regexMapper.enabled"
,
matchIfMissing
=
false
)
protected
static
class
RegexServiceRouteMapperConfiguration
{
@Bean
public
ServiceRouteMapper
serviceRouteMapper
(
ZuulProperties
props
)
{
return
new
RegExServiceRouteMapper
(
props
.
getRegexMapper
().
getServicePattern
(),
props
.
getRegexMapper
().
getRoutePattern
());
}
}
@Configuration
@ConditionalOnMissingBean
(
ServiceRouteMapper
.
class
)
protected
static
class
SimpleServiceRouteMapperConfiguration
{
@Bean
public
ServiceRouteMapper
serviceRouteMapper
()
{
return
new
SimpleServiceRouteMapper
();
}
}
@Configuration
@ConditionalOnClass
(
Endpoint
.
class
)
protected
static
class
RoutesEndpointConfiguration
{
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRouteLocator.java
View file @
4a52a7f8
...
...
@@ -55,6 +55,8 @@ public class ProxyRouteLocator implements RouteLocator {
private
String
servletPath
;
private
ServiceRouteMapper
serviceRouteMapper
;
public
ProxyRouteLocator
(
String
servletPath
,
DiscoveryClient
discovery
,
ZuulProperties
properties
)
{
if
(
StringUtils
.
hasText
(
servletPath
))
{
// a servletPath is passed explicitly
...
...
@@ -75,11 +77,17 @@ public class ProxyRouteLocator implements RouteLocator {
}
}
}
this
.
serviceRouteMapper
=
new
SimpleServiceRouteMapper
();
this
.
discovery
=
discovery
;
this
.
properties
=
properties
;
}
public
ProxyRouteLocator
(
String
servletPath
,
DiscoveryClient
discovery
,
ZuulProperties
properties
,
ServiceRouteMapper
serviceRouteMapper
)
{
this
(
servletPath
,
discovery
,
properties
);
this
.
serviceRouteMapper
=
serviceRouteMapper
;
}
public
void
addRoute
(
String
path
,
String
location
)
{
this
.
staticRoutes
.
put
(
path
,
new
ZuulRoute
(
path
,
location
));
resetRoutes
();
...
...
@@ -196,7 +204,7 @@ public class ProxyRouteLocator implements RouteLocator {
for
(
String
serviceId
:
services
)
{
// Ignore specifically ignored services and those that were manually
// configured
String
key
=
"/"
+
serviceId
+
"/**"
;
String
key
=
"/"
+
mapRouteToService
(
serviceId
)
+
"/**"
;
if
(
staticServices
.
containsKey
(
serviceId
)
&&
staticServices
.
get
(
serviceId
).
getUrl
()
==
null
)
{
// Explicitly configured with no URL, cannot be ignored
...
...
@@ -238,6 +246,10 @@ public class ProxyRouteLocator implements RouteLocator {
return
values
;
}
protected
String
mapRouteToService
(
String
serviceId
)
{
return
this
.
serviceRouteMapper
.
apply
(
serviceId
);
}
protected
void
addConfiguredRoutes
(
Map
<
String
,
ZuulRoute
>
routes
)
{
Map
<
String
,
ZuulRoute
>
routeEntries
=
this
.
properties
.
getRoutes
();
for
(
ZuulRoute
entry
:
routeEntries
.
values
())
{
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ServiceRouteMapper.java
0 → 100644
View file @
4a52a7f8
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
;
/**
* @author Stéphane LEROY
*
* Provide a way to apply convention between routes and discovered services name.
*
*/
public
interface
ServiceRouteMapper
{
/**
* Take a service Id (its discovered name) and return a route path.
*
* @param serviceId service discovered name
* @return route path
*/
String
apply
(
String
serviceId
);
}
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/SimpleServiceRouteMapper.java
0 → 100644
View file @
4a52a7f8
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
;
/**
* @author Stéphane Leroy
*
* A simple passthru service route mapper.
*/
public
class
SimpleServiceRouteMapper
implements
ServiceRouteMapper
{
@Override
public
String
apply
(
String
serviceId
)
{
return
serviceId
;
}
}
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java
View file @
4a52a7f8
...
...
@@ -21,16 +21,15 @@ import java.util.LinkedHashMap;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
javax.annotation.PostConstruct
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.util.StringUtils
;
import
lombok.AllArgsConstructor
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.util.StringUtils
;
/**
* @author Spencer Gibb
* @author Dave Syer
...
...
@@ -57,6 +56,8 @@ public class ZuulProperties {
private
boolean
ignoreLocalService
=
true
;
private
RegexMapper
regexMapper
=
new
RegexMapper
();
@PostConstruct
public
void
init
()
{
for
(
Entry
<
String
,
ZuulRoute
>
entry
:
this
.
routes
.
entrySet
())
{
...
...
@@ -76,6 +77,17 @@ public class ZuulProperties {
@Data
@AllArgsConstructor
@NoArgsConstructor
public
static
class
RegexMapper
{
private
boolean
enabled
=
false
;
private
String
servicePattern
=
"(?<name>.*)-(?<version>v.*$)"
;
private
String
routePattern
=
"${version}/${name}"
;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public
static
class
ZuulRoute
{
private
String
id
;
...
...
spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/regex/RegExServiceRouteMapper.java
0 → 100644
View file @
4a52a7f8
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
regex
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
import
org.springframework.cloud.netflix.zuul.filters.ServiceRouteMapper
;
import
org.springframework.util.StringUtils
;
/**
* @author Stéphane Leroy
*
* This service route mapper use Java 7 RegEx named group feature to rewrite a discovered
* service Id into a route.
*
* Ex : If we want to map service Id [rest-service-v1] to /v1/rest-service/** route
* service pattern : "(?<name>.*)-(?<version>v.*$)" route pattern : "${version}/${name}"
*
* /!\ This implementation use Matcher.replaceFirst so only one match will be replace.
*/
public
class
RegExServiceRouteMapper
implements
ServiceRouteMapper
{
/**
* A RegExp Pattern that extract needed information from a service ID. Ex :
* "(?<name>.*)-(?<version>v.*$)"
*/
private
Pattern
servicePattern
;
/**
* A RegExp that refer to named groups define in servicePattern. Ex :
* "${version}/${name}"
*/
private
String
routePattern
;
public
RegExServiceRouteMapper
(
String
servicePattern
,
String
routePattern
)
{
this
.
servicePattern
=
Pattern
.
compile
(
servicePattern
);
this
.
routePattern
=
routePattern
;
}
/**
* Use servicePattern to extract groups and routePattern to construct the route.
*
* If there is no matches, the serviceId is returned.
*
* @param serviceId service discovered name
* @return route path
*/
@Override
public
String
apply
(
String
serviceId
)
{
Matcher
matcher
=
servicePattern
.
matcher
(
serviceId
);
String
route
=
matcher
.
replaceFirst
(
routePattern
);
route
=
cleanRoute
(
route
);
return
(
StringUtils
.
hasText
(
route
)
?
route
:
serviceId
);
}
/**
* Route with regex and replace can be a bit messy when used with conditional named
* group. We clean here first and trailing '/' and remove multiple consecutive '/'
* @param route
* @return
*/
private
String
cleanRoute
(
final
String
route
)
{
String
routeToClean
=
route
.
replaceAll
(
"/{2,}"
,
"/"
);
if
(
routeToClean
.
startsWith
(
"/"
))
{
routeToClean
=
routeToClean
.
substring
(
1
);
}
if
(
routeToClean
.
endsWith
(
"/"
))
{
routeToClean
=
routeToClean
.
substring
(
0
,
routeToClean
.
length
()
-
1
);
}
return
routeToClean
;
}
}
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRouteLocatorTests.java
View file @
4a52a7f8
...
...
@@ -16,14 +16,6 @@
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
BDDMockito
.
given
;
import
static
org
.
mockito
.
MockitoAnnotations
.
initMocks
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
...
...
@@ -35,8 +27,17 @@ import org.springframework.cloud.client.DefaultServiceInstance;
import
org.springframework.cloud.client.discovery.DiscoveryClient
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator.ProxyRouteSpec
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute
;
import
org.springframework.cloud.netflix.zuul.filters.regex.RegExServiceRouteMapper
;
import
org.springframework.core.env.ConfigurableEnvironment
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
mockito
.
BDDMockito
.
given
;
import
static
org
.
mockito
.
MockitoAnnotations
.
initMocks
;
/**
* @author Spencer Gibb
* @author Dave Syer
...
...
@@ -518,6 +519,34 @@ public class ProxyRouteLocatorTests {
assertMapping
(
routesMap
,
MYSERVICE
);
}
@Test
public
void
testRegExServiceRouteMapperNoServiceIdMatches
()
{
given
(
this
.
discovery
.
getServices
()).
willReturn
(
Collections
.
singletonList
(
MYSERVICE
));
RegExServiceRouteMapper
regExServiceRouteMapper
=
new
RegExServiceRouteMapper
(
properties
.
getRegexMapper
().
getServicePattern
(),
properties
.
getRegexMapper
().
getRoutePattern
());
ProxyRouteLocator
routeLocator
=
new
ProxyRouteLocator
(
"/"
,
this
.
discovery
,
this
.
properties
,
regExServiceRouteMapper
);
Map
<
String
,
String
>
routesMap
=
routeLocator
.
getRoutes
();
assertNotNull
(
"routesMap was null"
,
routesMap
);
assertFalse
(
"routesMap was empty"
,
routesMap
.
isEmpty
());
assertMapping
(
routesMap
,
MYSERVICE
);
}
@Test
public
void
testRegExServiceRouteMapperServiceIdMatches
()
{
given
(
this
.
discovery
.
getServices
()).
willReturn
(
Collections
.
singletonList
(
"rest-service-v1"
));
RegExServiceRouteMapper
regExServiceRouteMapper
=
new
RegExServiceRouteMapper
(
properties
.
getRegexMapper
().
getServicePattern
(),
properties
.
getRegexMapper
().
getRoutePattern
());
ProxyRouteLocator
routeLocator
=
new
ProxyRouteLocator
(
"/"
,
this
.
discovery
,
this
.
properties
,
regExServiceRouteMapper
);
Map
<
String
,
String
>
routesMap
=
routeLocator
.
getRoutes
();
assertNotNull
(
"routesMap was null"
,
routesMap
);
assertFalse
(
"routesMap was empty"
,
routesMap
.
isEmpty
());
assertMapping
(
routesMap
,
"rest-service-v1"
,
"v1/rest-service"
);
}
protected
void
assertMapping
(
Map
<
String
,
String
>
routesMap
,
String
serviceId
)
{
assertMapping
(
routesMap
,
serviceId
,
serviceId
);
...
...
spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/regex/RegExServiceRouteMapperIntegrationTests.java
0 → 100644
View file @
4a52a7f8
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
regex
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.test.SpringApplicationConfiguration
;
import
org.springframework.boot.test.TestRestTemplate
;
import
org.springframework.boot.test.WebIntegrationTest
;
import
org.springframework.cloud.client.discovery.DiscoveryClient
;
import
org.springframework.cloud.netflix.ribbon.RibbonClient
;
import
org.springframework.cloud.netflix.ribbon.StaticServerList
;
import
org.springframework.cloud.netflix.zuul.EnableZuulProxy
;
import
org.springframework.cloud.netflix.zuul.RoutesEndpoint
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator
;
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.test.annotation.DirtiesContext
;
import
org.springframework.test.context.TestPropertySource
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.web.bind.annotation.PathVariable
;
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
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
when
;
import
static
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
regex
.
RegExServiceRouteMapperIntegrationTests
.
SERVICE_ID
;
/**
* @author Stéphane Leroy
*/
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringApplicationConfiguration
(
classes
=
SampleCustomZuulProxyApplication
.
class
)
@WebIntegrationTest
(
value
=
{
"spring.application.name=regex-test-application"
,
"spring.jmx.enabled=true"
},
randomPort
=
true
)
@TestPropertySource
(
properties
=
{
"eureka.client.enabled=false"
,
"zuul.regexMapper.enabled=true"
,
"zuul.regexMapper.servicePattern=(?<domain>^.+)-(?<name>.+)-(?<version>v.+$)"
,
"zuul.regexMapper.routePattern=${version}/${domain}/${name}"
})
@DirtiesContext
public
class
RegExServiceRouteMapperIntegrationTests
{
protected
static
final
String
SERVICE_ID
=
"domain-service-v1"
;
@Value
(
"${local.server.port}"
)
private
int
port
;
@Autowired
private
ProxyRouteLocator
routes
;
@Autowired
private
RoutesEndpoint
endpoint
;
@Test
public
void
getRegexMappedService
()
{
endpoint
.
reset
();
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
"/v1/domain/service/get/1"
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
result
.
getStatusCode
());
assertEquals
(
"Get 1"
,
result
.
getBody
());
}
@Test
public
void
getStaticRoute
()
{
this
.
routes
.
addRoute
(
"/self/**"
,
"http://localhost:"
+
this
.
port
);
endpoint
.
reset
();
ResponseEntity
<
String
>
result
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
this
.
port
+
"/self/get/1"
,
HttpMethod
.
GET
,
new
HttpEntity
<>((
Void
)
null
),
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
result
.
getStatusCode
());
assertEquals
(
"Get 1"
,
result
.
getBody
());
}
}
@Configuration
@EnableAutoConfiguration
@RestController
@EnableZuulProxy
@RibbonClient
(
value
=
SERVICE_ID
,
configuration
=
SimpleRibbonClientConfiguration
.
class
)
class
SampleCustomZuulProxyApplication
{
@Bean
public
DiscoveryClient
discoveryClient
()
{
DiscoveryClient
discoveryClient
=
mock
(
DiscoveryClient
.
class
);
List
<
String
>
services
=
new
ArrayList
<>();
services
.
add
(
SERVICE_ID
);
when
(
discoveryClient
.
getServices
()).
thenReturn
(
services
);
return
discoveryClient
;
}
@RequestMapping
(
value
=
"/get/{id}"
,
method
=
RequestMethod
.
GET
)
public
String
get
(
@PathVariable
String
id
)
{
return
"Get "
+
id
;
}
public
static
void
main
(
String
[]
args
)
{
SpringApplication
.
run
(
SampleCustomZuulProxyApplication
.
class
,
args
);
}
}
@Configuration
class
SimpleRibbonClientConfiguration
{
@Value
(
"${local.server.port}"
)
private
int
port
=
0
;
@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/regex/RegExServiceRouteMapperTests.java
0 → 100644
View file @
4a52a7f8
package
org
.
springframework
.
cloud
.
netflix
.
zuul
.
filters
.
regex
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
/**
* @author Stéphane Leroy
*/
public
class
RegExServiceRouteMapperTests
{
/**
* Service pattern that follow convention {domain}-{name}-{version}. The name is
* optional
*/
public
static
final
String
SERVICE_PATTERN
=
"(?<domain>^\\w+)(-(?<name>\\w+)-|-)(?<version>v\\d+$)"
;
public
static
final
String
ROUTE_PATTERN
=
"${version}/${domain}/${name}"
;
@Test
public
void
test_return_mapped_route_if_serviceid_matches
()
{
RegExServiceRouteMapper
toTest
=
new
RegExServiceRouteMapper
(
SERVICE_PATTERN
,
ROUTE_PATTERN
);
assertEquals
(
"service version convention"
,
"v1/rest/service"
,
toTest
.
apply
(
"rest-service-v1"
));
}
@Test
public
void
test_return_serviceid_if_no_matches
()
{
RegExServiceRouteMapper
toTest
=
new
RegExServiceRouteMapper
(
SERVICE_PATTERN
,
ROUTE_PATTERN
);
// No version here
assertEquals
(
"No matches for this service id"
,
"rest-service"
,
toTest
.
apply
(
"rest-service"
));
}
@Test
public
void
test_route_should_be_cleaned_before_returned
()
{
// Messy patterns
RegExServiceRouteMapper
toTest
=
new
RegExServiceRouteMapper
(
SERVICE_PATTERN
+
"(?<nevermatch>.)?"
,
"/${version}/${nevermatch}/${domain}/${name}/"
);
assertEquals
(
"No matches for this service id"
,
"v1/domain/service"
,
toTest
.
apply
(
"domain-service-v1"
));
assertEquals
(
"No matches for this service id"
,
"v1/domain"
,
toTest
.
apply
(
"domain-v1"
));
}
}
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