@@ -217,7 +217,6 @@ private void createContinuousTransform(String indexName, String transformId, Str
217
217
* Verify the basic stats API, which includes state, health, and optionally progress (if it exists).
218
218
* These are required for Kibana 8.13+.
219
219
*/
220
- @ SuppressWarnings ("unchecked" )
221
220
public void testBasicContinuousTransformStats () throws Exception {
222
221
var transformId = "transform-continuous-basic-stats" ;
223
222
createContinuousTransform ("continuous-basic-stats-reviews" , transformId , "reviews-by-user-business-day" );
@@ -234,6 +233,50 @@ public void testBasicContinuousTransformStats() throws Exception {
234
233
deleteTransform (transformId );
235
234
}
236
235
236
+ public void testEmptySourceIndexClearsErrors () throws Exception {
237
+ var sourceIndexName = "source-empty-reviews" ;
238
+ var destIndexName = "destination-empty-reviews" ;
239
+ var transformId = "transform-empty-source-index" ;
240
+
241
+ createReviewsIndexMappings (sourceIndexName , null );
242
+
243
+ var config = createTransformConfigBuilder (transformId , destIndexName , QueryConfig .matchAll (), sourceIndexName ).setPivotConfig (
244
+ createPivotConfig (groupByUserOnly (), aggregateScoresAndTimes ())
245
+ )
246
+ .setSyncConfig (new TimeSyncConfig ("timestamp" , TimeValue .timeValueSeconds (1 )))
247
+ .setSettings (new SettingsConfig .Builder ().setUnattended (true ).build ())
248
+ .build ();
249
+
250
+ putTransform (transformId , Strings .toString (config ), RequestOptions .DEFAULT );
251
+ startTransform (config .getId (), RequestOptions .DEFAULT );
252
+
253
+ waitUntilCheckpoint (config .getId (), 1L );
254
+ assertEquals ("green" , getTransformHealthStatus (transformId ));
255
+
256
+ // this will cause the transform to fail to search
257
+ assertAcknowledged (adminClient ().performRequest (new Request ("PUT" , sourceIndexName + "/_block/read" )));
258
+ assertBusy (() -> assertThat (getTransformHealthStatus (transformId ), oneOf ("yellow" , "red" )), 30 , TimeUnit .SECONDS );
259
+
260
+ // unblock reads on the search index and the transform should recover
261
+ assertAcknowledged (adminClient ().performRequest (new Request ("DELETE" , sourceIndexName + "/_block/read" )));
262
+ assertBusy (() -> assertEquals ("green" , getTransformHealthStatus (transformId )), 30 , TimeUnit .SECONDS );
263
+
264
+ stopTransform (transformId );
265
+ deleteTransform (transformId );
266
+ deleteIndex (sourceIndexName );
267
+ deleteIndex (destIndexName );
268
+ }
269
+
270
+ private Map <String , SingleGroupSource > groupByUserOnly () {
271
+ return Map .of ("by-user" , new TermsGroupSource ("user_id" , null , false ));
272
+ }
273
+
274
+ private AggregatorFactories .Builder aggregateScoresAndTimes () {
275
+ return AggregatorFactories .builder ()
276
+ .addAggregator (AggregationBuilders .avg ("review_score" ).field ("stars" ))
277
+ .addAggregator (AggregationBuilders .max ("timestamp" ).field ("timestamp" ));
278
+ }
279
+
237
280
public void testDestinationIndexBlocked () throws Exception {
238
281
var transformId = "transform-continuous-blocked-destination" ;
239
282
var sourceIndexName = "source-reviews" ;
@@ -385,12 +428,8 @@ public void testContinuousTransformUpdate() throws Exception {
385
428
String indexName = "continuous-reviews-update" ;
386
429
createReviewsIndex (indexName , 10 , NUM_USERS , TransformIT ::getUserIdForRow , TransformIT ::getDateStringForRow );
387
430
388
- Map <String , SingleGroupSource > groups = new HashMap <>();
389
- groups .put ("by-user" , new TermsGroupSource ("user_id" , null , false ));
390
-
391
- AggregatorFactories .Builder aggs = AggregatorFactories .builder ()
392
- .addAggregator (AggregationBuilders .avg ("review_score" ).field ("stars" ))
393
- .addAggregator (AggregationBuilders .max ("timestamp" ).field ("timestamp" ));
431
+ var groups = groupByUserOnly ();
432
+ var aggs = aggregateScoresAndTimes ();
394
433
395
434
String id = "transform-to-update" ;
396
435
String dest = "reviews-by-user-business-day-to-update" ;
@@ -481,8 +520,7 @@ public void testRetentionPolicyDelete() throws Exception {
481
520
String dest = "retention-policy-dest" ;
482
521
createReviewsIndex (indexName , 10 , NUM_USERS , TransformIT ::getUserIdForRow , TransformIT ::getDateStringForRow );
483
522
484
- Map <String , SingleGroupSource > groups = new HashMap <>();
485
- groups .put ("by-user" , new TermsGroupSource ("user_id" , null , false ));
523
+ var groups = groupByUserOnly ();
486
524
487
525
AggregatorFactories .Builder aggs = AggregatorFactories .builder ()
488
526
.addAggregator (AggregationBuilders .max ("timestamp" ).field ("timestamp" ));
0 commit comments