1515import org .elasticsearch .index .shard .ShardId ;
1616import org .elasticsearch .test .ESTestCase ;
1717import org .elasticsearch .xcontent .XContentType ;
18- import org .hamcrest .Matchers ;
1918
2019import java .util .ArrayList ;
2120import java .util .Arrays ;
21+ import java .util .Collections ;
2222import java .util .HashSet ;
2323import java .util .List ;
2424import java .util .Set ;
2525
2626import static org .hamcrest .Matchers .equalTo ;
2727import static org .hamcrest .Matchers .instanceOf ;
2828import static org .hamcrest .Matchers .is ;
29- import static org .hamcrest .Matchers .nullValue ;
29+ import static org .hamcrest .Matchers .sameInstance ;
3030
3131public class BulkRequestModifierTests extends ESTestCase {
3232
@@ -36,38 +36,53 @@ public void testBulkRequestModifier() {
3636 for (int i = 0 ; i < numRequests ; i ++) {
3737 bulkRequest .add (new IndexRequest ("_index" , "_type" , String .valueOf (i )).source ("{}" , XContentType .JSON ));
3838 }
39- CaptureActionListener actionListener = new CaptureActionListener ();
40- TransportBulkAction .BulkRequestModifier bulkRequestModifier = new TransportBulkAction .BulkRequestModifier (bulkRequest );
4139
42- int i = 0 ;
40+ // wrap the bulk request and fail some of the item requests at random
41+ TransportBulkAction .BulkRequestModifier modifier = new TransportBulkAction .BulkRequestModifier (bulkRequest );
4342 Set <Integer > failedSlots = new HashSet <>();
44- while ( bulkRequestModifier .hasNext ()) {
45- bulkRequestModifier .next ();
43+ for ( int i = 0 ; modifier .hasNext (); i ++ ) {
44+ modifier .next ();
4645 if (randomBoolean ()) {
47- bulkRequestModifier .markItemAsFailed (i , new RuntimeException ());
46+ modifier .markItemAsFailed (i , new RuntimeException ());
4847 failedSlots .add (i );
4948 }
50- i ++;
49+ }
50+ assertThat (modifier .getBulkRequest ().requests ().size (), equalTo (numRequests - failedSlots .size ()));
51+
52+ // populate the non-failed responses
53+ BulkRequest subsequentBulkRequest = modifier .getBulkRequest ();
54+ assertThat (subsequentBulkRequest .requests ().size (), equalTo (numRequests - failedSlots .size ()));
55+ List <BulkItemResponse > responses = new ArrayList <>();
56+ for (int j = 0 ; j < subsequentBulkRequest .requests ().size (); j ++) {
57+ IndexRequest indexRequest = (IndexRequest ) subsequentBulkRequest .requests ().get (j );
58+ IndexResponse indexResponse = new IndexResponse (new ShardId ("_index" , "_na_" , 0 ), "_type" , indexRequest .id (), 1 , 17 , 1 , true );
59+ responses .add (BulkItemResponse .success (j , indexRequest .opType (), indexResponse ));
5160 }
5261
53- assertThat (bulkRequestModifier .getBulkRequest ().requests ().size (), equalTo (numRequests - failedSlots .size ()));
54- // simulate that we actually executed the modified bulk request:
62+ // simulate that we actually executed the modified bulk request
5563 long ingestTook = randomLong ();
56- ActionListener <BulkResponse > result = bulkRequestModifier .wrapActionListenerIfNeeded (ingestTook , actionListener );
57- result .onResponse (new BulkResponse (new BulkItemResponse [numRequests - failedSlots .size ()], 0 ));
64+ CaptureActionListener actionListener = new CaptureActionListener ();
65+ ActionListener <BulkResponse > result = modifier .wrapActionListenerIfNeeded (ingestTook , actionListener );
66+ result .onResponse (new BulkResponse (responses .toArray (new BulkItemResponse [0 ]), 0 ));
5867
68+ // check the results for successes and failures
5969 BulkResponse bulkResponse = actionListener .getResponse ();
6070 assertThat (bulkResponse .getIngestTookInMillis (), equalTo (ingestTook ));
61- for (int j = 0 ; j < bulkResponse .getItems ().length ; j ++) {
62- if ( failedSlots . contains ( j )) {
63- BulkItemResponse item = bulkResponse . getItems ()[ j ];
71+ for (int i = 0 ; i < bulkResponse .getItems ().length ; i ++) {
72+ BulkItemResponse item = bulkResponse . getItems ()[ i ];
73+ if ( failedSlots . contains ( i )) {
6474 assertThat (item .isFailed (), is (true ));
65- assertThat (item .getFailure ().getIndex (), equalTo ("_index" ));
66- assertThat (item .getFailure ().getType (), equalTo ("_type" ));
67- assertThat (item .getFailure ().getId (), equalTo (String .valueOf (j )));
68- assertThat (item .getFailure ().getMessage (), equalTo ("java.lang.RuntimeException" ));
75+ BulkItemResponse .Failure failure = item .getFailure ();
76+ assertThat (failure .getIndex (), equalTo ("_index" ));
77+ assertThat (failure .getType (), equalTo ("_type" ));
78+ assertThat (failure .getId (), equalTo (String .valueOf (i )));
79+ assertThat (failure .getMessage (), equalTo ("java.lang.RuntimeException" ));
6980 } else {
70- assertThat (bulkResponse .getItems ()[j ], nullValue ());
81+ assertThat (item .isFailed (), is (false ));
82+ IndexResponse success = item .getResponse ();
83+ assertThat (success .getIndex (), equalTo ("_index" ));
84+ assertThat (success .getType (), equalTo ("_type" ));
85+ assertThat (success .getId (), equalTo (String .valueOf (i )));
7186 }
7287 }
7388 }
@@ -79,16 +94,29 @@ public void testPipelineFailures() {
7994 }
8095
8196 TransportBulkAction .BulkRequestModifier modifier = new TransportBulkAction .BulkRequestModifier (originalBulkRequest );
97+
98+ final List <Integer > failures = new ArrayList <>();
99+ // iterate the requests in order, recording that half of them should be failures
82100 for (int i = 0 ; modifier .hasNext (); i ++) {
83101 modifier .next ();
84102 if (i % 2 == 0 ) {
85- modifier . markItemAsFailed ( i , new RuntimeException () );
103+ failures . add ( i );
86104 }
87105 }
88106
107+ // with async processors, the failures can come back 'out of order' so sometimes we'll shuffle the list
108+ if (randomBoolean ()) {
109+ Collections .shuffle (failures , random ());
110+ }
111+
112+ // actually mark the failures
113+ for (int i : failures ) {
114+ modifier .markItemAsFailed (i , new RuntimeException ());
115+ }
116+
89117 // So half of the requests have "failed", so only the successful requests are left:
90118 BulkRequest bulkRequest = modifier .getBulkRequest ();
91- assertThat (bulkRequest .requests ().size (), Matchers . equalTo (16 ));
119+ assertThat (bulkRequest .requests ().size (), equalTo (16 ));
92120
93121 List <BulkItemResponse > responses = new ArrayList <>();
94122 ActionListener <BulkResponse > bulkResponseListener = modifier .wrapActionListenerIfNeeded (1L , new ActionListener <BulkResponse >() {
@@ -115,11 +143,11 @@ public void onFailure(Exception e) {}
115143 );
116144 originalResponses .add (BulkItemResponse .success (Integer .parseInt (indexRequest .id ()), indexRequest .opType (), indexResponse ));
117145 }
118- bulkResponseListener .onResponse (new BulkResponse (originalResponses .toArray (new BulkItemResponse [originalResponses . size () ]), 0 ));
146+ bulkResponseListener .onResponse (new BulkResponse (originalResponses .toArray (new BulkItemResponse [0 ]), 0 ));
119147
120- assertThat (responses .size (), Matchers . equalTo (32 ));
148+ assertThat (responses .size (), equalTo (32 ));
121149 for (int i = 0 ; i < 32 ; i ++) {
122- assertThat (responses .get (i ).getId (), Matchers . equalTo (String .valueOf (i )));
150+ assertThat (responses .get (i ).getId (), equalTo (String .valueOf (i )));
123151 }
124152 }
125153
@@ -135,7 +163,7 @@ public void testNoFailures() {
135163 }
136164
137165 BulkRequest bulkRequest = modifier .getBulkRequest ();
138- assertThat (bulkRequest , Matchers . sameInstance (originalBulkRequest ));
166+ assertThat (bulkRequest , sameInstance (originalBulkRequest ));
139167 ActionListener <BulkResponse > actionListener = ActionListener .wrap (() -> {});
140168 assertThat (modifier .wrapActionListenerIfNeeded (1L , actionListener ), instanceOf (ActionListener .MappedActionListener .class ));
141169 }
0 commit comments