How to develop custom plugin for ElasticSearch 2.2
What is Plugin:
Plugins are a way to enhance the basic elasticsearch functionality in a custom manner. They range from adding custom mapping types, custom analyzers, native scripts, custom discovery and more.
There are three types of plugins:
- Java plugins
These plugins contain only JAR files, and must be installed on every node in the cluster. After installation, each node must be restarted before the plugin becomes visible.
- Site plugins
These plugins contain static web content like Javascript, HTML, and CSS files, that can be served directly from Elasticsearch.
http://yournode:9200/_plugin/[plugin name]
- Mixed plugins
Mixed plugins contain both JAR files and web content.
Here, I am going to develop Java Plugins.
1. Create one simple Maven project from Eclipse.
2. Add below things to your pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.elasticsearch</groupId>
<artifactId>es_plugin</artifactId>
<version>1.1</version>
<packaging>jar</packaging>
<name>es_plugin</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.2.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>${project.build.directory}/releases/</outputDirectory>
<descriptors>
<descriptor>${basedir}/src/main/assemblies/plugin.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>
3. In side src folder, you should have these three folders.
src -> assemblies, java and resources subfolder
4. Inside assemblies folder, plugin.xml
5. Inside resources, plugin-descriptor.properties file should be there.
6. Inside java folder, all java file under package, In my case
java\org\elasticsearch\es_plugin this folder has three java file.
- App.java
- ExampleRestModule.java
- HelloRestHandler.java
** plugin.xml **
<?xml version="1.0"?>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>plugin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
</dependencySet>
</dependencySets>
</assembly>
** plugin-descriptor.properties **
# All plugins, be they site or Java plugins, must contain a file called plugin-descriptor.properties in the root directory.
# Elasticsearch plugin descriptor file
description=Binod Suman ES Demo Plugin
version=1.1
# 'name': the plugin name
name=Binod ES Plugin Demo
jvm=true
# 'classname': the name of the class to load, fully-qualified.
#classname=com.netiq.scm.SCMPlugin
classname=org.elasticsearch.es_plugin.App
java.version=1.8
elasticsearch.version=2.2.1
** App.java **
package org.elasticsearch.es_plugin;
import java.util.Collection;
import java.util.Collections;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.plugins.Plugin;
@SuppressWarnings("static-method")
public class App extends Plugin {
@Override
public String name() {
return "Binod Suman ElasticSearch Demo Name";
}
@Override
public String description() {
return "** Purpose for this plugin to how to write first ElasticSearch Demo";
}
@Override
public Collection
nodeModules() {
return Collections.
singletonList(new ExampleRestModule());
}
}
** ExampleRestModule.java **
package org.elasticsearch.es_plugin;
import org.elasticsearch.common.inject.AbstractModule;
public class ExampleRestModule extends AbstractModule {
@Override
protected void configure() {
bind(HelloRestHandler.class).asEagerSingleton();
}
}
** HelloRestHandler.java **
package org.elasticsearch.es_plugin;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
public class HelloRestHandler extends AbstractComponent {
@Inject
public HelloRestHandler(Settings settings) {
super(settings);
System.out.println("**** Hello I am here in HelloResthandler Module of ES 2 **");
}
}
** Now build your code by pom.xml **
mvn clean install
It will create one jar file "es_plugin.jar" inside target folder.
Create one folder in side your ElasticSearch installation Plugin folder. In my case, I created one folder
binod-demo-plugin inside E:\Software\elasticsearch-2.2.1\plugins folder.
Inside E:\Software\elasticsearch-2.2.1\plugins\binod-demo-plugin folder, I kept these two files:
es_plugin.jar
plugin-descriptor.properties
Now try to restart ElasticSearch.
E:\Software\elasticsearch-2.2.1\bin>elasticsearch.bat
[2016-03-22 23:03:38,140][INFO ][node ] [Bison] version[2.2.1], pid[13000], build[d045fc2/2016-03-09T09:38:54Z]
[2016-03-22 23:03:38,141][INFO ][node ] [Bison] initializing ...
[2016-03-22 23:03:38,689][INFO ][plugins ] [Bison] modules [lang-expression, lang-groovy], plugins [
Binod ES Plugin Demo, scm], sites []
[2016-03-22 23:03:38,712][INFO ][env ] [Bison] using [1] data paths, mounts [[New Volume (E:)]], net usable_space [66.1gb], net total_space [157.8gb], spins? [unknown], types [NTFS]
[2016-03-22 23:03:38,712][INFO ][env ] [Bison] heap size [910.5mb], compressed ordinary object pointers [true]
[2016-03-22 23:03:38,931][INFO ][http ] [Bison] Using [org.elasticsearch.http.netty.NettyHttpServerTransport] as http transport, overridden by [SCM]
**** Hello I am here in HelloResthandler Module of ES 2 **
[2016-03-22 23:03:39,779][INFO ][com.netiq.scm.Util ] [Bison] java.home = D:\InstalledFolder\Java\jdk1.8.0_45\jre
[2016-03-22 23:03:39,780][ERROR][com.netiq.scm.Util ] [Bison] E:\Software\elasticsearch-2.2.1\config\db.properties (The system cannot find the file specified)
[2016-03-22 23:03:40,878][ERROR][com.netiq.scm.Util ] [Bison] Cannot sync configuration from SCM Core. java.net.MalformedURLException: no protocol: nullconfig/[get]
[2016-03-22 23:03:40,997][INFO ][node ] [Bison] initialized
[2016-03-22 23:03:40,997][INFO ][node ] [Bison] starting ...
-03-22 23:03:47,695][INFO ][node ] [Bison] started
Here you can see the output carefully, some message comes from your own plugin.
**** How to set Debug breakpoint *****
1. put break point of HelloRestHandler constructor
2. Add some extra parameter in elasticsearch.bat file.
For More details:
http://binodsuman.blogspot.in/2016/03/how-to-call-elasticsearch-in-debug-mode.html
3. Set one remote debug for this project in Eclipse.
4. Now start ElasticSearch.bat with extra debug parameter and start project in Eclipse.