Reputation: 31
I try use Spring Cloud Gateway Filter for my request. I tried use some variants realisation filters like below:
@Component
@Slf4j
@Order(-10000)
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
public CustomFilter() {
super(Config.class);
log.info("Loaded GatewayFilterFactory [Authorize]");
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("enabled");
}
@Override
public ShortcutType shortcutType() {
return ShortcutType.DEFAULT;
}
@Override
public GatewayFilter apply(CustomFilter.Config config) {
log.info("Into apply");
return (exchange, chain)->{
log.info("Into exchange!");
System.out.println(exchange.getRequest() + " request");
return chain.filter(exchange);
};
}
public static class Config {
private boolean enabled;
public Config() {}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}
Component
@Slf4j
public class MainFilter implements GatewayFilterFactory<MainFilter.Config> {
@Override
public GatewayFilter apply(Config config) {
log.info("[Apply]");
return (exchange, chain) -> {
log.info("[Apply: {}]", exchange);
System.out.println("gateway filter name " + config.getName());
return chain.filter(exchange);
};
}
@Override
public Class<Config> getConfigClass() {
return Config.class;
}
@Override
public Config newConfig() {
return new Config("MainFilter");
}
public static class Config {
public Config(String name) {
this.name = name;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
My gateway.yml file below:
server: port: 8080 management: endpoint: gateway: enabled: true endpoints: web: exposure: include: gateway spring: cloud: discovery: enabled: true gateway: discovery: locator: enabled: true lowerCaseServiceId: true # default-filters: # - name: MainFilter routes: - id: second_route uri: lb://auth-service predicates: - Path=/api/v1/** filters: - MainFilter application: loadbalancer: ribbon: enabled: false
But when i create request for service localhost:8080/auth-service/api/v1/ Filter not working. I don't see mwssahe log.info() on my console. But when i use conditions default-filter in my gateway.yml my custom filter is working. What problem for use custom filter with my route?
Upvotes: 3
Views: 3241
Reputation: 467
Most likely your filter doesn't work because the incoming request doesn't match the path predicate from your configuration
The route is configured as
routes:
- id: second_route
uri: lb://auth-service
predicates:
- Path=/api/v1/**
filters:
- MainFilter
where MainFilter is applied to all requests that match the path predicate /api/v1/**
.
If we take a closer look at the predicate, the incoming request path should:
/api/v1
/api/v1
segment (the **
is similar to regex .*
expression and will match everything)Therefore the following request urls should be matched:
But when i create request for service localhost:8080/auth-service/api/v1/ Filter not working
Based on the path predicate mapping information provided above, your request should not be matched the path predicate you defined.
Your request has the following path/auth-service/api/v1
while gateway is looking for path like /api/v1/
.
Since no routes are matched, gateway ignores the request and allows it to go further in the pipeline where I assume your auth-service API matches the mapping and corresponding controller returns the response directly without the gateway
In speaking about default filters, they will handle all requests no matter what URL/Header/Query they have.
You should be able to find the path matcher logs using the following configuration
logging:
level:
org.springframework.cloud.gateway: TRACE
reactor.netty.http.client: TRACE
Then look for logs similar to this:
Pattern "[/api/v1/**]" does not match against value "/auth-service/api/v1"
Pattern "/api/v1/**" matches against value "/api/v1/"
Additional information about path predicates could be found here:
Upvotes: 0