Как выполнить тест e2e настраиваемого фильтра весеннего облачного шлюза?

Я реализовал собственный фильтр GatewayFilterFactory. Но я не знаю, как протестировать этот фильтр с настройкой e2e.

Я сослался на официальный Spring-cloud-gateway AddRequestHeaderGatewayFilterFactoryTests код тестового примера.


Это мой код настраиваемого фильтра:

@Component
public class MyCustomFilter implements GatewayFilterFactory<MyCustomFilter.Config>, Ordered {

    @Override
    public GatewayFilter apply(Config config) {
        return new OrderedGatewayFilter((this::filter), getOrder());
    }

    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        /* do some filtering */
    }


    @Override
    public int getOrder() {
        return 1000;
    }

    @Override
    public Config newConfig() {
        return new Config(MyCustomFilter.class.getSimpleName());
    }

    public static getConfig() {
        return 
    }

    @Getter
    @Setter
    public static class Config {
        private String name;

        Config(String name) {
            this.name = name;
        }
    }
}

А это мой тестовый код:

BaseWebClientTests класс выглядит точно так же, как официальный код класса BaseWebClientTests

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@DirtiesContext
@ActiveProfiles("my-custom-filter")
public class MyCustomFilterTests extends BaseWebClientTests {
    @LocalServerPort
    protected int port = 0;

    protected WebTestClient testClient;

    protected WebClient webClient;

    protected String baseUri;

    @Before
    public void setup() throws Exception {
        setup(new ReactorClientHttpConnector(), "http://localhost:" + port);
    }

    protected void setup(ClientHttpConnector httpConnector, String baseUri) {
        this.baseUri = baseUri;
        this.webClient = WebClient.builder().clientConnector(httpConnector)
                .baseUrl(this.baseUri).build();
        this.testClient = WebTestClient
                .bindToServer(httpConnector)
                .baseUrl(this.baseUri)
                .build();
    }

    @Test
    public void shouldFailByFilterTests() {
        /* This test should be failed but success :( */
        testClient.get().uri("/api/path")
                .exchange().expectBody(Map.class).consumeWith(result -> {
            /* do assertion */
        });
    }

    @EnableAutoConfiguration
    @SpringBootConfiguration
    @Import(DefaultTestConfig.class)
    public static class TestConfig {

        @Value("${test.uri}")
        String uri;

        @Bean
        public MyCustomFilter myCustomFilter() {
            return new MyCustomFilter();
        }

        @Bean
        public RouteLocator testRouteLocator(RouteLocatorBuilder builder, MyCustomFilter myCustomFilter) {
            return builder.routes().route("my_custom_filter",
                    r -> r.path("/api/path")
                            .filters(f -> f.filter(myCustomFilter.apply(new MyCustomFilter.Config("STRING"))))
                            .uri(uri))
                    .build();
        }

    }
}

Наконец, целевой контроллер выглядит так:

@RestController
@RequestMapping("/api/path")
public class HttpBinCompatibleController {

    @GetMapping("/")
    public Mono<BodyData> identity() {
        return Mono.just(new BodyData("api success"));
    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    static class BodyData {
        private String message;
    }
}

What I understand how this filter factory test code works is that

введите описание изображения здесь

  • настраиваемый фильтр: настраиваемый фильтр настраивается внутри TestConfig class testRouteLocator метода
  • целевой контроллер: целевой контроллер определяется как HttpBinCompatibleController класс

testClient отправляет запрос, а пользовательский должен выполнить некоторую фильтрацию, после чего целевой контроллер должен получить запрос от testClient.

От этого shouldFailByFilterTests TC я ожидаю, что до того, как запрос от testClient будет отправлен на целевой контроллер, этот запрос должен быть отклонен MyCustomFilter. Но запрос отправляется на целевой контроллер.

Я думаю, что запрос от testClient не проксируется testRouteLocator, но я не уверен

Вопрос

  1. В чем причина этой проблемы?
  2. Есть ли другой способ проверить мой собственный фильтр?

person zeroFruit    schedule 28.06.2020    source источник
comment
Вы поставили точку останова в свой фильтр?   -  person spencergibb    schedule 29.06.2020
comment
Ага. и он не останавливается на этой точке останова.   -  person zeroFruit    schedule 29.06.2020
comment
В Spring Cloud Gateway мы делаем это постоянно. Вы можете установить logging.level.org.springframework.cloud.gateway=TRACE и посмотреть, сможете ли вы что-нибудь сказать?   -  person spencergibb    schedule 29.06.2020


Ответы (1)


Эта проблема была связана с несовместимостью версий между Spring Boot и Spring Cloud.

Я использовал Spring Boot версии 2.1.7 и Spring Cloud версии Greenwich.SR2.

Затем я нашел таблицу «Совместимость с загрузкой Spring Train» по этой ссылке

Прежде чем я заметил несовместимость версий, для использования функции @Configuration(proxyBeanMethods = false) обновил версию Spring Boot до 2.2.x.

В решении используется ветка 2.1.x BaseWebClientTests.

person zeroFruit    schedule 06.07.2020