Skip to content
Merged
Changes from 11 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
63b3ca2
Add REST & Transport layers section to GeneralArchitectureGuide.md
nicktindall Apr 7, 2025
94d97da
Wording
nicktindall Apr 7, 2025
47f2823
More work
nicktindall Apr 7, 2025
5389469
Wording
nicktindall Apr 7, 2025
dfc3951
Wording
nicktindall Apr 7, 2025
b3ef1d3
Add hint about action naming
nicktindall Apr 7, 2025
3003256
Move note
nicktindall Apr 7, 2025
e4fdab6
Add brief description of RestController/HttpServerTransport
nicktindall Apr 8, 2025
45b5c7a
Add better explanation of action registration
nicktindall Apr 8, 2025
11e4abe
Update docs/internal/GeneralArchitectureGuide.md
nicktindall Apr 8, 2025
6d6d364
Typo
nicktindall Apr 8, 2025
867d32a
Merge remote-tracking branch 'origin/main' into add_rest_and_transpor…
nicktindall Apr 11, 2025
95cfa18
Merge remote-tracking branch 'origin/main' into add_rest_and_transpor…
nicktindall May 26, 2025
cbf7491
Attempt to reconcile new and old content
nicktindall May 26, 2025
6e01a65
Merge branch 'main' into add_rest_and_transport_layers
nicktindall May 26, 2025
344d8e4
Fix terminology
nicktindall May 26, 2025
6cc5261
Add section about RestInterceptor, fix line lengths
nicktindall May 27, 2025
fd8d00f
Add section on Transport infrastructure
nicktindall May 27, 2025
8353865
Sort links alphabetically
nicktindall May 27, 2025
1fdfb5f
Improve wording on RestController request handling
nicktindall May 27, 2025
b667284
Add step where response is sent
nicktindall May 27, 2025
837f976
Improve description of security filter
nicktindall May 27, 2025
6a6f8a1
Update docs/internal/GeneralArchitectureGuide.md
nicktindall May 28, 2025
029b101
Update docs/internal/GeneralArchitectureGuide.md
nicktindall May 28, 2025
31fdac0
Update docs/internal/GeneralArchitectureGuide.md
nicktindall May 28, 2025
4bdef35
Update docs/internal/GeneralArchitectureGuide.md
nicktindall May 28, 2025
158e09d
Update docs/internal/GeneralArchitectureGuide.md
nicktindall May 28, 2025
52ddb10
Update docs/internal/GeneralArchitectureGuide.md
nicktindall May 29, 2025
a4561da
Emphasise that only one RestInterceptor can be configured
nicktindall May 29, 2025
76b5383
Re-word section about security overriding HttpServerTransport
nicktindall May 29, 2025
f4b2b62
Remove duplicate links
nicktindall May 29, 2025
aa23318
action interceptors -> TransportInterceptors
nicktindall May 29, 2025
4e0e7bc
Disambiguate getRestHandlers link
nicktindall May 29, 2025
6529bff
De-dupe links per paragraph
nicktindall May 29, 2025
03f2af7
first mention is linked
nicktindall May 29, 2025
3e9f3c7
Add Netty links
nicktindall May 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 73 additions & 1 deletion docs/internal/GeneralArchitectureGuide.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,78 @@
# General Architecture

## Transport Actions
## REST & Transport layers

[TransportAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/TransportAction.java
[ActionPlugin]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/plugins/ActionPlugin.java
[ActionModule]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/ActionModule.java

There are two main types of network communication used in Elasticsearch:
- External clients interact with the cluster via the public REST API over HTTP connections
- Cluster nodes communicate internally using a binary message format over TCP connections

> [!NOTE]
> Cross-cluster [replication](https://www.elastic.co/guide/en/elasticsearch/reference/current/xpack-ccr.html) and [search](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cross-cluster-search.html) use binary/TCP messaging for inter-cluster communication but this is out of scope for this section
The node that a REST request arrives at is called the "coordinating" node. Its job is to coordinate the execution of the request with the other nodes in the cluster and when the requested action is completed, return the possibly aggregated response to the REST client via HTTP.

By default, all nodes will act as coordinating nodes, but by specifying `node.roles` to be empty you can create a [coordinating-only node](https://www.elastic.co/guide/en/elasticsearch/reference/current/node-roles-overview.html#coordinating-only-node-role).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a little confusing to talk about node roles given we're considering coordinating REST requests here. All nodes handle REST requests, this is not optional.


### REST Layer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general in this section, you're diving into the implementation details, but not providing many high level words to tie everything together. You could start off with a high level explanation that ties multiple classes / concepts together, and then elaborate later in the section.

Some details like "the request handling logic, and some other runtime characteristics such as path/query parameters that are supported and the content type(s) it accepts" are briefly mentioned, but not explained, and so are difficult to digest.

For example, I might start the REST section like

"All user requests are sent to REST endpoints in Elasticsearch. Each endpoint is handled in a corresponding Rest*Action.java file. All of these endpoints are implementations of the RestHandler, usually via BaseRestHandler. Each REST endpoint implementation is registered in the ActionModule and mapped to a REST endpoint. Plugins can also contribute mappings of REST endpoints to implementations, when they are activated, via the ActionPlugin#getRestHandlers interface: ActionModule#initRestHandlers iterates the plugins and registers their actions as well. .

The RestHandler#routes() method implementation specifies what endpoints are handled by a particular REST endpoint implementation. <those other attributes you mentioned -- request handling, query params>. "

With appropriate code links and more elaboration. I didn't polish this, and doesn't include everything, but to try to give an idea of what I mean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole architecture guide is an exercise in walking the line between too much and too little detail 😄 Thanks for the feedback, hopefully this second iteration is pitched at the right level.


[BaseRestHandler]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java
[RestHandler]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/rest/RestHandler.java
[Route]:https://github.com/elastic/elasticsearch/blob/0b09506b543231862570c7c1ee623c1af139bd5a/server/src/main/java/org/elasticsearch/rest/RestHandler.java#L134
[getRestHandlers]:https://github.com/elastic/elasticsearch/blob/0b09506b543231862570c7c1ee623c1af139bd5a/server/src/main/java/org/elasticsearch/plugins/ActionPlugin.java#L76
[RestBulkAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/rest/action/document/RestBulkAction.java
[RestController]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/rest/RestController.java
[HttpServerTransport.Dispatcher]:https://github.com/elastic/elasticsearch/blob/997a7b8fab6c0bcaacf963c28fe98024492960c5/server/src/main/java/org/elasticsearch/http/HttpServerTransport.java#L36
[HttpServerTransport]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/http/HttpServerTransport.java
[Netty4HttpServerTransport]:https://github.com/elastic/elasticsearch/blob/main/modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/Netty4HttpServerTransport.java

Each REST endpoint is defined by a [RestHandler] instance. [RestHandler] implementations define the list of [Route]s that they handle, the request handling logic, and some other runtime characteristics such as path/query parameters that are supported and the content type(s) it accepts. There are many built-in REST endpoints configured statically in [ActionModule], additional endpoints can be contributed by [ActionPlugin]s via the [getRestHandlers] method.

[BaseRestHandler] is the base class for almost all REST endpoints in Elasticsearch. It validates the request parameters against those which are supported, delegates to its sub-classes to set up the execution of the requested action, then delivers the request content to the action either as a single parsed payload or a stream of binary chunks. Actions such as the [RestBulkAction] use the streaming capability to process large payloads incrementally and apply back-pressure when overloaded.

The sub-classes of [BaseRestHandler], usually named `Rest{action-name}Action`, are the entry-points to the cluster, where HTTP requests from outside the cluster are translated into internal [TransportAction] invocations.

[RestHandler]s are registered with the [RestController], which implements request routing and some cross-cutting concerns. [RestController] is a [HttpServerTransport.Dispatcher], which dispatches requests for a [HttpServerTransport]. [HttpServerTransport] is our HTTP abstraction, of which there is a single [Netty-based implementation][Netty4HttpServerTransport].

> [!NOTE]
> `Rest{action-name}Action` classes often have a corresponding `Transport{action-name}Action`, this naming convention makes it easy to locate the corresponding [RestHandler] for a [TransportAction]. (e.g. `RestGetAction` calls `TransportGetAction`)
### Transport Layer

[ActionRequest]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/ActionRequest.java
[NodeClient]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/client/internal/node/NodeClient.java
[TransportMasterNodeAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeAction.java
[TransportLocalClusterStateAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/local/TransportLocalClusterStateAction.java
[TransportReplicationAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/replication/TransportReplicationAction.java
[TransportNodesAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java
[TransportSingleShardAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/single/shard/TransportSingleShardAction.java
[getActions]:https://github.com/elastic/elasticsearch/blob/0b09506b543231862570c7c1ee623c1af139bd5a/server/src/main/java/org/elasticsearch/plugins/ActionPlugin.java#L55
[ActionType]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/ActionType.java
[ActionModule#setupActions]:https://github.com/elastic/elasticsearch/blob/997a7b8fab6c0bcaacf963c28fe98024492960c5/server/src/main/java/org/elasticsearch/action/ActionModule.java#L612
[NodeClient#executeLocally]:https://github.com/elastic/elasticsearch/blob/997a7b8fab6c0bcaacf963c28fe98024492960c5/server/src/main/java/org/elasticsearch/client/internal/node/NodeClient.java#L101
[TransportService#sendRequest]:https://github.com/elastic/elasticsearch/blob/997a7b8fab6c0bcaacf963c28fe98024492960c5/server/src/main/java/org/elasticsearch/transport/TransportService.java#L767
[TransportService#registerRequestHandler]:https://github.com/elastic/elasticsearch/blob/997a7b8fab6c0bcaacf963c28fe98024492960c5/server/src/main/java/org/elasticsearch/transport/TransportService.java#L1197
[HandledTransportAction]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/action/support/HandledTransportAction.java
[TransportService]:https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/transport/TransportService.java

When `Rest{action-name}Action` handlers receive a request, they typically translate the request into a [ActionRequest] and dispatch it via the provided [NodeClient]. The [NodeClient] is the entrypoint into the "transport layer" over which internal cluster actions are coordinated.

Elasticsearch contains many built-in [TransportAction]s, configured statically in [ActionModule], additional actions can be contributed by [ActionPlugin]s via the [getActions] method. [TransportAction]s define the request and response types used to invoke the action and the logic for performing the action.

[TransportAction]s that are registered in [ActionModule#setupActions] (including those supplied by plugins) are locally bound to their [ActionType]. This map of `type -> action` bindings is what [NodeClient] instances use to locate actions in [NodeClient#executeLocally].

The [NodeClient] executes all actions locally on the invoking node, the actions themselves sometimes dispatch downstream actions to other nodes in the cluster via the transport layer (see [TransportService#sendRequest]). To be callable in this way, actions must register themselves with the [TransportService] by calling [TransportService#registerRequestHandler]. [HandledTransportAction] is a common parent class which registers an action with the [TransportService].

There are a few common patterns for [TransportAction] execution which are present in the codebase. Some prominent examples include...

- [TransportMasterNodeAction]: Executes an action on the master node. Typically used to perform cluster state updates, as these can only be performed on the master. The base class contains logic for locating the master node and delegating to it to execute the specified logic.
- [TransportNodesAction]: Executes an action on many nodes then collates the responses.
- [TransportLocalClusterStateAction]: Waits for a cluster state that optionally meets some criteria and performs a read action on it on the coordinating node.
- [TransportReplicationAction]: Execute an action on a primary shard followed by all replicas that exist for that shard. The base class implements logic for locating the primary and replica shards in the cluster and delegating to the relevant nodes. Often used for index updates in stateful Elasticsearch.
- [TransportSingleShardAction]: Executes a read operation on a specific shard, the base class contains logic for locating an available copy of the nominated shard and delegating to the relevant node to execute the action. On a failure, the action is retried on a different copy.

## Serializations

Expand Down
Loading