Skip to content

Commit

Permalink
Add RouteLocator Builder
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeCqupt committed Oct 24, 2023
1 parent df30cc4 commit 4d69ce9
Show file tree
Hide file tree
Showing 20 changed files with 429 additions and 727 deletions.
624 changes: 0 additions & 624 deletions docs/zh-cn/detail-design.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import com.google.common.collect.Lists;
import io.github.xinfra.lab.gateway.commons.Assert;
import io.github.xinfra.lab.gateway.config.GatewayConfigManager;
import io.github.xinfra.lab.gateway.filter.GatewayFilter;
import io.github.xinfra.lab.gateway.filter.global.GlobalGatewayFilter;
import io.github.xinfra.lab.gateway.filter.global.RoutingFilter;
import io.github.xinfra.lab.gateway.handler.DefaultWebExceptionHandler;
import io.github.xinfra.lab.gateway.handler.ExceptionHandlingWebHandler;
import io.github.xinfra.lab.gateway.handler.FilteringWebHandler;
import io.github.xinfra.lab.gateway.handler.ReactorHttpHandler;
Expand All @@ -18,7 +19,6 @@
import reactor.netty.http.server.HttpServer;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -27,18 +27,22 @@
public class GatewayServerBootstrap {

private int port;
private List<GatewayFilter> globalFilters = new ArrayList<>();
private List<WebExceptionHandler> webExceptionHandlers = new ArrayList<>();
private List<GlobalGatewayFilter> globalFilters;
private List<WebExceptionHandler> webExceptionHandlers;
private RouteLocator routeLocator;
private String configPath;
private DisposableServer server;

public RouteLocator getRouteLocator() {
return routeLocator;
}

public GatewayServerBootstrap port(int port) {
this.port = port;
return this;
}


public GatewayServerBootstrap globalFilters(List<GatewayFilter> globalFilters) {
public GatewayServerBootstrap globalFilters(List<GlobalGatewayFilter> globalFilters) {
Assert.notNull(globalFilters, "globalFilters must not be null.");
this.globalFilters = globalFilters;
return this;
Expand All @@ -63,13 +67,16 @@ public GatewayServerBootstrap configPath(String configPath) {
}


public DisposableServer start() {

public GatewayServerBootstrap start() {
if (routeLocator == null) {
routeLocator = getDefaultRouteLocator();
}

globalFilters.addAll(getDefaultGlobalFilters());
if (globalFilters == null) {
globalFilters = getDefaultGlobalFilters();
}
if (webExceptionHandlers == null) {
webExceptionHandlers = getDefaultWebExceptionHandlers();
}

// trigger GatewayFilterChain
FilteringWebHandler filteringWebHandler = new FilteringWebHandler(globalFilters);
Expand All @@ -81,17 +88,26 @@ public DisposableServer start() {
ReactorHttpHandler httpHandler = new ReactorHttpHandler(exceptionHandlingWebHandler);

// start server
return HttpServer.create()
this.server = HttpServer.create()
.handle(httpHandler::handle)
.bindAddress(() -> new InetSocketAddress(port))
.bind().block();

return this;
}

private List<GatewayFilter> getDefaultGlobalFilters() {
public GatewayServerBootstrap stop() {
this.server.disposeNow();
return this;
}

return Lists.newArrayList(new RoutingFilter());
protected List<WebExceptionHandler> getDefaultWebExceptionHandlers() {
return Lists.newArrayList(new DefaultWebExceptionHandler());
}

protected List<GlobalGatewayFilter> getDefaultGlobalFilters() {
return Lists.newArrayList(new RoutingFilter());
}

protected RouteLocator getDefaultRouteLocator() {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.xinfra.lab.gateway.bootstrap;
package io.github.xinfra.lab.gateway.commons;

public class AbstractConfigurable<C> implements Configurable<C> {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.xinfra.lab.gateway.bootstrap;
package io.github.xinfra.lab.gateway.commons;

public interface Configurable<C> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import io.github.xinfra.lab.gateway.server.ServerWebExchange;
import reactor.core.publisher.Mono;

public interface Endpoint {
public interface Endpoint<T> {

T getConfig();
Mono<Void> invoke(ServerWebExchange exchange);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.xinfra.lab.gateway.endpoint;

import io.github.xinfra.lab.gateway.bootstrap.Configurable;
import io.github.xinfra.lab.gateway.commons.Configurable;

public interface EndpointFactory<C> extends Configurable<C> {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.github.xinfra.lab.gateway.endpoint;

import io.github.xinfra.lab.gateway.server.ServerWebExchange;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.server.HttpServerRequest;
import reactor.netty.http.server.HttpServerResponse;

import java.net.URI;
import java.util.List;

import static io.github.xinfra.lab.gateway.commons.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
import static io.github.xinfra.lab.gateway.commons.ServerWebExchangeUtils.markResponseCommitted;

@Slf4j
public class HttpEndpoint implements Endpoint<HttpEndpoint.Config> {

@Data
public static class Config {
List<String> urls;
List<Integer> weights;
}

private Config config;

public HttpEndpoint(Config config) {
this.config = config;
}

@Override
public Config getConfig() {
return this.config;
}

@Override
public Mono<Void> invoke(ServerWebExchange exchange) {


HttpServerRequest request = exchange.getRequest();
HttpServerResponse response = exchange.getResponse();

return HttpClient.create()
.headers(headers -> {
headers.add(request.requestHeaders());
})
.request(request.method())
.uri(URI.create(config.getUrls().get(0))) // TODO Chooser
.send(request.receive())
.response((httpClientResponse, byteBufFlux) ->
response.status(httpClientResponse.status())
.headers(httpClientResponse.responseHeaders())
.sendByteArray(byteBufFlux.asByteArray())
)
.subscribeOn(Schedulers.boundedElastic())
.doOnError(t -> {
log.error("fail invoke http endpoint:{}",
exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR), t);
}).doOnNext(v -> {
markResponseCommitted(exchange);
}).then();
}
}
Original file line number Diff line number Diff line change
@@ -1,66 +1,27 @@
package io.github.xinfra.lab.gateway.endpoint;


import io.github.xinfra.lab.gateway.bootstrap.AbstractConfigurable;
import lombok.Data;
import io.github.xinfra.lab.gateway.commons.AbstractConfigurable;
import lombok.extern.slf4j.Slf4j;
import reactor.core.scheduler.Schedulers;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.server.HttpServerRequest;
import reactor.netty.http.server.HttpServerResponse;

import java.net.URI;
import java.util.List;

import static io.github.xinfra.lab.gateway.commons.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
import static io.github.xinfra.lab.gateway.commons.ServerWebExchangeUtils.markResponseCommitted;

@Slf4j
public class HttpEndpointFactory extends
AbstractConfigurable<HttpEndpointFactory.Config>
implements EndpointFactory<HttpEndpointFactory.Config> {
AbstractConfigurable<HttpEndpoint.Config>
implements EndpointFactory<HttpEndpoint.Config> {
public static final String NAME = "Http";

public HttpEndpointFactory() {
super(HttpEndpointFactory.Config.class);
super(HttpEndpoint.Config.class);
}

@Override
public String getName() {
return "Http";
return NAME;
}

@Override
public Endpoint apply(Config config) {
return exchange -> {

HttpServerRequest request = exchange.getRequest();
HttpServerResponse response = exchange.getResponse();

return HttpClient.create()
.headers(headers -> {
headers.add(request.requestHeaders());
})
.request(request.method())
.uri(URI.create(config.getHosts().get(0))) // TODO Chooser
.send(request.receive())
.response((httpClientResponse, byteBufFlux) ->
response.status(httpClientResponse.status())
.headers(httpClientResponse.responseHeaders())
.sendByteArray(byteBufFlux.asByteArray())
)
.subscribeOn(Schedulers.boundedElastic())
.doOnError(t -> {
log.error("fail invoke http endpoint:{}",
exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR), t);
}).doOnNext(v -> {
markResponseCommitted(exchange);
}).then();
};
public Endpoint apply(HttpEndpoint.Config config) {
return new HttpEndpoint(config);
}


@Data
public static class Config {
List<String> hosts;
List<Integer> weights;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package io.github.xinfra.lab.gateway.filter;

import io.github.xinfra.lab.gateway.bootstrap.AbstractConfigurable;
import io.github.xinfra.lab.gateway.commons.AbstractConfigurable;
import reactor.netty.http.server.HttpServerRequest;

import java.util.Map;

public class AddHeaderGatewayFilterFactory extends
AbstractConfigurable<Map<String, String>>
implements GatewayFilterFactory<Map<String, String>> {
public static final String NAME = "AddHeader";
public AddHeaderGatewayFilterFactory() {
super((Class) Map.class);
}

@Override
public String getName() {
return "AddHeader";
return NAME;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.xinfra.lab.gateway.filter;

import io.github.xinfra.lab.gateway.bootstrap.Configurable;
import io.github.xinfra.lab.gateway.commons.Configurable;

public interface GatewayFilterFactory<C> extends Configurable<C> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.github.xinfra.lab.gateway.commons.OrderedAwareComparator;
import io.github.xinfra.lab.gateway.filter.DefaultGatewayFilterChain;
import io.github.xinfra.lab.gateway.filter.GatewayFilter;
import io.github.xinfra.lab.gateway.filter.global.GlobalGatewayFilter;
import io.github.xinfra.lab.gateway.route.Route;
import io.github.xinfra.lab.gateway.server.ServerWebExchange;
import reactor.core.publisher.Mono;
Expand All @@ -14,9 +15,9 @@

public class FilteringWebHandler implements WebHandler {

private List<GatewayFilter> globalFilters;
private List<GlobalGatewayFilter> globalFilters;

public FilteringWebHandler(List<GatewayFilter> globalFilters) {
public FilteringWebHandler(List<GlobalGatewayFilter> globalFilters) {
this.globalFilters = globalFilters;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.xinfra.lab.gateway.predicate;

import io.github.xinfra.lab.gateway.bootstrap.AbstractConfigurable;
import io.github.xinfra.lab.gateway.commons.AbstractConfigurable;
import io.github.xinfra.lab.gateway.server.ServerWebExchange;
import lombok.Data;
import reactor.core.publisher.Mono;
Expand All @@ -11,14 +11,15 @@ public class PathRoutePredicateFactory
extends AbstractConfigurable<PathRoutePredicateFactory.PatternConfig>
implements RoutePredicateFactory<PathRoutePredicateFactory.PatternConfig> {

public static final String NAME = "Path";

public PathRoutePredicateFactory() {
super(PatternConfig.class);
}

@Override
public String getName() {
return "Path";
return NAME;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.xinfra.lab.gateway.predicate;


import io.github.xinfra.lab.gateway.bootstrap.Configurable;
import io.github.xinfra.lab.gateway.commons.Configurable;
import io.github.xinfra.lab.gateway.server.ServerWebExchange;

public interface RoutePredicateFactory<C> extends Configurable<C> {
Expand Down
Loading

0 comments on commit 4d69ce9

Please sign in to comment.