Creating an Elasticsearch Plugin Series (1) Hello World

In this series, I will explain the basic way to write plugins in Elasticsearch. Part 1 will create a REST API that displays "Hello World". The created source can be found on github.

Purpose

Create an Elasticsearch Plugin that displays "Hello Wolrd" when you access the specified URL.

Implementation overview

Use the Gradle plugin to create an Elasticsearch plugin. This plug-in is included in Elasticsearch's OSS, but there are almost no documents, and the operating specifications may change due to major version upgrades. Therefore, it is necessary to consider those risks when using it. For 7 series Gradle plug-in, it seems that the download source of the Elasticsearch module is the internal URL. As a result, the gradle plugin fails to launch Elasticsearch for testing. In this tutorial, you will download Elasticsearch separately, install the Plugin manually, and start Elasticsearch.

Operating environment

** Gradle plugin for Elasticsearch 7.4.2 requires Java 12 or above. Gradle 6.0 is required to work with Java 13). Therefore, it is this combination when making an Elasticsearch 7.4 plug-in at present) **

Notation in the article

-[~] is a variable according to the environment. Please read according to your own environment.

Advance preparation

--Install Elasticsearch OSS version Expand to [ELASTICSEARCH_DIR] --Install Gradle RC version Expand to [GRADLE_DIR] --Install JDK OracleJDK Place in [JAVA_DIR]

Project preparation

The project shall be placed in [PROJECT_DIR].

The project will have the following structure

--place the java source that is the source of the class bundled in the src / main / java jar. --place various resources bundled in src / main / resources jar. --src / main / plugin-metadata Places unique settings for Eclipse plugins such as security policy. --src / test / java Place the java source for testing. --src / test / resources Place various resources for testing. --settings.gradle This file is required to set the project configuration. --build.gradle This file is required to set tasks when building a project.

Create settings.gradle

Since this is a single project configuration, specify only the project name. The project name will be the prefix of the jar file or the project name when imported into a development environment such as Eclipse.

rootProject.name = 'elasticsearch-sample-plugins'

create build.gradle

Make specific settings for creating the JVM version (targetVersion) of the operating environment and the Elasticsearch plug-in.

buildscript {
	repositories {
		mavenLocal()
		mavenCentral()
		jcenter()
	}
    dependencies {
 // Elasticsearch publishes build tools in maven's central repository.
    	// https://mvnrepository.com/artifact/org.elasticsearch.gradle/build-tools
    	classpath group: 'org.elasticsearch.gradle', name: 'build-tools', version: '7.4.2'		
    }
}

plugins {
	id 'java'
 // maven required to resolve dependencies
	id 'maven'
 // Required when using Eclipse as a development environment
	id 'eclipse'
}

 // The name of the Gradle plugin to build the plugin
apply plugin: 'elasticsearch.esplugin'

sourceCompatibility = 1.8
 // Make sure Elasticsearch runtime works with JDK 1.8.
targetCompatibility = 1.8

group = 'taka8.elasticsearch.plugins'
version = '0.0.1'

repositories {
	mavenLocal()
	mavenCentral()
	jcenter()
}
[compileJava, compileTestJava, javadoc]*.options*.encoding = 'UTF-8'

eclipse {
	 classpath {
		containers.clear()
		downloadSources = true
		downloadJavadoc = true
	}
}

ext {
 // If you do not set the following two, the plugin build will result in an error
	licenseFile = project.file('LICENSE')
	noticeFile = project.file('NOTICE')
}

esplugin {
 // Plugin name
	name project.name
	
 // Plugin description
	description 'Elasticsearch sample plugin'
	
 // Class that is the entrance to the plugin
	classname 'taka8.elasticsearch.plugins.SamplePlugin'
}

Plugin source preparation

Create a class that will be the entry point for the plugin

Create a class with the class name (FQCN) set in esplugin.classname of build.gradle under "src / main / java".

SamplePlugin.java


package taka8.elasticsearch.plugins;

import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;

import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.IndexScopedSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.plugins.ActionPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestHandler;

import taka8.elasticsearch.rest.HelloWorldAction;

//When creating a plugin for REST API, you need to implement ActionPlugin.
public class SamplePlugin extends Plugin implements ActionPlugin {

	//Returns a list of RestHandlers defined by this plugin
	@Override
	public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
			ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
			IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
		return Arrays.asList(//
				//Originally defined class(Return Hello World string
				new HelloWorldAction(restController));
	}

}

Create a RestHandler

HelloWorldAction.java


package taka8.elasticsearch.rest;

import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.HEAD;

import java.io.IOException;

import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;

//RestHandler that accepts REST API is easy to create by inheriting BaseRestHandler
public class HelloWorldAction extends BaseRestHandler {

	public HelloWorldAction(final RestController controller) {
		assert controller != null;
		//Define the path to accept the request.
		controller.registerHandler(GET, "/hello", this);
		controller.registerHandler(HEAD, "/hello", this);
	}

	//Define the name of RestHandler.
	//Make the name easy for people to see.
	//Used in APIs that return usage
	@Override
	public String getName() {
		return "hello_word_action";
	}

	@Override
	protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
		return channel -> {
			RestResponse response = new BytesRestResponse(RestStatus.OK, "Hello World");
			//Write a response to the channel
			channel.sendResponse(response);
		};
	}

}

Operation check

Setting environment variables

>set JAVA_HOME=[JAVA_DIR]
>set PATH=[GRADLE_DIR]\bin;%PATH%

Build

>gradle install

Plugin install

>cd [ELASTICSEARCH_DIR]
>.\bin\elasticsearch-plugin install file:/[PROJECT_DIR]/build/distributions/elasticsearch-sample-plugins-0.0.1.zip

** PROJECT_DIR should be in URL notation **

Launch Elasticsearch

>cd [ELASTICSEARCH_DIR]
>.\bin\elasticsearch

Screen check

Go to http : // localhost: 9200 / hello with your browser and check that "Hello World" is displayed.

Afterword

I found that it is easy to create an Elasticsearch plugin using the Gradle plugin for creating plugins. This makes little sense in actual development, but Elasticsearch actually has an API access part created in almost the same way as a plugin, so you can create a fairly sophisticated plugin. From the next time, I will explain how to make more advanced plug-ins.

Recommended Posts

Creating an Elasticsearch Plugin Series (1) Hello World
Creating an Elasticsearch Plugin Series (2) Search
Hello World for ImageJ Java Plugin
Read "Hello world"
Java, Hello, world!
Java Hello World
"Hello World" in Java
Java Learning (1)-Hello World
Read System.out.println ("hello, world")
Let's write Hello World
Hello world in node.js
Hello World in Java
Studying Java-Part 1-Hello World
Hello World on WebAssembly
Hello World with Micronaut