package io.searchbox.core; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import io.searchbox.client.JestResult; import io.searchbox.client.config.HttpClientConfig; import io.searchbox.client.http.JestHttpClient; import io.searchbox.common.AbstractIntegrationTest; import io.searchbox.params.Parameters; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.test.ESIntegTestCase; import org.json.JSONException; import org.junit.Test; import org.skyscreamer.jsonassert.JSONAssert; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.*; /** * @author Dogukan Sonmez */ @ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 1) public class BulkIntegrationTest extends AbstractIntegrationTest { @Test public void bulkOperationWithCustomGson() throws Exception { String index = "twitter"; String type = "tweet"; String id = "1"; Calendar calendar = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT")); calendar.set(2013, 0, 1, 0, 0, 0); // 2013-01-01 00:00:00 GMT Date date = calendar.getTime(); String dateStyle = "yyyy-**-MM"; HttpClientConfig httpClientConfig = new HttpClientConfig. Builder("http://localhost:" + getPort()) .multiThreaded(true) .gson(new GsonBuilder().setDateFormat(dateStyle).create()) .build(); factory.setHttpClientConfig(httpClientConfig); JestHttpClient client = (JestHttpClient) factory.getObject(); Map<String, Object> source = new HashMap<String, Object>(); source.put("user", date); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index).type(type).id(id).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(1, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); GetResponse getResponse = client().get(new GetRequest("twitter", "tweet", "1")).actionGet(5000); assertNotNull(getResponse); // use date formatter to avoid timezone issues when testing SimpleDateFormat df = new SimpleDateFormat(dateStyle, Locale.UK); assertEquals(df.format(date), getResponse.getSourceAsMap().get("user")); } @Test public void bulkOperationWithIndex() throws IOException { String index = "twitter"; String type = "tweet"; String id = "1"; Map<String, String> source = new HashMap<String, String>(); source.put("user", "kimchy"); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index).type(type).id(id).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(1, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); } @Test public void bulkOperationWithDefaultIndexAndDefaultType() throws IOException { String index = "twitter"; String type = "tweet"; String id = "1"; Map<String, String> source1 = new HashMap<String, String>(); source1.put("user name", "kimchy olga john doe"); Bulk bulk = new Bulk.Builder() .defaultIndex(index) .defaultType(type) .addAction(new Index.Builder(source1).id(id).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(1, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); GetResponse getResponse = client().get(new GetRequest("twitter", "tweet", "1")).actionGet(); assertNotNull(getResponse); assertEquals(new Gson().toJson(source1), getResponse.getSourceAsString()); } @Test public void bulkOperationWithIndexWithSourceIncludingWhitespace() throws IOException, JSONException { String index = "twitter"; String type = "tweet"; Map<String, String> source1 = new HashMap<String, String>(); source1.put("user name", "kimchy olga john doe"); String source2 = "{\"k e y\" : \" val v a l \" }"; Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source1).index(index).type(type).id("1").build()) .addAction(new Index.Builder(source2).index(index).type(type).id("2").build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(2, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals("1", firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); BulkResult.BulkResultItem secondItem = items.get(1); assertEquals("index", secondItem.operation); assertEquals(index, secondItem.index); assertEquals(type, secondItem.type); assertEquals("2", secondItem.id); assertEquals(201, secondItem.status); assertNull(secondItem.error); GetResponse getResponse = client().get(new GetRequest("twitter", "tweet", "1")).actionGet(); assertNotNull(getResponse); assertEquals(new Gson().toJson(source1), getResponse.getSourceAsString()); getResponse = client().get(new GetRequest("twitter", "tweet", "2")).actionGet(); assertNotNull(getResponse); JSONAssert.assertEquals(source2, getResponse.getSourceAsString(), false); } @Test public void bulkOperationWithIndexWithSourceIncludingLineBreak() throws IOException { String index = "twitter"; String type = "tweet"; Map<String, String> source1 = new HashMap<String, String>(); source1.put("user name", "kimchy\nolga\njohn doe"); String source2 = "{\"k e y\" : \" val\nv a\r\nl \" }"; Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source1).index(index).type(type).id("1").build()) .addAction(new Index.Builder(source2).index(index).type(type).id("2").build()) .build(); BulkResult result = client.execute(bulk); assertFalse(result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(0, items.size()); assertEquals(0, result.getFailedItems().size()); } @Test public void bulkOperationWithIndexWithParam() throws IOException { String index = "twitter"; String type = "tweet"; Map<String, String> source = new HashMap<String, String>(); source.put("user", "kimchy"); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source) .index(index) .type(type) .id("1") .setParameter(Parameters.VERSION, 6) .build()) .build(); JestResult result = client.execute(bulk); assertFalse(result.getErrorMessage(), result.isSucceeded()); } @Test public void bulkOperationWithIndexAndUpdate() throws IOException { String index = "twitter"; String type = "tweet"; String id = "1"; String script = "{ \"script\" : { \"inline\": \"ctx._source.user += params.tag\", \"params\" : {\"tag\" : \"_rob\"}}}"; Map<String, String> source = new HashMap<>(); source.put("user", "kimchy"); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index).type(type).id(id).build()) .addAction(new Update.Builder(script).index(index).type(type).id(id).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(2, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); BulkResult.BulkResultItem secondItem = items.get(1); assertEquals("update", secondItem.operation); assertEquals(index, secondItem.index); assertEquals(type, secondItem.type); assertEquals(id, secondItem.id); assertEquals(200, secondItem.status); assertNull(secondItem.error); GetResponse getResponse = client().get(new GetRequest("twitter", "tweet", "1")).actionGet(); assertNotNull(getResponse); assertEquals("{\"user\":\"kimchy_rob\"}", getResponse.getSourceAsString()); } @Test public void bulkOperationWithIndexJsonSource() throws IOException { String index = "twitter"; String type = "tweet"; String id = "1"; String source = "{\"user\":\"super\"}"; Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index).type(type).id(id).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(1, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); } @Test public void bulkOperationWithSingleDelete() throws IOException { String index = "twitter"; String type = "tweet"; String id = "1"; Bulk bulk = new Bulk.Builder() .addAction(new Delete.Builder(id).index(index).type(type).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(1, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("delete", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(404, firstItem.status); assertNull(firstItem.error); } @Test public void bulkOperationWithMultipleIndex() throws IOException { String index1 = "twitter"; String type1 = "tweet"; String id1 = "1"; String index2 = "elasticsearch"; String type2 = "jest"; String id2 = "2"; Map<String, String> source = new HashMap<String, String>(); source.put("user", "kimcy"); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index1).type(type1).id(id1).build()) .addAction(new Index.Builder(source).index(index2).type(type2).id(id2).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(2, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index1, firstItem.index); assertEquals(type1, firstItem.type); assertEquals(id1, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); BulkResult.BulkResultItem secondItem = items.get(1); assertEquals("index", secondItem.operation); assertEquals(index2, secondItem.index); assertEquals(type2, secondItem.type); assertEquals(id2, secondItem.id); assertEquals(201, secondItem.status); assertNull(secondItem.error); } @Test public void bulkOperationWithIndexCreateOpType() throws IOException { String index = "twitter"; String type = "tweet"; String id = "1"; Map<String, String> source = new HashMap<String, String>(); source.put("user", "kimcy"); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index).type(type).id(id).build()) .addAction(new Index.Builder(source) .index(index).type(type).id(id).setParameter(Parameters.OP_TYPE, "create").build()) .build(); BulkResult result = client.execute(bulk); assertFalse(result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); List<BulkResult.BulkResultItem> failedItems = result.getFailedItems(); assertEquals(2, items.size()); assertEquals(1, failedItems.size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("index", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals(id, firstItem.id); assertEquals(201, firstItem.status); assertNull(firstItem.error); BulkResult.BulkResultItem secondItem = items.get(1); assertEquals("create", secondItem.operation); assertEquals(index, secondItem.index); assertEquals(type, secondItem.type); assertEquals(id, secondItem.id); assertEquals(409, secondItem.status); assertNotNull(secondItem.error); assertEquals(secondItem, failedItems.get(0)); // second index request with create op type should fail because it's a duplicate of the first index request assertNotNull( result.getJsonObject().getAsJsonArray("items").get(1).getAsJsonObject().getAsJsonObject("create").get("error").getAsJsonObject().get("reason").getAsString() ); } @Test public void bulkOperationWithMultipleDelete() throws IOException { String index = "twitter"; String type = "tweet"; Bulk bulk = new Bulk.Builder() .addAction(new Delete.Builder("1").index(index).type(type).build()) .addAction(new Delete.Builder("2").index(index).type(type).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); assertEquals(2, items.size()); assertEquals(0, result.getFailedItems().size()); BulkResult.BulkResultItem firstItem = items.get(0); assertEquals("delete", firstItem.operation); assertEquals(index, firstItem.index); assertEquals(type, firstItem.type); assertEquals("1", firstItem.id); assertEquals(404, firstItem.status); assertNull(firstItem.error); BulkResult.BulkResultItem secondItem = items.get(1); assertEquals("delete", secondItem.operation); assertEquals(index, secondItem.index); assertEquals(type, secondItem.type); assertEquals("2", secondItem.id); assertEquals(404, secondItem.status); assertNull(secondItem.error); } @Test public void bulkOperationWithMultipleIndexAndDelete() throws IOException { String index = "twitter"; String type = "tweet"; Map<String, String> source = new HashMap<String, String>(); source.put("field", "value"); Bulk bulk = new Bulk.Builder() .addAction(new Index.Builder(source).index(index).type(type).id("1").build()) .addAction(new Index.Builder(source).index("elasticsearch").type("jest").id("2").build()) .addAction(new Delete.Builder("1").index(index).type(type).build()) .addAction(new Delete.Builder("2").index(index).type(type).build()) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); List<BulkResult.BulkResultItem> failedItems = result.getFailedItems(); assertEquals(4, items.size()); assertEquals(0, failedItems.size()); } @Test public void bulkOperationWithSourceList() throws IOException { TestArticleModel model1 = new TestArticleModel("tweet1"); TestArticleModel model2 = new TestArticleModel("2", "tweet2"); List<Index> modelList = Arrays.asList( new Index.Builder(model1).build(), new Index.Builder(model2).build() ); Bulk bulk = new Bulk.Builder() .defaultIndex("twitter") .defaultType("tweet") .addAction(modelList) .build(); BulkResult result = client.execute(bulk); assertTrue(result.getErrorMessage(), result.isSucceeded()); List<BulkResult.BulkResultItem> items = result.getItems(); List<BulkResult.BulkResultItem> failedItems = result.getFailedItems(); assertEquals(2, items.size()); assertEquals(0, failedItems.size()); } }