Adds option to lower case routes to services.

fixes gh-302
This commit is contained in:
Spencer Gibb
2018-04-27 15:06:31 -04:00
parent 3d2364a570
commit b091f47312
3 changed files with 82 additions and 5 deletions

View File

@@ -28,6 +28,7 @@ import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
import org.springframework.core.style.ToStringCreator;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.SimpleEvaluationContext;
@@ -84,11 +85,13 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
String uri = urlExpr.getValue(evalCtxt, instance, String.class);
routeDefinition.setUri(URI.create(uri));
final ServiceInstance instanceForEval = new DelegatingServiceInstance(instance, properties);
for (PredicateDefinition original : this.properties.getPredicates()) {
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(original.getName());
for (Map.Entry<String, String> entry : original.getArgs().entrySet()) {
String value = getValueFromExpr(evalCtxt, parser, instance, entry);
String value = getValueFromExpr(evalCtxt, parser, instanceForEval, entry);
predicate.addArg(entry.getKey(), value);
}
routeDefinition.getPredicates().add(predicate);
@@ -98,7 +101,7 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
FilterDefinition filter = new FilterDefinition();
filter.setName(original.getName());
for (Map.Entry<String, String> entry : original.getArgs().entrySet()) {
String value = getValueFromExpr(evalCtxt, parser, instance, entry);
String value = getValueFromExpr(evalCtxt, parser, instanceForEval, entry);
filter.addArg(entry.getKey(), value);
}
routeDefinition.getFilters().add(filter);
@@ -112,4 +115,61 @@ public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLoc
Expression valueExpr = parser.parseExpression(entry.getValue());
return valueExpr.getValue(evalCtxt, instance, String.class);
}
private static class DelegatingServiceInstance implements ServiceInstance {
final ServiceInstance delegate;
private final DiscoveryLocatorProperties properties;
private DelegatingServiceInstance(ServiceInstance delegate, DiscoveryLocatorProperties properties) {
this.delegate = delegate;
this.properties = properties;
}
@Override
public String getServiceId() {
if (properties.isLowerCaseServiceId()) {
return delegate.getServiceId().toLowerCase();
}
return delegate.getServiceId();
}
@Override
public String getHost() {
return delegate.getHost();
}
@Override
public int getPort() {
return delegate.getPort();
}
@Override
public boolean isSecure() {
return delegate.isSecure();
}
@Override
public URI getUri() {
return delegate.getUri();
}
@Override
public Map<String, String> getMetadata() {
return delegate.getMetadata();
}
@Override
public String getScheme() {
return delegate.getScheme();
}
@Override
public String toString() {
return new ToStringCreator(this)
.append("delegate", delegate)
.append("properties", properties)
.toString();
}
}
}

View File

@@ -47,6 +47,13 @@ public class DiscoveryLocatorProperties {
/** SpEL expression that create the uri for each route, defaults to: 'lb://'+serviceId */
private String urlExpression = "'lb://'+serviceId";
/**
* Option to lower case serviceId in predicates and filters, defaults to false.
* Useful with eureka when it automatically uppercases serviceId.
* so MYSERIVCE, would match /myservice/**
*/
private boolean lowerCaseServiceId = false;
private List<PredicateDefinition> predicates = new ArrayList<>();
private List<FilterDefinition> filters = new ArrayList<>();
@@ -83,6 +90,14 @@ public class DiscoveryLocatorProperties {
this.urlExpression = urlExpression;
}
public boolean isLowerCaseServiceId() {
return lowerCaseServiceId;
}
public void setLowerCaseServiceId(boolean lowerCaseServiceId) {
this.lowerCaseServiceId = lowerCaseServiceId;
}
public List<PredicateDefinition> getPredicates() {
return predicates;
}
@@ -106,6 +121,7 @@ public class DiscoveryLocatorProperties {
.append("routeIdPrefix", routeIdPrefix)
.append("includeExpression", includeExpression)
.append("urlExpression", urlExpression)
.append("lowerCaseServiceId", lowerCaseServiceId)
.append("predicates", predicates)
.append("filters", filters)
.toString();

View File

@@ -49,11 +49,12 @@ import static org.springframework.cloud.gateway.handler.predicate.RoutePredicate
properties = {"spring.cloud.gateway.discovery.locator.enabled=true",
"spring.cloud.gateway.discovery.locator.route-id-prefix=testedge_",
"spring.cloud.gateway.discovery.locator.include-expression=metadata['edge'] == 'true'",
"spring.cloud.gateway.discovery.locator.predicates[0].name=Path",
"spring.cloud.gateway.discovery.locator.lower-case-service-id=true",
/*"spring.cloud.gateway.discovery.locator.predicates[0].name=Path",
"spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]='/'+serviceId.toLowerCase()+'/**'",
"spring.cloud.gateway.discovery.locator.filters[0].name=RewritePath",
"spring.cloud.gateway.discovery.locator.filters[0].args[regexp]='/' + serviceId.toLowerCase() + '/(?<remaining>.*)'",
"spring.cloud.gateway.discovery.locator.filters[0].args[replacement]='/$\\\\{remaining}'",
"spring.cloud.gateway.discovery.locator.filters[0].args[replacement]='/$\\\\{remaining}'",*/
})
public class DiscoveryClientRouteDefinitionLocatorTests {
@@ -84,7 +85,7 @@ public class DiscoveryClientRouteDefinitionLocatorTests {
assertThat(filter.getName()).isEqualTo("RewritePath");
assertThat(filter.getArgs()).hasSize(2)
.containsEntry(REGEXP_KEY, "/service1/(?<remaining>.*)")
.containsEntry(REPLACEMENT_KEY, "/$\\{remaining}");
.containsEntry(REPLACEMENT_KEY, "/${remaining}");
}
@SpringBootConfiguration