15
15
import org .elasticsearch .index .shard .ShardId ;
16
16
import org .elasticsearch .test .ESTestCase ;
17
17
import org .elasticsearch .xcontent .XContentType ;
18
- import org .hamcrest .Matchers ;
19
18
20
19
import java .util .ArrayList ;
21
20
import java .util .Arrays ;
21
+ import java .util .Collections ;
22
22
import java .util .HashSet ;
23
23
import java .util .List ;
24
24
import java .util .Set ;
25
25
26
26
import static org .hamcrest .Matchers .equalTo ;
27
27
import static org .hamcrest .Matchers .instanceOf ;
28
28
import static org .hamcrest .Matchers .is ;
29
- import static org .hamcrest .Matchers .nullValue ;
29
+ import static org .hamcrest .Matchers .sameInstance ;
30
30
31
31
public class BulkRequestModifierTests extends ESTestCase {
32
32
@@ -36,38 +36,53 @@ public void testBulkRequestModifier() {
36
36
for (int i = 0 ; i < numRequests ; i ++) {
37
37
bulkRequest .add (new IndexRequest ("_index" , "_type" , String .valueOf (i )).source ("{}" , XContentType .JSON ));
38
38
}
39
- CaptureActionListener actionListener = new CaptureActionListener ();
40
- TransportBulkAction .BulkRequestModifier bulkRequestModifier = new TransportBulkAction .BulkRequestModifier (bulkRequest );
41
39
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 );
43
42
Set <Integer > failedSlots = new HashSet <>();
44
- while ( bulkRequestModifier .hasNext ()) {
45
- bulkRequestModifier .next ();
43
+ for ( int i = 0 ; modifier .hasNext (); i ++ ) {
44
+ modifier .next ();
46
45
if (randomBoolean ()) {
47
- bulkRequestModifier .markItemAsFailed (i , new RuntimeException ());
46
+ modifier .markItemAsFailed (i , new RuntimeException ());
48
47
failedSlots .add (i );
49
48
}
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 ));
51
60
}
52
61
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
55
63
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 ));
58
67
68
+ // check the results for successes and failures
59
69
BulkResponse bulkResponse = actionListener .getResponse ();
60
70
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 )) {
64
74
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" ));
69
80
} 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 )));
71
86
}
72
87
}
73
88
}
@@ -79,16 +94,29 @@ public void testPipelineFailures() {
79
94
}
80
95
81
96
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
82
100
for (int i = 0 ; modifier .hasNext (); i ++) {
83
101
modifier .next ();
84
102
if (i % 2 == 0 ) {
85
- modifier . markItemAsFailed ( i , new RuntimeException () );
103
+ failures . add ( i );
86
104
}
87
105
}
88
106
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
+
89
117
// So half of the requests have "failed", so only the successful requests are left:
90
118
BulkRequest bulkRequest = modifier .getBulkRequest ();
91
- assertThat (bulkRequest .requests ().size (), Matchers . equalTo (16 ));
119
+ assertThat (bulkRequest .requests ().size (), equalTo (16 ));
92
120
93
121
List <BulkItemResponse > responses = new ArrayList <>();
94
122
ActionListener <BulkResponse > bulkResponseListener = modifier .wrapActionListenerIfNeeded (1L , new ActionListener <BulkResponse >() {
@@ -115,11 +143,11 @@ public void onFailure(Exception e) {}
115
143
);
116
144
originalResponses .add (BulkItemResponse .success (Integer .parseInt (indexRequest .id ()), indexRequest .opType (), indexResponse ));
117
145
}
118
- bulkResponseListener .onResponse (new BulkResponse (originalResponses .toArray (new BulkItemResponse [originalResponses . size () ]), 0 ));
146
+ bulkResponseListener .onResponse (new BulkResponse (originalResponses .toArray (new BulkItemResponse [0 ]), 0 ));
119
147
120
- assertThat (responses .size (), Matchers . equalTo (32 ));
148
+ assertThat (responses .size (), equalTo (32 ));
121
149
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 )));
123
151
}
124
152
}
125
153
@@ -135,7 +163,7 @@ public void testNoFailures() {
135
163
}
136
164
137
165
BulkRequest bulkRequest = modifier .getBulkRequest ();
138
- assertThat (bulkRequest , Matchers . sameInstance (originalBulkRequest ));
166
+ assertThat (bulkRequest , sameInstance (originalBulkRequest ));
139
167
ActionListener <BulkResponse > actionListener = ActionListener .wrap (() -> {});
140
168
assertThat (modifier .wrapActionListenerIfNeeded (1L , actionListener ), instanceOf (ActionListener .MappedActionListener .class ));
141
169
}
0 commit comments