This commit is contained in:
Spencer Gibb
2017-06-23 16:47:57 -06:00
parent 5b10004ab7
commit 27e5e178d9
9 changed files with 33 additions and 39 deletions

View File

@@ -90,6 +90,7 @@ import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import reactor.core.publisher.Flux;
import reactor.ipc.netty.http.client.HttpClient;
import reactor.ipc.netty.resources.PoolResources;
import rx.RxReactiveStreams;
/**
@@ -109,8 +110,8 @@ public class GatewayAutoConfiguration {
@ConditionalOnMissingBean
public HttpClient httpClient() {
return HttpClient.create(opts -> {
//opts.poolResources(PoolResources.elastic("proxy"));
//opts.disablePool(); //TODO: why do I need this again?
opts.poolResources(PoolResources.elastic("proxy"));
// opts.disablePool(); //TODO: why do I need this again?
});
}

View File

@@ -18,6 +18,7 @@
package org.springframework.cloud.gateway.filter;
import java.net.URI;
import java.util.Optional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -30,7 +31,6 @@ import org.springframework.web.server.WebFilterChain;
import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
import reactor.core.publisher.Mono;
@@ -55,19 +55,19 @@ public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
URI url = getAttribute(exchange, GATEWAY_REQUEST_URL_ATTR, URI.class);
if (url == null || !url.getScheme().equals("lb")) {
Optional<URI> url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
if (!url.isPresent() || !url.get().getScheme().equals("lb")) {
return chain.filter(exchange);
}
log.trace("LoadBalancerClientFilter url before: " + url);
log.trace("LoadBalancerClientFilter url before: " + url.get());
final ServiceInstance instance = loadBalancer.choose(url.getHost());
final ServiceInstance instance = loadBalancer.choose(url.get().getHost());
if (instance == null) {
throw new NotFoundException("");
}
URI requestUrl = UriComponentsBuilder.fromUri(url)
URI requestUrl = UriComponentsBuilder.fromUri(url.get())
.scheme(instance.isSecure()? "https" : "http") //TODO: support websockets
.host(instance.getHost())
.port(instance.getPort())

View File

@@ -18,6 +18,7 @@
package org.springframework.cloud.gateway.filter;
import java.net.URI;
import java.util.Optional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -29,7 +30,6 @@ import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
import reactor.core.publisher.Mono;
@@ -48,13 +48,13 @@ public class RouteToRequestUrlFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Route route = getAttribute(exchange, GATEWAY_ROUTE_ATTR, Route.class);
if (route == null) {
Optional<Route> route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
if (!route.isPresent()) {
return chain.filter(exchange);
}
log.info("RouteToRequestUrlFilter start");
URI requestUrl = UriComponentsBuilder.fromHttpRequest(exchange.getRequest())
.uri(route.getUri())
.uri(route.get().getUri())
.build(true)
.toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);

View File

@@ -17,6 +17,8 @@
package org.springframework.cloud.gateway.filter;
import java.util.Optional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.Ordered;
@@ -27,7 +29,6 @@ import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@@ -52,8 +53,9 @@ public class WriteResponseFilter implements GlobalFilter, Ordered {
// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added
// until the WebHandler is run
return chain.filter(exchange).then(Mono.defer(() -> {
HttpClientResponse clientResponse = getAttribute(exchange, CLIENT_RESPONSE_ATTR, HttpClientResponse.class);
if (clientResponse == null) {
Optional<HttpClientResponse> clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR);
// HttpClientResponse clientResponse = getAttribute(exchange, CLIENT_RESPONSE_ATTR, HttpClientResponse.class);
if (!clientResponse.isPresent()) {
return Mono.empty();
}
log.trace("WriteResponseFilter start");
@@ -62,7 +64,7 @@ public class WriteResponseFilter implements GlobalFilter, Ordered {
NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory();
//TODO: what if it's not netty
final Flux<NettyDataBuffer> body = clientResponse.receive()
final Flux<NettyDataBuffer> body = clientResponse.get().receive()
.retain() //TODO: needed?
.map(factory::wrap);

View File

@@ -19,8 +19,10 @@ package org.springframework.cloud.gateway.filter.factory;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.tuple.Tuple;
@@ -28,7 +30,6 @@ import org.springframework.web.server.WebFilter;
import org.springframework.web.util.UriTemplate;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.getAttribute;
/**
* @author Spencer Gibb
@@ -49,9 +50,9 @@ public class SetPathWebFilterFactory implements WebFilterFactory {
UriTemplate uriTemplate = new UriTemplate(template);
return (exchange, chain) -> {
Map<String, String> variables = getAttribute(exchange, URI_TEMPLATE_VARIABLES_ATTRIBUTE, Map.class);
Optional<Map<String, String>> variables = exchange.getAttribute(URI_TEMPLATE_VARIABLES_ATTRIBUTE);
ServerHttpRequest req = exchange.getRequest();
URI uri = uriTemplate.expand(variables);
URI uri = uriTemplate.expand(variables.orElseGet(Collections::emptyMap));
String newPath = uri.getPath();
ServerHttpRequest request = req.mutate()

View File

@@ -56,12 +56,12 @@ public class SetStatusWebFilterFactory implements WebFilterFactory {
return chain.filter(exchange);*/
// option 2 (runs in reverse filter order)
return chain.filter(exchange).then(Mono.defer(() -> {
// check not really needed, since it is guarded in setStatusCode, but it's a good example
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// check not really needed, since it is guarded in setStatusCode,
// but it's a good example
if (!exchange.getResponse().isCommitted()) {
setResponseStatus(exchange, httpStatus);
}
return Mono.empty();
}));
};
}

