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
4720b78d
Commit
4720b78d
authored
Dec 16, 2015
by
Spencer Gibb
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #699 from stephaneLeroy/master
* pull699: Add Zuul Proxy regex serviceId to route mapping
parents
9f994870
4a52a7f8
Hide 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 @
4720b78d
...
...
@@ -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 @
4720b78d
...
...
@@ -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 @
4720b78d
...
...
@@ -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 @
4720b78d
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 @
4720b78d
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 @
4720b78d
...
...
@@ -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 @
4720b78d
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 @
4720b78d
...
...
@@ -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 @
4720b78d
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 @
4720b78d
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