8
8
9
9
package org .elasticsearch .action .bulk ;
10
10
11
- import org .elasticsearch .action .ActionRequestBuilder ;
11
+ import org .elasticsearch .action .ActionRequest ;
12
+ import org .elasticsearch .action .ActionRequestLazyBuilder ;
13
+ import org .elasticsearch .action .ActionResponse ;
14
+ import org .elasticsearch .action .DocWriteRequest ;
15
+ import org .elasticsearch .action .RequestBuilder ;
12
16
import org .elasticsearch .action .delete .DeleteRequest ;
13
17
import org .elasticsearch .action .delete .DeleteRequestBuilder ;
14
18
import org .elasticsearch .action .index .IndexRequest ;
15
19
import org .elasticsearch .action .index .IndexRequestBuilder ;
16
20
import org .elasticsearch .action .support .ActiveShardCount ;
21
+ import org .elasticsearch .action .support .WriteRequest ;
17
22
import org .elasticsearch .action .support .WriteRequestBuilder ;
18
23
import org .elasticsearch .action .support .replication .ReplicationRequest ;
19
24
import org .elasticsearch .action .update .UpdateRequest ;
23
28
import org .elasticsearch .core .TimeValue ;
24
29
import org .elasticsearch .xcontent .XContentType ;
25
30
31
+ import java .io .IOException ;
32
+ import java .util .ArrayList ;
33
+ import java .util .List ;
34
+
26
35
/**
27
36
* A bulk request holds an ordered {@link IndexRequest}s and {@link DeleteRequest}s and allows to executes
28
37
* it in a single batch.
29
38
*/
30
- public class BulkRequestBuilder extends ActionRequestBuilder <BulkRequest , BulkResponse > implements WriteRequestBuilder <BulkRequestBuilder > {
39
+ public class BulkRequestBuilder extends ActionRequestLazyBuilder <BulkRequest , BulkResponse >
40
+ implements
41
+ WriteRequestBuilder <BulkRequestBuilder > {
42
+ private final String globalIndex ;
43
+ /*
44
+ * The following 3 variables hold the list of requests that make up this bulk. Only one can be non-empty. That is, users can't add
45
+ * some IndexRequests and some IndexRequestBuilders. They need to pick one (preferably builders) and stick with it.
46
+ */
47
+ private final List <DocWriteRequest <?>> requests = new ArrayList <>();
48
+ private final List <FramedData > framedData = new ArrayList <>();
49
+ private final List <RequestBuilder <? extends ActionRequest , ? extends ActionResponse >> requestBuilders = new ArrayList <>();
50
+ private ActiveShardCount waitForActiveShards ;
51
+ private TimeValue timeout ;
52
+ private String timeoutString ;
53
+ private String globalPipeline ;
54
+ private String globalRouting ;
55
+ private WriteRequest .RefreshPolicy refreshPolicy ;
56
+ private String refreshPolicyString ;
31
57
32
58
public BulkRequestBuilder (ElasticsearchClient client , @ Nullable String globalIndex ) {
33
- super (client , BulkAction .INSTANCE , new BulkRequest (globalIndex ));
59
+ super (client , BulkAction .INSTANCE );
60
+ this .globalIndex = globalIndex ;
34
61
}
35
62
36
63
public BulkRequestBuilder (ElasticsearchClient client ) {
37
- super (client , BulkAction . INSTANCE , new BulkRequest () );
64
+ this (client , null );
38
65
}
39
66
40
67
/**
41
68
* Adds an {@link IndexRequest} to the list of actions to execute. Follows the same behavior of {@link IndexRequest}
42
69
* (for example, if no id is provided, one will be generated, or usage of the create flag).
70
+ * @deprecated use {@link #add(IndexRequestBuilder)} instead
43
71
*/
72
+ @ Deprecated
44
73
public BulkRequestBuilder add (IndexRequest request ) {
45
- super . request .add (request );
74
+ requests .add (request );
46
75
return this ;
47
76
}
48
77
@@ -51,47 +80,51 @@ public BulkRequestBuilder add(IndexRequest request) {
51
80
* (for example, if no id is provided, one will be generated, or usage of the create flag).
52
81
*/
53
82
public BulkRequestBuilder add (IndexRequestBuilder request ) {
54
- super . request . add (request . request () );
83
+ requestBuilders . add (request );
55
84
return this ;
56
85
}
57
86
58
87
/**
59
88
* Adds an {@link DeleteRequest} to the list of actions to execute.
89
+ * @deprecated use {@link #add(DeleteRequestBuilder)} instead
60
90
*/
91
+ @ Deprecated
61
92
public BulkRequestBuilder add (DeleteRequest request ) {
62
- super . request .add (request );
93
+ requests .add (request );
63
94
return this ;
64
95
}
65
96
66
97
/**
67
98
* Adds an {@link DeleteRequest} to the list of actions to execute.
68
99
*/
69
100
public BulkRequestBuilder add (DeleteRequestBuilder request ) {
70
- super . request . add (request . request () );
101
+ requestBuilders . add (request );
71
102
return this ;
72
103
}
73
104
74
105
/**
75
106
* Adds an {@link UpdateRequest} to the list of actions to execute.
107
+ * @deprecated use {@link #add(UpdateRequestBuilder)} instead
76
108
*/
109
+ @ Deprecated
77
110
public BulkRequestBuilder add (UpdateRequest request ) {
78
- super . request .add (request );
111
+ requests .add (request );
79
112
return this ;
80
113
}
81
114
82
115
/**
83
116
* Adds an {@link UpdateRequest} to the list of actions to execute.
84
117
*/
85
118
public BulkRequestBuilder add (UpdateRequestBuilder request ) {
86
- super . request . add (request . request () );
119
+ requestBuilders . add (request );
87
120
return this ;
88
121
}
89
122
90
123
/**
91
124
* Adds a framed data in binary format
92
125
*/
93
126
public BulkRequestBuilder add (byte [] data , int from , int length , XContentType xContentType ) throws Exception {
94
- request .add (data , from , length , null , xContentType );
127
+ framedData .add (new FramedData ( data , from , length , null , xContentType ) );
95
128
return this ;
96
129
}
97
130
@@ -100,7 +133,7 @@ public BulkRequestBuilder add(byte[] data, int from, int length, XContentType xC
100
133
*/
101
134
public BulkRequestBuilder add (byte [] data , int from , int length , @ Nullable String defaultIndex , XContentType xContentType )
102
135
throws Exception {
103
- request .add (data , from , length , defaultIndex , xContentType );
136
+ framedData .add (new FramedData ( data , from , length , defaultIndex , xContentType ) );
104
137
return this ;
105
138
}
106
139
@@ -109,7 +142,7 @@ public BulkRequestBuilder add(byte[] data, int from, int length, @Nullable Strin
109
142
* See {@link ReplicationRequest#waitForActiveShards(ActiveShardCount)} for details.
110
143
*/
111
144
public BulkRequestBuilder setWaitForActiveShards (ActiveShardCount waitForActiveShards ) {
112
- request .waitForActiveShards ( waitForActiveShards ) ;
145
+ this .waitForActiveShards = waitForActiveShards ;
113
146
return this ;
114
147
}
115
148
@@ -126,32 +159,112 @@ public BulkRequestBuilder setWaitForActiveShards(final int waitForActiveShards)
126
159
* A timeout to wait if the index operation can't be performed immediately. Defaults to {@code 1m}.
127
160
*/
128
161
public final BulkRequestBuilder setTimeout (TimeValue timeout ) {
129
- request .timeout ( timeout ) ;
162
+ this .timeout = timeout ;
130
163
return this ;
131
164
}
132
165
133
166
/**
134
167
* A timeout to wait if the index operation can't be performed immediately. Defaults to {@code 1m}.
135
168
*/
136
169
public final BulkRequestBuilder setTimeout (String timeout ) {
137
- request . timeout ( timeout ) ;
170
+ this . timeoutString = timeout ;
138
171
return this ;
139
172
}
140
173
141
174
/**
142
175
* The number of actions currently in the bulk.
143
176
*/
144
177
public int numberOfActions () {
145
- return request . numberOfActions ();
178
+ return requests . size () + requestBuilders . size () + framedData . size ();
146
179
}
147
180
148
181
public BulkRequestBuilder pipeline (String globalPipeline ) {
149
- request . pipeline ( globalPipeline ) ;
182
+ this . globalPipeline = globalPipeline ;
150
183
return this ;
151
184
}
152
185
153
186
public BulkRequestBuilder routing (String globalRouting ) {
154
- request .routing (globalRouting );
187
+ this .globalRouting = globalRouting ;
188
+ return this ;
189
+ }
190
+
191
+ @ Override
192
+ public BulkRequestBuilder setRefreshPolicy (WriteRequest .RefreshPolicy refreshPolicy ) {
193
+ this .refreshPolicy = refreshPolicy ;
194
+ return this ;
195
+ }
196
+
197
+ @ Override
198
+ public BulkRequestBuilder setRefreshPolicy (String refreshPolicy ) {
199
+ this .refreshPolicyString = refreshPolicy ;
155
200
return this ;
156
201
}
202
+
203
+ @ Override
204
+ public BulkRequest request () {
205
+ validate ();
206
+ BulkRequest request = new BulkRequest (globalIndex );
207
+ for (RequestBuilder <? extends ActionRequest , ? extends ActionResponse > requestBuilder : requestBuilders ) {
208
+ ActionRequest childRequest = requestBuilder .request ();
209
+ request .add ((DocWriteRequest <?>) childRequest );
210
+ }
211
+ for (DocWriteRequest <?> childRequest : requests ) {
212
+ request .add (childRequest );
213
+ }
214
+ for (FramedData framedData : framedData ) {
215
+ try {
216
+ request .add (framedData .data , framedData .from , framedData .length , framedData .defaultIndex , framedData .xContentType );
217
+ } catch (IOException e ) {
218
+ throw new RuntimeException (e );
219
+ }
220
+ }
221
+ if (waitForActiveShards != null ) {
222
+ request .waitForActiveShards (waitForActiveShards );
223
+ }
224
+ if (timeout != null ) {
225
+ request .timeout (timeout );
226
+ }
227
+ if (timeoutString != null ) {
228
+ request .timeout (timeoutString );
229
+ }
230
+ if (globalPipeline != null ) {
231
+ request .pipeline (globalPipeline );
232
+ }
233
+ if (globalRouting != null ) {
234
+ request .routing (globalRouting );
235
+ }
236
+ if (refreshPolicy != null ) {
237
+ request .setRefreshPolicy (refreshPolicy );
238
+ }
239
+ if (refreshPolicyString != null ) {
240
+ request .setRefreshPolicy (refreshPolicyString );
241
+ }
242
+ return request ;
243
+ }
244
+
245
+ private void validate () {
246
+ if (countNonEmptyLists (requestBuilders , requests , framedData ) > 1 ) {
247
+ throw new IllegalStateException (
248
+ "Must use only request builders, requests, or byte arrays within a single bulk request. Cannot mix and match"
249
+ );
250
+ }
251
+ if (timeout != null && timeoutString != null ) {
252
+ throw new IllegalStateException ("Must use only one setTimeout method" );
253
+ }
254
+ if (refreshPolicy != null && refreshPolicyString != null ) {
255
+ throw new IllegalStateException ("Must use only one setRefreshPolicy method" );
256
+ }
257
+ }
258
+
259
+ private int countNonEmptyLists (List <?>... lists ) {
260
+ int sum = 0 ;
261
+ for (List <?> list : lists ) {
262
+ if (list .isEmpty () == false ) {
263
+ sum ++;
264
+ }
265
+ }
266
+ return sum ;
267
+ }
268
+
269
+ private record FramedData (byte [] data , int from , int length , @ Nullable String defaultIndex , XContentType xContentType ) {}
157
270
}
0 commit comments