elasticsearch plug in development tutorial

  • 2020-08-22 21:59:04
  • OfStack

The retrieval engine Elasticsearch supports the plug-in pattern. Sometimes you may need to install a plugin. You can even develop your own plug-ins. Here is a demo of ES plug-in development, version 1.5.2 of ES.

1. The plug-in class inherits from org.elasticsearch.plugins.AbstractPlugin


package org.elasticsearch.plugin.helloworld;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.plugins.AbstractPlugin;
import org.elasticsearch.rest.RestModule;

public class HelloWorldPlugin extends AbstractPlugin {
 final ESLogger logger = Loggers.getLogger(getClass());

 @Override
 public String name() {
 // The plug-in name 
 return "HelloWorld";
 }

 @Override
 public String description() {
 // Plug-in description 
 return "Hello World Plugin";
 }
 
 // Processing modules, because there are many kinds of systems Module , so its type needs to be inferred 
 @Override
 public void processModule(Module module) {
 if(module instanceof RestModule) {
  ((RestModule)module).addRestAction(HelloWorldHandler.class);
 }
 
 if(module instanceof HelloModule) {
  logger.info("############## process hello module #####################");
 }
 }
 
 @Override
 public Collection<Module> modules(Settings settings) {
 // Create your own collection of modules 
 // If you do not define your own module, you can return null 
 HelloModule helloModule = new HelloModule();
 ArrayList<Module> list = new ArrayList<>();
 list.add(helloModule);
 Collections.unmodifiableList(list);
 return list;
 }
 
 @SuppressWarnings("rawtypes")
 @Override
 public Collection<Class<? extends LifecycleComponent>> services() {
 // Create your own collection of service classes that you need to inherit from LifecycleComponent . ES It takes the initiative to create and invoke an instance of the service class itself start methods 
 // Suppose you don't define your own service class. Can return null 
 Collection<Class<?
 extends LifecycleComponent>> list = new ArrayList<>();
 list.add(HelloService.class);
 return list;
 }
 
}

The Module class actually defines the dependency injection rules. Assuming that it is not clear, I can go to the Google Guice document, which is basically 1. HelloModule in the example above:


package org.elasticsearch.plugin.helloworld;

import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.inject.Scopes;

public class HelloModule extends AbstractModule {

 @Override
 protected void configure() {
 // will InjectableService Interface types are bound to InjectableServiceImpl The implementation class 
 // When injection is required InjectableService "Will be used InjectableServiceImpl The instance 
 bind(InjectableService.class).to(InjectableServiceImpl.class);
 // make HelloService Is the singleton state 
 bind(HelloService.class).in(Scopes.SINGLETON);
 }
 
}

Different modules have different processing methods. For example, for RestModule in the sample, 1 Handler is added:


package org.elasticsearch.plugin.helloworld;

import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.RestRequest.Method;
import org.elasticsearch.rest.RestResponse;


public class HelloWorldHandler extends BaseRestHandler {

 // Injection of objects 
  @Inject
  protected HelloWorldHandler(Settings settings, RestController controller, Client client) {
 super(settings, controller, client);
 // Will the Handler Bind to a query path 
 controller.registerHandler(Method.GET, "/hello/", this);
 controller.registerHandler(Method.GET, "/hello/{name}", this);
 }

 // Requests for binding paths are processed 
 @Override
 protected void handleRequest(RestRequest request, RestChannel channel, Client client) throws Exception {
 logger.debug("HelloWorldAction.handleRequest called");
 final String name = request.hasParam("name") ? request.param("name") : "world";
 
 String content = "{\"success\":true, \"message\":\"hello " +name+ "\"}";
 
 RestResponse response = new BytesRestResponse(RestStatus.OK, BytesRestResponse.TEXT_CONTENT_TYPE, content);
 channel.sendResponse(response);
 }
}

Finally, add a property file named ES29en-ES30en. properties under the classpath root folder to specify the plug-in implementation class:


plugin=org.elasticsearch.plugin.helloworld.HelloWorldPlugin

2. Pack the plug-in into jar package and install

If ES_HOME represents the Elasticsearch installation folder. Create a folder named HelloWorld under the ES_HOME/plugins folder. The folder name must be the same as the plug-in name (distinguish upper and lower case), then copy the jar package to the HelloWorld folder, and once again boot it up when you run:
curl-GET localhost:9200/hello, the corresponding result will be returned.

3. Add pages to the plug-in

Suppose you want to add a query page to your plug-in. You can create a folder named "_site" under the folder ES_HOME/plugins/HelloWorld. The folder name must be _site. Then you can put the corresponding html page into the folder _site

localhost: 9200 / _plugin HelloWorld/index html � asked.
Because Elasticsearch offers jsclientAPI. Therefore, using html static pages and js can complete the corresponding functions.


Related articles: