Как динамически направить входящий запрос с помощью службы сопоставления URL-> liability-backend-service? - PullRequest
0 голосов
/ 28 июня 2019

Я новичок в Spring-Cloud-Gateway и не могу ответить на вопрос, если я решил свою проблему намеченным способом.Я надеюсь, что кто-то может указать мне правильное направление, дать совет или предоставить примерный пример кода.

Требование: входящий запрос в моем сервисе spring-cloud-gateway должен быть перенаправлен в правильный бэкэнд-сервис (естьХ таких бэкэнд-сервисов, каждый из которых отвечает за определенную задачу).Сам запрос не содержит достаточной информации, чтобы решить, к какой серверной службе следует направить.

Существует дополнительная REST-служба, которая отображает произвольный URL-адрес-для-ответной-службы-имени.Формат ответа - это небольшой файл JSON, содержащий имя бэкэнд-службы для переадресации.

Каким было бы самое простое / лучшее / самое умное / предназначенное решение для реализации этой функциональности с помощью spring-cloud-gateway?

Я попытался реализовать GatewayFilter, который сначала вызывает службу сопоставления и в зависимости от набора результатов GATEWAY_REQUEST_URL_ATTR для обмена.Это работает хорошо.Но у меня есть дополнительные вопросы.

  1. Можно ли пропустить часть .uri("not://needed")) в настройке маршрута?

  2. Почему стоимость заказа должна быть выше 9999?(см. пример кода)

@SpringBootApplication
@RestController
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public RouteLocator myRoutes(RouteLocatorBuilder builder) {
        return builder.routes().route(r -> r
                .alwaysTrue()
                .filters(f -> f.filter(new CustomRequestFilter()))
                .uri("not://needed"))  // how to omit ?
                .build();
    }


    public static class CustomRequestFilter implements GatewayFilter, Ordered {

        @Override
        public int getOrder() {
            return 10000; // why order > 9999 ?  (below 10000 does not work)
        }

        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

            return getBackendServiceMappingResult(exchange.getRequest().getURI().toString()) //async call to REST service mapping URL->backend service name
                    .flatMap(mappingResult -> {
                        URI uri = mapServiceNameToBackendService(mappingResult.getServiceName());
                        exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, uri);
                        return chain.filter(exchange);
                    });
        }

        private URI mapServiceNameToBackendService(String serviceName) {
            try {
                switch (serviceName) {
                    case "serviceA": return new URI("http://httpbin.org:80/get");
                    case "serviceB": return new URI("https://someotherhost:443/");
                }
            } catch (URISyntaxException e) {
                //ignore
            }
            return null;
        }
    }

    static class MappingResult {
        String serviceName;
        public String getServiceName() {
            return serviceName;
        }
    }

    static Mono<MappingResult> getBackendServiceMappingResult(String uri) {
        WebClient client = WebClient.create("http://localhost:8080");
        return client.get().uri(uriBuilder -> uriBuilder.path("/mapping").queryParam("uri", uri).build()).retrieve().bodyToMono(MappingResult.class);
    }
}

Существует ли лучший подход (с весенним облаком-шлюзом) для решения требования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...