Browse Source

simple configurable routes

pull/41/head
Spencer Gibb 8 years ago
parent
commit
e47eb9e5fc
No known key found for this signature in database
GPG Key ID: 7788A47380690861
  1. 54
      src/main/java/org/springframework/cloud/gateway/GatewayConfiguration.java
  2. 39
      src/main/java/org/springframework/cloud/gateway/GatewayHandlerMapping.java
  3. 49
      src/main/java/org/springframework/cloud/gateway/GatewayProperties.java
  4. 24
      src/main/java/org/springframework/cloud/gateway/GatewayWebHandler.java
  5. 36
      src/main/java/org/springframework/cloud/gateway/SpringCloudGatewayApplication.java
  6. 48
      src/main/java/org/springframework/cloud/gateway/filters/FindRouteFilter.java
  7. 0
      src/main/resources/application.properties
  8. 10
      src/main/resources/application.yml

54
src/main/java/org/springframework/cloud/gateway/GatewayConfiguration.java

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
package org.springframework.cloud.gateway;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.filters.FindRouteFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.client.reactive.WebClient;
/**
* @author Spencer Gibb
*/
@Configuration
@EnableConfigurationProperties
public class GatewayConfiguration {
@Bean
@ConditionalOnMissingBean
public WebClient webClient() {
return WebClient.builder(new ReactorClientHttpConnector()).build();
}
@Bean
public FindRouteFilter findRouteFilter(GatewayProperties properties) {
return new FindRouteFilter(properties);
}
@Bean
public GatewayProperties gatewayProperties() {
return new GatewayProperties();
}
@Bean
public GatewayWebHandler gatewayController(GatewayProperties properties, WebClient webClient) {
return new GatewayWebHandler(properties, webClient);
}
@Bean
public GatewayHandlerMapping gatewayHandlerMapping(GatewayProperties properties, GatewayWebHandler gatewayWebHandler) {
return new GatewayHandlerMapping(properties, gatewayWebHandler);
}
/*@Bean
public GatewayWebReactiveConfigurer gatewayWebReactiveConfiguration() {
return new GatewayWebReactiveConfigurer();
}
public static class GatewayWebReactiveConfigurer implements WebReactiveConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
}*/
}

39
src/main/java/org/springframework/cloud/gateway/GatewayHandlerMapping.java

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
package org.springframework.cloud.gateway;
import org.springframework.beans.BeansException;
import org.springframework.cloud.gateway.GatewayProperties.Route;
import org.springframework.web.reactive.handler.AbstractUrlHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
import java.util.Map;
/**
* @author Spencer Gibb
*/
public class GatewayHandlerMapping extends AbstractUrlHandlerMapping {
private GatewayProperties properties;
private GatewayWebHandler gatewayWebHandler;
public GatewayHandlerMapping(GatewayProperties properties, GatewayWebHandler gatewayWebHandler) {
this.properties = properties;
this.gatewayWebHandler = gatewayWebHandler;
}
@Override
protected void initApplicationContext() throws BeansException {
super.initApplicationContext();
registerHandlers(this.properties.getRoutes());
}
protected void registerHandlers(Map<String, Route> routes) {
for (Route route : routes.values()) {
registerHandler(route.getPath(), this.gatewayWebHandler);
}
}
@Override
protected Object lookupHandler(String urlPath, ServerWebExchange exchange) throws Exception {
return super.lookupHandler(urlPath, exchange);
}
}

49
src/main/java/org/springframework/cloud/gateway/GatewayProperties.java

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
package org.springframework.cloud.gateway;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author Spencer Gibb
*/
@ConfigurationProperties("spring.cloud.gateway")
public class GatewayProperties {
/**
* Map of route names to properties.
*/
private Map<String, Route> routes = new LinkedHashMap<>();
public Map<String, Route> getRoutes() {
return routes;
}
public void setRoutes(Map<String, Route> routes) {
this.routes = routes;
}
public static class Route {
private String id;
private String path;
private String url;
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
public String getUrl() {
return this.url;
}
public void setUrl(String url) {
this.url = url;
}
}
}

24
src/main/java/org/springframework/cloud/gateway/GatewayController.java → src/main/java/org/springframework/cloud/gateway/GatewayWebHandler.java

