Elastic Search @ 6.4.3

DZone 's Guide to

Elastic Search @ 6.4.3

In this article, we discuss how to write a simple Java service to expose a specific computation on top of an elastic search query.

· Big Data Zone ·
Free Resource


Elastic - 6.4.3

Working with Elastic is quite fun. You can simply use a query string URL or compose a Java program using the Java high-level/low-level client to consume and return the results.

In this blog, I am going to write a simple Java service that will expose a specific computation on top of an elastic search query. You can read more at the elastic.co

I will write a simple Sprint Boot application that will expose a few endpoints, allowing users to invoke queries on a predefined index, which can be customized.

You may also like: Hunting the ELK (Stack): Data Monitoring to Visualization

Step 1: Dependency Check

The version and the libraries I am using are:

  • Dependencies Java-JDK 1.8 (AdoptOpenJDK).
  • Maven 3.
  • Spring Boot — 2.2.1. RELEASE.

One might question why you'd want to write a service on top of a service. Well, in my case, I wanted to run a specific query that had to be exposed as a URL instead of a request body, and unfortunately, the version that I had to work with was 6.4.3, not the latest 7.4, which could have made this process much simpler.


Expose two endpoints as REST endpoints (unsecured):

  •  /es: Returns customized information about the cluster and the version of ES.

  •  /metric: Returns the response of my customized query (more information below).

Step 2: Spring.io Starter

As with most of my sample blogs, I start at https://start.spring.io/ to create the project space.


<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<relativePath/> <!-- lookup parent from repository -->

<description>Metrics counter</description>







We need to add the RestHighLevelClient dependency in the POM.xml file.



With pom defined it was time to start writing my code. I did add some debug details to check all the beans that will be created when I boot up my application. More information about CommandLineRunner can be found here.

public class MetricsApplication {

public static void main(String[] args) {
SpringApplication.run(MetricsApplication.class, args);

public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {

System.out.println("Let's inspect the beans provided by Spring Boot:");

String[] beanNames = ctx.getBeanDefinitionNames();
for (String beanName : beanNames) {



The first thing I did was add an application.properties for my project that contains the hostname and the required index information


Step 3: New Objects

After defining the properties, it is time to create the configuration object that will construct the high-level client of ES.

public class ElasticsearchConfig {

    private String elasticsearchHost;

    private String indexName;

    @Bean(destroyMethod = "close")
    public RestHighLevelClient client() {

        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost(elasticsearchHost)));

        return client;


    public SearchRequest searchRequest()
        SearchRequest searchRequest = new SearchRequest(indexName);
        return searchRequest;


It is a simple definition for creating the RestHighLevelClient and the SearchRequest. More details are available on the website elastic.co.

The basic building blocks are available, so, now, it's time to define a service that will invoke the search on ES when invoked.

public class MetricService {
    private RestHighLevelClient restClient;
    private SearchRequest searchRequest;

    public MetricService(RestHighLevelClient restClient, SearchRequest searchRequest) {
        this.restClient = restClient;
        this.searchRequest = searchRequest;

    /** Cluster information as read from the response **/
    public String clusterInfo() {
              MainResponse response = restClient.info(RequestOptions.DEFAULT);

              XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
                      .field("version", response.getVersion().toString())
              return Strings.toString(builder);
         }catch (IOException ex){

         return "ERROR: 500";


    /** Metric information that is composite query which has Must and Should **/
    public String getMetric() {

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchSourceBuilder.sort(new FieldSortBuilder("@timestamp").order(SortOrder.DESC));
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        List<QueryBuilder> mustQueries = new LinkedList<QueryBuilder>();

        mustQueries.add(QueryBuilders.termQuery("header_item_for", "users"));
        mustQueries.add(QueryBuilders.termQuery("metric_name", "SuccessfulLogin"));



        SearchResponse searchResponse = null;
        String output = null;
        try {
            searchResponse = restClient.search(this.searchRequest, RequestOptions.DEFAULT);

            if (searchResponse != null) {
                System.out.println(" results found.");
                output = searchResponse.toString();
        } catch (ElasticsearchStatusException ex) {
        catch (IOException ex) {
            System.out.println(" Ex : " + ex.getMessage());
        return output;


The two methods defined here are meant to be used by the two rest endpoints, that I will be exposing.


It returns the ES version information as a JSON with two information fields, name and version.


It returns a single document that has the header_item_for as users and metric_name as  SuccessfulLogin, which are the fields in the document. The other limiting condition is that the document should have been generated within the time-window of the last 7 minutes (from now).

Step 4:  Controller

public class MetricController {

    private MetricService metricService;

    public MetricController(MetricService metricService) {
        this.metricService = metricService;

    public ServiceVersion defaultHandler() {
        return getVersionInformation();

    public String ElasticQuery() {
        return metricService.getMetric();

    public String getVersionInformation() {
        return metricService.clusterInfo();

The controller ties the endpoint to the service endpoints exposed. If I ran the application (and the index exists), I can see the results of my search query.

To summarize, I just walked through a sample program by which you can execute queries (using QueryBuilder and SearchRequest) and the Java High Level Client (v6.4) to deploy your simple rest services on Tomcat.

Further Reading

elastic, elastisearch, elk, java, spring data, springboot, tutorial

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}