View File

@@ -63,11 +63,11 @@ public class NettyProxyWebHandler implements WebHandler {
return this.httpClient.request(method, url, req ->
req.options(NettyPipeline.SendOptions::flushOnEach)
.headers(httpHeaders)
.sendHeaders()
.sendHeaders() // I shouldn't have to do this
.send(request.getBody()
.map(DataBuffer::asByteBuffer)
.map(Unpooled::wrappedBuffer)))
.flatMap(res -> {
.doOnNext(res -> {
// Defer committing the response until all route filters have run
// Put client response as ServerWebExchange attribute and write response later WriteResponseFilter
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
@@ -79,8 +79,6 @@ public class NettyProxyWebHandler implements WebHandler {
response.getHeaders().putAll(headers);
response.setStatusCode(HttpStatus.valueOf(res.status().code()));
return Mono.empty();
});
}).then();
}
}

View File

@@ -50,7 +50,7 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
exchange.getAttributes().put(GATEWAY_HANDLER_MAPPER_ATTR, getClass().getSimpleName());
return lookupRoute(exchange)
.log("TRACE")
.log() //name this
.flatMap((Function<Route, Mono<?>>) r -> {
if (logger.isDebugEnabled()) {
logger.debug("Mapping [" + getExchangeDesc(exchange) + "] to " + r);
@@ -80,6 +80,9 @@ public class RoutePredicateHandlerMapping extends AbstractHandlerMapping {
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes()
.filter(route -> route.getPredicate().test(exchange))
// .defaultIfEmpty() put a static Route not found
// or .switchIfEmpty()
// .switchIfEmpty(Mono.<Route>empty().log("noroute"))
.next()
//TODO: error handling
.map(route -> {

View File

@@ -37,17 +37,6 @@ public class ServerWebExchangeUtils {
public static final String GATEWAY_REQUEST_URL_ATTR = "gatewayRequestUrl";
public static final String GATEWAY_HANDLER_MAPPER_ATTR = "gatewayHandlerMapper";
public static <T> T getAttribute(ServerWebExchange exchange, String attributeName, Class<T> type) {
if (exchange.getAttributes().containsKey(attributeName)) {
Object attr = exchange.getAttributes().get(attributeName);
if (type.isAssignableFrom(attr.getClass())) {
return type.cast(attr);
}
throw new ClassCastException(attributeName + " is not of type " + type);
}
return null;
}
public static boolean setResponseStatus(ServerWebExchange exchange, HttpStatus httpStatus) {
boolean response = exchange.getResponse().setStatusCode(httpStatus);
if (!response && logger.isWarnEnabled()) {