Convert RestWrapper to an explicit Interceptor (#104291)

Adds a new `RestInterceptor` interface and converts
`RestServerActionPlugin.getRestHandlerInterceptor` to return this new
type instead of a wrapping function.

This has the following benefits:
- Less object creation, there is 1 instance of the interceptor class
  (see `SecurityRestFilter`) rather than an instance per handler
- More control over the sequence of steps in processing a request.
  The explicit interceptor separates it from the deprecation handler
  or any validation that might be needed, and the controller can be
  intentional about the order in which these operations are applied.
This commit is contained in:
Tim Vernum 2024-01-19 12:08:06 +11:00 committed by GitHub
parent 4ea815932b
commit f3bc319b13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 179 additions and 143 deletions

View file

@ -8,6 +8,7 @@
package co.elastic.elasticsearch.test;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.client.internal.node.NodeClient;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
@ -18,12 +19,11 @@ import org.elasticsearch.plugins.interceptor.RestServerActionPlugin;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;
import org.elasticsearch.rest.RestInterceptor;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.telemetry.tracing.Tracer;
import org.elasticsearch.usage.UsageService;
import java.util.function.UnaryOperator;
public class CustomRestPlugin extends Plugin implements RestServerActionPlugin {
private static final Logger logger = LogManager.getLogger(CustomRestPlugin.class);
@ -35,34 +35,33 @@ public class CustomRestPlugin extends Plugin implements RestServerActionPlugin {
}
}
public static class CustomInterceptor implements RestHandler {
public static class CustomInterceptor implements RestInterceptor {
private final ThreadContext threadContext;
private final RestHandler delegate;
public CustomInterceptor(ThreadContext threadContext, RestHandler delegate) {
public CustomInterceptor(ThreadContext threadContext) {
this.threadContext = threadContext;
this.delegate = delegate;
}
@Override
public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws Exception {
public void intercept(RestRequest request, RestChannel channel, RestHandler targetHandler, ActionListener<Boolean> listener)
throws Exception {
logger.info("intercept request {} {}", request.method(), request.uri());
echoHeader("x-test-interceptor", request, threadContext);
delegate.handleRequest(request, channel, client);
listener.onResponse(Boolean.TRUE);
}
}
public static class CustomController extends RestController {
public CustomController(
UnaryOperator<RestHandler> handlerWrapper,
RestInterceptor interceptor,
NodeClient client,
CircuitBreakerService circuitBreakerService,
UsageService usageService,
Tracer tracer
) {
super(handlerWrapper, client, circuitBreakerService, usageService, tracer);
super(interceptor, client, circuitBreakerService, usageService, tracer);
}
@Override
@ -74,19 +73,19 @@ public class CustomRestPlugin extends Plugin implements RestServerActionPlugin {
}
@Override
public UnaryOperator<RestHandler> getRestHandlerInterceptor(ThreadContext threadContext) {
return handler -> new CustomInterceptor(threadContext, handler);
public RestInterceptor getRestHandlerInterceptor(ThreadContext threadContext) {
return new CustomInterceptor(threadContext);
}
@Override
public RestController getRestController(
UnaryOperator<RestHandler> handlerWrapper,
RestInterceptor interceptor,
NodeClient client,
CircuitBreakerService circuitBreakerService,
UsageService usageService,
Tracer tracer
) {
return new CustomController(handlerWrapper, client, circuitBreakerService, usageService, tracer);
return new CustomController(interceptor, client, circuitBreakerService, usageService, tracer);
}
}