Я реализовал собственный фильтр 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
classtestRouteLocator
метода - целевой контроллер: целевой контроллер определяется как
HttpBinCompatibleController
класс
testClient
отправляет запрос, а пользовательский должен выполнить некоторую фильтрацию, после чего целевой контроллер должен получить запрос от testClient
.
От этого shouldFailByFilterTests
TC я ожидаю, что до того, как запрос от testClient
будет отправлен на целевой контроллер, этот запрос должен быть отклонен MyCustomFilter
. Но запрос отправляется на целевой контроллер.
Я думаю, что запрос от testClient
не проксируется testRouteLocator
, но я не уверен
Вопрос
- В чем причина этой проблемы?
- Есть ли другой способ проверить мой собственный фильтр?
logging.level.org.springframework.cloud.gateway=TRACE
и посмотреть, сможете ли вы что-нибудь сказать? - person spencergibb   schedule 29.06.2020