Q:

How to properly initialize Elasticsearch for queries?

I wrote a program that inserts an element, then it searches all elements in the store. Thus, it finds one more element every time the program runs. I’d expect to be able to comment out the insert and still run the program, just finding the stuff that was already inserted. Whenever I do though, I get an exception “Failed to execute phase [query_fetch], all shards failed”. Any ideas?
Hypothesis: inserting the element does some sort of implicit initialization on my node. However, I’m looking through the ES source, and I can’t figure out what that would be.
try (Node node = NodeBuilder.nodeBuilder().clusterName("tesssst").build().start()) {
    try (Client client = node.client()) {

        //insert an entry; if this part is removed, the program crashes
        client.prepareIndex("movies", "movie", UUID.randomUUID().toString()).setSource(
            "{\"title\": \"Lawrence of Arabia\",\"director\": \"David Lean\",\"year\": 1962,\"genres\":"
            + " [\"Adventure\", \"Biography\", \"Drama\"]}").execute().actionGet();

        //search all entries
        System.out.println("***************");
        SearchResponse response = client.prepareSearch("movies")
            .setTypes("movie")
            .setSearchType(SearchType.QUERY_AND_FETCH)
            .setFrom(0).setSize(60).setExplain(true)
            .execute()
            .actionGet();
        SearchHit[] results = response.getHits().getHits();
        System.out.println("Current results: " + results.length);
        for (SearchHit hit : results) {
            System.out.println("------------------------------");
            Map<String, Object> result = hit.getSource();
            System.out.println(result);
        }
        System.out.println("***************");

        client.close();
    }
    node.close();
}

A:

The problem was that Elasticsearch didn't have enough time to startup, but the initial insert gave it enough time. Simply adding an appropriate wait fixes it:
final ClusterHealthRequest clusterHealthRequest = new ClusterHealthRequest("movies")
        .timeout(TimeValue.timeValueSeconds(60)).waitForGreenStatus();
final ClusterHealthResponse clusterHealth = client.admin().cluster()
        .health(clusterHealthRequest).actionGet();
if (clusterHealth.isTimedOut()) {
    System.out.println("ElasticSearch cluster health timed out");
} else {
    System.out.println("ElasticSearch cluster health: Status "
           + clusterHealth.getStatus().name() + "; " + clusterHealth.getNumberOfNodes()
           + " nodes; " + clusterHealth.getActiveShards() + " active shards.");
}

(if your standards are lower, you can save time with waitForYellowStatus)

