写入源码分析
接收与处理
请求首先会被 Netty4HttpServerTransport
接收,接着交由 RestController
进行路由分发。
private void tryAllHandlers(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) throws Exception {
// 从 tier 树中,找到该请求路径对应的 RestHandler
Iterator<MethodHandlers> allHandlers = getAllHandlers(request.params(), rawPath);
while (allHandlers.hasNext()) {
final RestHandler handler;
final MethodHandlers handlers = allHandlers.next();
if (handlers == null) {
handler = null;
} else {
handler = handlers.getHandler(requestMethod, restApiVersion);
}
if (handler == null) {
if (handleNoHandlerFound(rawPath, requestMethod, uri, channel)) {
return;
}
} else {
// 找到后,将本次请求转发给该 RestHandler
dispatchRequest(request, channel, handler, threadContext);
return;
}
}
}
那么 ES 如何知道对应的路由应该由谁处理呢?
在 Node
初始化时,会执行 ActionModule#initRestHandlers(...)
public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster) {
...
...
// 注册路由
registerHandler.accept(new RestIndexAction());
...
...
}
RestIndexAction
注册的路由如下所示
public List<Route> routes() {
return List.of(
new Route(POST, "/{index}/_doc/{id}"),
new Route(PUT, "/{index}/_doc/{id}"),
Route.builder(POST, "/{index}/{type}/{id}").deprecated(TYPES_DEPRECATION_MESSAGE, RestApiVersion.V_7).build(),
Route.builder(PUT, "/{index}/{type}/{id}").deprecated(TYPES_DEPRECATION_MESSAGE, RestApiVersion.V_7).build()
);
}
每个 RestHandler
在 prepareRequest(final RestRequest request, final NodeClient client)
都会声明与之绑定的 TransportAction
,之后所有逻辑会交由 TransportAction
处理。
其绑定的 TransportAction
为 TransportIndexAction
。
RestIndexAction#prepareRequest(...)
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {