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;

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD})
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;

import lombok.extern.java.Log;

@ApplicationScoped
@Startup
@Log
public class ClientProducer {

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

    @PostConstruct
    public void postConstruct() {
        final Settings settings = ImmutableSettings.settingsBuilder()
                .put("http.enabled", false)
                .put("client.transport.sniff", true)
                .put("cluster.name", clusterName)
                .put("discovery.zen.ping.unicast.hosts", hosts)
                .build();

        final Node node = NodeBuilder.nodeBuilder()
                .settings(settings)
                .client(true)
                .node()
                .start();

        client = node.client();
    }

    @Produces
    @ElasticSearchClient
    public Client getClient() {
        return client;
    }

    @PreDestroy
    public void preDestroy() {
        client.close();
    }
}

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

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