Creating a CDI Producer for an ElasticSearch Node Client

I recently began diving into ElasticSearch and trying to learn the Java API. While the documentation is actually good, it also doesn't provide a clear big picture.

After a few hours on trial and error, I was finally able to come up with a CDI producer which is @ApplicationScored. From my googling, it does seem that the ElasticSearch clients are thread-safe.

Below is my producer class.

CDI qualifier annotation

package com.brandonlamb.elasticsearch;

import java.lang.annotation.Retention;  
import java.lang.annotation.Target;

import javax.inject.Qualifier;

import static java.lang.annotation.ElementType.FIELD;  
import static java.lang.annotation.ElementType.METHOD;  
import static java.lang.annotation.ElementType.TYPE;  
import static java.lang.annotation.RetentionPolicy.RUNTIME;

public @interface ElasticSearchClient {  

CDI producer class

package com.brandonlamb.elasticsearch;

import org.elasticsearch.client.Client;  
import org.elasticsearch.common.settings.ImmutableSettings;  
import org.elasticsearch.common.settings.Settings;  
import org.elasticsearch.node.Node;  
import org.elasticsearch.node.NodeBuilder;

import javax.annotation.PostConstruct;  
import javax.annotation.PreDestroy;  
import javax.ejb.Startup;  
import javax.enterprise.context.ApplicationScoped;  
import javax.enterprise.inject.Produces;  
import javax.inject.Inject;


public class ClientProducer {

    private Client client;
    private final String hosts = "host1:9300, host2:9300";
    private final String clusterName = "my-cluster;

    public void postConstruct() {
        final Settings settings = ImmutableSettings.settingsBuilder()
                .put("http.enabled", false)
                .put("client.transport.sniff", true)
                .put("", clusterName)
                .put("", hosts)

        final Node node = NodeBuilder.nodeBuilder()

        client = node.client();

    public Client getClient() {
        return client;

    public void preDestroy() {

Now to use this, I simply inject into a DAL/Repository object.

@ElasticSearchClient // provided by me/you, not some built-in
private Client client;