2015-07-14 5 views
12

Vorrei scrivere qualche integrazione con ElasticSearch. Per i test mi piacerebbe eseguire ES in memoria.ElasticSearch in memoria per i test

Ho trovato alcune informazioni nella documentazione, ma senza esempi su come scrivere questo tipo di test. Elasticsearch Reference [1.6] » Testing » Java Testing Framework » integration tests « unit tests

Inoltre ho trovato l'articolo seguente, ma è senza dati. Easy JUnit testing with Elastic Search

Sto cercando di esempio come avviare ed eseguire ES in-memory e accedervi tramite l'API REST.

+1

Comincerei a guardare le classi di test di Elasticsearch. Ad esempio, [questo] (https://github.com/elastic/elasticsearch/blob/v1.6.0/src/test/java/org/elasticsearch/test/ElasticsearchSingleNodeTest.java) in cui il tipo di archivio dell'indice può essere [ impostato su 'ram'] (https://github.com/elastic/elasticsearch/blob/v1.6.0/src/test/java/org/elasticsearch/test/ElasticsearchSingleNodeTest.java#L139). –

risposta

5

Sulla base the second link hai fornito, ho creato questo abstract classe di test:

@RunWith(SpringJUnit4ClassRunner.class) 
public abstract class AbstractElasticsearchTest { 

    private static final String HTTP_PORT = "9205"; 
    private static final String HTTP_TRANSPORT_PORT = "9305"; 
    private static final String ES_WORKING_DIR = "target/es"; 

    private static Node node; 

    @BeforeClass 
    public static void startElasticsearch() throws Exception {  
     removeOldDataDir(ES_WORKING_DIR + "/" + clusterName); 

     Settings settings = Settings.builder() 
       .put("path.home", ES_WORKING_DIR) 
       .put("path.conf", ES_WORKING_DIR) 
       .put("path.data", ES_WORKING_DIR) 
       .put("path.work", ES_WORKING_DIR) 
       .put("path.logs", ES_WORKING_DIR) 
       .put("http.port", HTTP_PORT) 
       .put("transport.tcp.port", HTTP_TRANSPORT_PORT) 
       .put("index.number_of_shards", "1") 
       .put("index.number_of_replicas", "0") 
       .put("discovery.zen.ping.multicast.enabled", "false") 
       .build(); 
     node = nodeBuilder().settings(settings).clusterName("monkeys.elasticsearch").client(false).node(); 
     node.start(); 
    } 

    @AfterClass 
    public static void stopElasticsearch() { 
     node.close(); 
    } 

    private static void removeOldDataDir(String datadir) throws Exception { 
     File dataDir = new File(datadir); 
     if (dataDir.exists()) { 
      FileSystemUtils.deleteRecursively(dataDir); 
     } 
    }  
} 

Nel codice di produzione, ho configurato un client elasticsearch come segue. Il test di integrazione estende la classe astratta sopra definita e configura la proprietà elasticsearch.port come 9305 e elasticsearch.host come localhost.

@Configuration 
public class ElasticsearchConfiguration {  
    @Bean(destroyMethod = "close") 
    public Client elasticsearchClient(@Value("${elasticsearch.clusterName}") String clusterName, 
             @Value("${elasticsearch.host}") String elasticsearchClusterHost, 
             @Value("${elasticsearch.port}") Integer elasticsearchClusterPort) throws UnknownHostException { 
     Settings settings = Settings.settingsBuilder().put("cluster.name", clusterName).build(); 
     InetSocketTransportAddress transportAddress = new InetSocketTransportAddress(InetAddress.getByName(elasticsearchClusterHost), elasticsearchClusterPort); 
     return TransportClient.builder().settings(settings).build().addTransportAddress(transportAddress); 
    } 
} 

Questo è tutto. Il test di integrazione eseguirà il codice di produzione configurato per connettersi al nodo avviato nello AbstractElasticsearchTest.startElasticsearch().

Nel caso in cui si desideri utilizzare l'API REST elasticsearch, utilizzare la porta 9205. Ad es. con Apache HttpComponents:

HttpClient httpClient = HttpClients.createDefault(); 
HttpPut httpPut = new HttpPut("http://localhost:9205/_template/" + templateName); 
httpPut.setEntity(new FileEntity(new File("template.json"))); 
httpClient.execute(httpPut); 
2

Qui è la mia realizzazione

import java.io.File; 
import java.io.IOException; 
import java.nio.file.Files; 
import java.util.UUID; 
import org.elasticsearch.client.Client; 
import org.elasticsearch.common.settings.ImmutableSettings; 
import org.elasticsearch.node.Node; 
import org.elasticsearch.node.NodeBuilder; 

/** 
* 
* @author Raghu Nair 
*/ 
public final class ElasticSearchInMemory { 

    private static Client client = null; 
    private static File tempDir = null; 
    private static Node elasticSearchNode = null; 

    public static Client getClient() { 
     return client; 
    } 

    public static void setUp() throws Exception { 
     tempDir = File.createTempFile("elasticsearch-temp", Long.toString(System.nanoTime())); 
     tempDir.delete(); 
     tempDir.mkdir(); 
     System.out.println("writing to: " + tempDir); 

     String clusterName = UUID.randomUUID().toString(); 
     elasticSearchNode = NodeBuilder 
       .nodeBuilder() 
       .local(false) 
       .clusterName(clusterName) 
       .settings(
         ImmutableSettings.settingsBuilder() 
         .put("script.disable_dynamic", "false") 
         .put("gateway.type", "local") 
         .put("index.number_of_shards", "1") 
         .put("index.number_of_replicas", "0") 
         .put("path.data", new File(tempDir, "data").getAbsolutePath()) 
         .put("path.logs", new File(tempDir, "logs").getAbsolutePath()) 
         .put("path.work", new File(tempDir, "work").getAbsolutePath()) 
       ).node(); 
     elasticSearchNode.start(); 
     client = elasticSearchNode.client(); 
    } 

    public static void tearDown() throws Exception { 
     if (client != null) { 
      client.close(); 
     } 
     if (elasticSearchNode != null) { 
      elasticSearchNode.stop(); 
      elasticSearchNode.close(); 
     } 
     if (tempDir != null) { 
      removeDirectory(tempDir); 
     } 
    } 

    public static void removeDirectory(File dir) throws IOException { 
     if (dir.isDirectory()) { 
      File[] files = dir.listFiles(); 
      if (files != null && files.length > 0) { 
       for (File aFile : files) { 
        removeDirectory(aFile); 
       } 
      } 
     } 
     Files.delete(dir.toPath());   
    } 
} 
+3

Questo non funziona più su ES 5.X Hanno rimosso NodeBuilder –

+0

Immagino che possiamo ancora risolvere il problema usando Node (impostazioni) .start(); – JVXR

0

È possibile avviare ES sul computer locale utilizzando:

Settings settings = Settings.settingsBuilder() 
     .put("path.home", ".") 
     .build(); 
NodeBuilder.nodeBuilder().settings(settings).node(); 

Quando ES iniziata, riempire libero di accedere a sopra REST usando curl o altri strumenti:

curl http://localhost:9200/_cat/health?v