elastic/elasticsearch
Action layer
Every request that reaches Elasticsearch — whether from a REST client, a peer node, or a local plugin — flows through the action layer. The layer turns "I want to do X" into a concrete pair of (ActionType, Request) -> Response and routes it to the right handler on the right node.
Purpose
- One canonical way to invoke any cluster operation, regardless of whether the caller is on the same node, a different node, or an external HTTP client.
- A registration model that lets plugins contribute new actions without modifying the server.
- Built-in retry, timeout, audit (security), tracing, and cancellation semantics.
Directory layout
server/src/main/java/org/elasticsearch/action/
├── ActionModule.java Catalog of all actions; wires REST handlers
├── ActionType.java, Action*.java Generic action plumbing (listener, request, response)
├── HandledTransportAction.java Common base for transport actions
├── support/
│ ├── master/ TransportMasterNodeAction etc.
│ ├── nodes/ TransportNodesAction (fan-out to all nodes)
│ ├── single/shard/ TransportSingleShardAction (one shard)
│ ├── broadcast/ TransportBroadcastByNodeAction
│ ├── replication/ TransportReplicationAction (primary + replica)
│ └── ...
├── admin/ Admin actions (cluster + indices admin)
├── bulk/ Bulk indexing
├── search/ Search action and friends
├── get/, index/, update/, delete/ Single-document CRUD
├── ingest/, fieldcaps/, termvectors/ More user-facing actions
└── ...
server/src/main/java/org/elasticsearch/rest/
├── RestController.java HTTP route table
├── BaseRestHandler.java Base for Rest*Action
├── action/ Rest*Action implementations
└── ...Key abstractions
| Type | File | Role |
|---|---|---|
ActionType<Response> |
server/src/main/java/org/elasticsearch/action/ActionType.java |
Identity of an action (string name + response type) |
ActionModule |
server/src/main/java/org/elasticsearch/action/ActionModule.java |
Registers every built-in action and contributes plugin actions |
HandledTransportAction |
server/src/main/java/org/elasticsearch/action/support/HandledTransportAction.java |
Most common base; runs locally on the receiving node |
TransportMasterNodeAction |
server/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeAction.java |
Forwards to the elected master |
TransportNodesAction |
server/src/main/java/org/elasticsearch/action/support/nodes/TransportNodesAction.java |
Fan-out to all nodes, gather, reduce |
TransportSingleShardAction |
.../single/shard/TransportSingleShardAction.java |
Reads from one (preferred) shard |
TransportReplicationAction |
.../replication/TransportReplicationAction.java |
Writes to a primary then replicates |
TransportBroadcastByNodeAction |
.../broadcast/node/TransportBroadcastByNodeAction.java |
Per-shard broadcast bucketed by node |
RestHandler / BaseRestHandler |
server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java |
REST entry; declares HTTP routes via routes() |
RestController |
server/src/main/java/org/elasticsearch/rest/RestController.java |
Dispatches HTTP requests to a RestHandler, applies tracing, security, deprecation handling |
NodeClient |
server/src/main/java/org/elasticsearch/client/internal/node/NodeClient.java |
Local executor for action types |
How a REST request flows
sequenceDiagram participant HTTP as Netty4 HTTP server participant RC as RestController participant RA as Rest*Action participant NC as NodeClient participant TS as TransportService participant TA as Transport*Action HTTP->>RC: HTTP request RC->>RC: route lookup, security audit, deprecation, tracing RC->>RA: RestRequest, RestChannel RA->>NC: client.execute(ActionType, Request, Listener) NC->>TS: transportService.sendChildRequest(...) TS-->>TA: invoke local handler (or send to remote) TA-->>TS: Response TS-->>NC: Response NC-->>RA: Response RA-->>RC: build XContent and reply RC-->>HTTP: HTTP response
The NodeClient resolves the ActionType to a registered TransportAction via the Map<ActionType<?>, TransportAction<?, ?>> populated by ActionModule. Local actions run inline; remote actions are forwarded over TransportService.
Registering a new action
- Define
MyAction extends ActionType<MyResponse>(typically as a staticINSTANCEfield on a request/response class). - Implement
MyTransportAction extends HandledTransportAction<MyRequest, MyResponse>(or one of the specialized bases). - Implement
RestMyAction extends BaseRestHandlerand overrideroutes()andprepareRequest(). - Server-side: add to
ActionModule.actions()andActionModule.restHandlers(). - Plugin-side: contribute via
ActionPlugin.getActions()andActionPlugin.getRestHandlers().
ActionModule is enormous (~thousands of lines) precisely because it holds the catalog. Search for any ActionType.INSTANCE to find its registration site.
Transport action specializations
| Base | Use when |
|---|---|
HandledTransportAction |
The action runs locally on the node that receives it. |
TransportMasterNodeAction |
The action mutates cluster state or must run on the master. |
TransportMasterNodeReadAction |
Read-only equivalent — can be served by a non-master if local: true is requested. |
TransportNodesAction |
Fan out to every node, gather per-node responses, reduce. |
TransportBroadcastByNodeAction |
Like TransportNodesAction but bucketed by shard ownership. |
TransportSingleShardAction |
Read from exactly one (preferred) shard, with retry on failover. |
TransportReplicationAction |
Two-phase write: primary -> replicas. |
TransportInstanceSingleOperationAction |
Like single-shard but for instance-level operations. |
TransportLocalProjectMetadataAction |
Stateless variant for the project metadata APIs. |
Pick the lightest base that does what you need; the framework handles retries, timeouts, and shard relocation.
Security and audit integration
X-Pack security wraps the action layer with an ActionFilter that authorizes each call against the caller's effective roles. Action names follow the <scope>:<sub-scope>/<verb> convention precisely so that role-based privilege resolution can match patterns (e.g. indices:data/read/*).
Cancellation
Long-running actions implement CancellableTask. The action layer threads a Task through every call; clients can cancel via POST /_tasks/<id>/_cancel. Search and ES|QL both honor this cooperatively.
Tests
- Action serialization: every
Request/Responsehas aWriteableround-trip test. - Action behavior: integration tests in
internalClusterTestexercise the full path including replication and master forwarding. - REST: YAML REST tests covering the HTTP surface.
See Patterns and conventions for the recipe.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.