Reindexar elasticsearch 2.3.3 cuando se usa Java NodeClient


Con la obsolescencia de SearchTye.SCAN y la nueva API Reindex, queremos migrar nuestro clúster y clientes de elasticsearch de 2.1.1 a 2.3.3.

Usamos java y las bibliotecas apropiadas para acceder a elasticsearch. Para acceder al clúster usamos TransportClient, para Unittests integrados usamos NodeClient.

Desafortunadamente, la API Reindex se proporciona como un complemento, que parece que NodeClient no puede manejar.

Entonces la pregunta es cómo usar elNodeClient con el complemento Reindex?

Ya intenté exponer el constructor NodeClient protegido para pasar la clase ReindexPlugin como argumento sin éxito.

Usar NodeClient para iniciar un ElasticSearch incrustado y usar TransportClient con ReindexPlugin agregado tampoco funcionó. Todo lo que obtengo aquí es una excepción: ActionNotFoundTransportException[Sin controlador para la acción [índices:datos/escribir/reindexar]]

Dependencias de interés:

  • org.elasticsearch:elasticsearch:2.3.3
  • org.elasticsearch.module:reindex:2.3.3
  • org.apache.lucene:lucene-expresiones:5.5.1
  • org.codehaus.groovy:groovy:2.4.6

Iniciando NodeClient:

Settings.Builder settings = Settings.settingsBuilder();
settings.put("path.data", "/some/path/data");
settings.put("path.home", "/some/path/home");
//settings.put("plugin.types", ReindexPlugin.class.getName()); > No effect
settings.put("http.port", 9299);
settings.put("transport.tcp.port", 9399);

node = NodeBuilder.nodeBuilder()
    .clusterName("testcluster")
    .settings(settings)
    .local(true)
    .node();

// also tested with local(false), then no transport port is available, resulting in NoNodeAvailableException

Uso de TransportClient para acceder al Nodo:

Settings settings = Settings.settingsBuilder()
    .put("cluster.name", "testcluster")
    .put("discovery.zen.ping.multicast.enabled", false)
    .build();
InetSocketTransportAddress[] addresses = new InetSocketTransportAddress[]
    {new InetSocketTransportAddress(new InetSocketAddress("localhost", 9399))};
client = TransportClient.builder()
    .settings(settings)
    .addPlugin(ReindexPlugin.class)
    .build()
    .addTransportAddresses(addresses);

Parte principal de la activación de la reindexación:

ReindexRequestBuilder builder = ReindexAction.INSTANCE.newRequestBuilder(getClient())
    .source(indexFrom)
    .destination(indexTo)
    .refresh(true);


------------Respuesta------------

Pude resolver esto combinando los dos enfoques descritos anteriormente.

Entonces, crear el NodeClient implica overriding el Nodo:

class ExposedNode extends Node {
    public ExposedNode(Environment tmpEnv, Version version, Collection<Class<? extends Plugin>> classpathPlugins) {
        super(tmpEnv, version, classpathPlugins);
    }
}

Y usarlo al iniciar NodeClient:

Settings.Builder settings = Settings.settingsBuilder();
settings.put("path.data", "/some/path/data");
settings.put("path.home", "/some/path/home");
settings.put("http.port", 9299);
settings.put("transport.tcp.port", 9399);

// Construct Node without NodeBuilder
List<Class<? extends Plugin>> classpathPlugins = ImmutableList.of(ReindexPlugin.class);
settings.put("node.local", false);
settings.put("cluster.name", "testcluster");
Settings preparedSettings = settings.build();
node = new ExposedNode(InternalSettingsPreparer.prepareEnvironment(preparedSettings, null), Version.CURRENT, classpathPlugins);
node.start();

Después de eso, puede usar TransportClient que agrega ReindexPlugin, como se describe en la pregunta.

Sin embargo, este es un truco sucio, que puede fallar en una versión futura, y muestra lo mal que Elasticsearch admite el desarrollo de complementos imo.

Etiquetas: reindex elasticsearch-plugin elasticsearch java

Artículos relacionados:

ruby - Cómo agregar un valor a un hash existente sin una clave

jquery: el video de YouTube no se muestra