@ -1,34 +1,32 @@ @@ -1,34 +1,32 @@
package org.springframework.cloud.gateway;
import java.util.Optional;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.reactive.ClientRequest;
import org.springframework.web.client.reactive.WebClient;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebHandler;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Optional;
/**
* @author Spencer Gibb
*/
@RestController
@SuppressWarnings("unused")
public class GatewayController {
public class GatewayWebHandler implements WebHandler {
private final GatewayProperties properties;
private final WebClient webClient;
public GatewayController(WebClient webClient) {
public GatewayWebHandler(GatewayProperties properties, WebClient webClient) {
this.properties = properties;
this.webClient = webClient;
}
//TODO: plugin to request mappings
@GetMapping(path = "/")
public Flux<Void> home(ServerWebExchange exchange) {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
Optional<String> requestUrl = exchange.getAttribute("requestUrl");
ServerHttpRequest request = exchange.getRequest();
ClientRequest<Void> clientRequest = ClientRequest
@ -42,6 +40,6 @@ public class GatewayController { @@ -42,6 +40,6 @@ public class GatewayController {
response.setStatusCode(clientResponse.statusCode());
Flux<DataBuffer> body = clientResponse.body((inputMessage, context) -> inputMessage.getBody());
return response.writeWith(body);
});
}).next(); // TODO: is this correct?
}
}

36
src/main/java/org/springframework/cloud/gateway/SpringCloudGatewayApplication.java

@ -2,38 +2,25 @@ package org.springframework.cloud.gateway; @@ -2,38 +2,25 @@ package org.springframework.cloud.gateway;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.client.reactive.WebClient;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import reactor.core.publisher.Mono;
@SpringBootApplication
//TODO: move to autoconfig
@Import(GatewayConfiguration.class)
@SpringBootConfiguration
@EnableAutoConfiguration
public class SpringCloudGatewayApplication {
private static final Log log = LogFactory.getLog(SpringCloudGatewayApplication.class);
@Bean
public WebClient webClient() {
return WebClient.builder(new ReactorClientHttpConnector()).build();
}
// TODO: request only, how to filter response?
@Bean
@Order(500)
public WebFilter findRouteFilter() {
return (exchange, chain) -> {
log.info("findRoutFilter start");
exchange.getAttributes().put("requestUrl", "http://httpbin.org/get");
return chain.filter(exchange);
};
}
// TODO: only apply filters to zuul?
@Bean
@Order(501)
public WebFilter modifyResponseFilter() {
@ -60,6 +47,9 @@ public class SpringCloudGatewayApplication { @@ -60,6 +47,9 @@ public class SpringCloudGatewayApplication {
}
public static void main(String[] args) {
SpringApplication.run(SpringCloudGatewayApplication.class, args);
new SpringApplicationBuilder()
.sources(SpringCloudGatewayApplication.class)
//TODO: howto do programatically
.run(args);
}
}

48
src/main/java/org/springframework/cloud/gateway/filters/FindRouteFilter.java

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
package org.springframework.cloud.gateway.filters;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.GatewayProperties;
import org.springframework.cloud.gateway.GatewayProperties.Route;
import org.springframework.cloud.gateway.SpringCloudGatewayApplication;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import java.net.URI;
/**
* @author Spencer Gibb
*/
public class FindRouteFilter implements WebFilter {
private static final Log log = LogFactory.getLog(SpringCloudGatewayApplication.class);
private final GatewayProperties properties;
private final AntPathMatcher matcher;
public FindRouteFilter(GatewayProperties properties) {
this.properties = properties;
this.matcher = new AntPathMatcher();
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
log.info("FindRouteFilter start");
//TODO:
ServerHttpRequest request = exchange.getRequest();
URI uri = request.getURI();
String path = uri.getPath();
for (Route route : this.properties.getRoutes().values()) {
if (this.matcher.match(route.getPath(), path)) {
String url = route.getUrl() + path;
exchange.getAttributes().put("requestUrl", url);
return chain.filter(exchange);
}
}
return chain.filter(exchange);
}
}

0
src/main/resources/application.properties

10
src/main/resources/application.yml

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
spring:
resources:
# TODO: how to add this programmatically
add-mappings: false
cloud:
gateway:
routes:
test1:
path: /**
url: http://httpbin.org
Loading…
Cancel
Save