Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Build a Plugin and Add a Listener to an Index in ElasticSearch 5

DZone's Guide to

Build a Plugin and Add a Listener to an Index in ElasticSearch 5

The WebSocket Change Feed plugin is not naturally compatible with ElasticSearch, but you can build your own code to make it work.

· Database Zone
Free Resource

Want to free your enterprise from the costs of provisioning servers? Learn about serverless architecture with Couchbase and cloud computing.

ElasticSearch 5.x is pretty exciting release with many cool features. However, this new release is very different than the older versions of ES, especially when it comes to the plugin. Today, we needed to use a plugin called WebSocket Change Feed Plugin (by ForgeRock/Chris Clifton) (it was also recommended in ES5 documentations).

We thought it would be adaptable with ES5. However, it is not compatible (and perhaps ES did not update their documentation). I'll try to upgrade the WebSocket plugin to ES5 and will share the results later, too. In the meantime, I googled to see were there any guidelines or documentation on how to build an ES5 plugin where you can attach a listener to an index lifecycle. For some reason, I could not find any. Hence, I spent a few hours and finally, I managed to make it work.

You can see the simple code on GitHub.

POM 

You need to get your dependencies right. Please have a look at my pom.xml.

ES Resources and the Plug Assembly File

You will need to have a properties file that tells to ES about the metadata of this plugin, which is as below:

description=${project.description}.
version=${project.version}
name=${project.artifactId}
classname=com.chrisshayan.plugins.ElasticSearchPlugin
java.version=1.8
elasticsearch.version=${elasticsearch.version}

Line 4 (classname) is the full qualified classname of your main Plugin file. ES needs to know this while it is running your plugin. Also, there's the plugin.xml file that tells to Maven how to treat it in the packaging:

<?xml version="1.0"?>
<assembly>
	<id>plugin</id>
	<formats>
		<format>zip</format>
	</formats>
	<includeBaseDirectory>false</includeBaseDirectory>
	<files>
		<file>
			<source>${basedir}/src/main/resources/plugin-descriptor.properties</source>
			<outputDirectory>elasticsearch</outputDirectory>
			<filtered>true</filtered>
		</file>
	</files>
	<dependencySets>
		<dependencySet>
			<outputDirectory>elasticsearch</outputDirectory>
			<useProjectArtifact>true</useProjectArtifact>
			<useTransitiveFiltering>true</useTransitiveFiltering>
		</dependencySet>
	</dependencySets>
</assembly>

How to Add a Listener to an Index?

It's quite straightforward. You need to extend the Plugin class and then add your IndexEventListener to the IndexModule as shown in following code (Lines 13-25):

public class ElasticSearchPlugin extends Plugin {
    private final Logger logger = Loggers.getLogger(ElasticSearchPlugin.class);

    @Override
    public Collection<Module> createGuiceModules() {
        Collection<Module> modules = new ArrayList<>(1);
        modules.add(new PluginModule());

        return modules;
    }

    @Override
    public void onIndexModule(IndexModule indexModule) {
        indexModule.addIndexEventListener(new IndexEventListener() {
            @Override
            public void afterIndexCreated(IndexService indexService) {
                logger.info("afterIndexCreated :" + indexService.getMetaData().getIndex().getName());
            }

            @Override
            public void afterIndexRemoved(Index index, IndexSettings indexSettings, IndicesClusterStateService.AllocatedIndices.IndexRemovalReason reason) {
                logger.info("afterIndexRemoved :" + index.getName());
            }
        });
    }
}

Hopefully, this quick post saves a few hours of yours!

Learn how the world’s first Engagement Database can lower your costs and simplify deployments with Couchbase in the cloud.

Topics:
elasticsearch ,tutorial ,database ,plugin development ,websocket

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}