Elasticsearch provides a rich set of Java calling interfaces by constructing a client representation. In general, the client is divided into two types of cluster information in terms of client and data (index) aspects of the client. These two categories can be divided into ordinary operations and the admin operation of the two classes. The following are the client inheritance relationships (version 1.5, other versions may be different):
With this inheritance diagram, you can clearly understand the implementation of the client and its functions. There are three categories: client, indicesadminclient and clusteradminclient. It has its own implementation class, but in the end it provides services externally through the client interface. Client as the external total interface, first through the admin () method to combine the relevant operation of the admin, it also provides all the data and cluster common operation.
Method implementation, all interfaces are implemented in two ways asynchronous invocation, one is to return a actionfuture, the other is to accept a ActionListener. Take the index method as an example, as shown below
Actionfuture<indexresponse> index (indexrequest request);
void index (Indexrequest request, actionlistener<indexresponse> Listener);
The first method returns a future, and the second method needs to pass a listener. This is also the two basic way of implementing async. The client uses the façade pattern, all implementations are in the Abstractclient class, and the index method is the example where the code looks like this:
@Override public actionfuture<indexresponse> index (final Indexrequest request) { return Execute (indexaction.instance, request); } @Override publicvoid index (finalfinal actionlistener< Indexresponse> Listener) { Execute (indexaction.instance, request, listener); }
The implementation, as shown above, is that it is a façade pattern because all methods are integrated into the client, but the execution is performed in the action that should be taken. In the Execute method, the corresponding action instance is obtained, and the real logic is implemented in the corresponding transportaction. As shown in the following code:
@SuppressWarnings ("Unchecked") @Override Public<requestextendsActionrequest, ResponseextendsActionresponse, RequestbuilderextendsActionrequestbuilder<request, Response, Requestbuilder, client>> actionfuture<response> Execute ( Action<request, Response, Requestbuilder, client>action, request request) {Headers.applyto (request); Transportaction<request, response> transportaction =Actions.get ((clientaction) action); returnTransportaction.execute (Request); } @SuppressWarnings ("Unchecked") @Override Public<requestextendsActionrequest, ResponseextendsActionresponse, RequestbuilderextendsActionrequestbuilder<request, Response, Requestbuilder, client>>voidExecute (action<request, Response, Requestbuilder, client> Action, request request, Actionlistener<response >listener) {Headers.applyto (request); Transportaction<request, response> transportaction =Actions.get ((clientaction) action); Transportaction.execute (request, listener); }
Each operation should have corresponding transportaction, these transportaction is the final performer. This is a simple analysis with index as an example, and more results will be seen in the subsequent index function analysis.
Public classIndexactionextendsClientaction<indexrequest, Indexresponse, indexrequestbuilder> { Public Static FinalIndexaction INSTANCE =Newindexaction (); Public Static FinalString NAME = "Indices:data/write/index"; Privateindexaction () {Super(NAME); } @Override Publicindexresponse Newresponse () {return NewIndexresponse (); } @Override PublicIndexrequestbuilder newrequestbuilder (client client) {return Newindexrequestbuilder (client); }}
In Indexaction, it simply defines a name, and a few simple methods. This noun is registered in the client as the key to the transportaction at startup. In the Execute method, the transportclient is removed according to the name of the action as shown in the previous code. The real execution logic is in the internaltransportclient, which first skips its implementation, followed by a detailed analysis. All of these action registrations are implemented in Actionmodule, and the registration process is parsed with the action later.
Summary: The client module integrates all operations into the client interface through the proxy mode. This allows the external call to simply initialize the client to complete all invocation functions. The execution logic of these interfaces is in the corresponding transportaction. This ingenious design offers great convenience to the user.
Elasticsearch Client Introduction to Java clients