11
11
import org .apache .logging .log4j .Logger ;
12
12
import org .elasticsearch .action .admin .indices .rollover .RolloverAction ;
13
13
import org .elasticsearch .action .admin .indices .rollover .RolloverRequest ;
14
- import org .elasticsearch .action .admin .indices .settings .get .GetSettingsRequest ;
15
- import org .elasticsearch .action .admin .indices .settings .get .GetSettingsResponse ;
16
14
import org .elasticsearch .action .downsample .DownsampleConfig ;
17
- import org .elasticsearch .action .support .IndicesOptions ;
18
15
import org .elasticsearch .cluster .metadata .DataStreamLifecycle ;
19
16
import org .elasticsearch .cluster .metadata .IndexMetadata ;
17
+ import org .elasticsearch .cluster .service .ClusterService ;
20
18
import org .elasticsearch .common .settings .Settings ;
21
19
import org .elasticsearch .core .TimeValue ;
22
20
import org .elasticsearch .datastreams .DataStreamsPlugin ;
23
21
import org .elasticsearch .datastreams .lifecycle .DataStreamLifecycleService ;
24
22
import org .elasticsearch .plugins .Plugin ;
25
23
import org .elasticsearch .search .aggregations .bucket .histogram .DateHistogramInterval ;
24
+ import org .elasticsearch .test .ClusterServiceUtils ;
26
25
import org .elasticsearch .test .ESIntegTestCase ;
27
26
import org .elasticsearch .test .InternalTestCluster ;
28
- import org .elasticsearch .test .junit .annotations .TestLogging ;
29
27
import org .elasticsearch .xpack .aggregatemetric .AggregateMetricMapperPlugin ;
30
28
import org .elasticsearch .xpack .core .LocalStateCompositeXPackPlugin ;
31
29
32
30
import java .util .Collection ;
33
31
import java .util .List ;
34
32
import java .util .concurrent .TimeUnit ;
35
33
34
+ import static org .elasticsearch .cluster .metadata .IndexMetadata .INDEX_DOWNSAMPLE_STATUS ;
36
35
import static org .elasticsearch .xpack .downsample .DataStreamLifecycleDriver .getBackingIndices ;
37
36
import static org .elasticsearch .xpack .downsample .DataStreamLifecycleDriver .putTSDBIndexTemplate ;
38
- import static org .hamcrest .Matchers .is ;
39
- import static org .hamcrest .Matchers .notNullValue ;
40
37
41
38
@ ESIntegTestCase .ClusterScope (scope = ESIntegTestCase .Scope .TEST , numDataNodes = 0 , numClientNodes = 4 )
42
39
public class DataStreamLifecycleDownsampleDisruptionIT extends ESIntegTestCase {
43
40
private static final Logger logger = LogManager .getLogger (DataStreamLifecycleDownsampleDisruptionIT .class );
44
- public static final int DOC_COUNT = 50_000 ;
41
+ public static final int DOC_COUNT = 25_000 ;
45
42
46
43
@ Override
47
44
protected Collection <Class <? extends Plugin >> nodePlugins () {
@@ -55,7 +52,6 @@ protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) {
55
52
return settings .build ();
56
53
}
57
54
58
- @ TestLogging (value = "org.elasticsearch.datastreams.lifecycle:TRACE" , reason = "debugging" )
59
55
public void testDataStreamLifecycleDownsampleRollingRestart () throws Exception {
60
56
final InternalTestCluster cluster = internalCluster ();
61
57
cluster .startMasterOnlyNodes (1 );
@@ -88,38 +84,38 @@ public void testDataStreamLifecycleDownsampleRollingRestart() throws Exception {
88
84
// testing so DSL doesn't have to wait for the end_time to lapse)
89
85
putTSDBIndexTemplate (client (), dataStreamName , null , null , lifecycle );
90
86
client ().execute (RolloverAction .INSTANCE , new RolloverRequest (dataStreamName , null )).actionGet ();
87
+ String sourceIndex = getBackingIndices (client (), dataStreamName ).get (0 );
88
+ final String targetIndex = "downsample-5m-" + sourceIndex ;
91
89
92
- // DSL runs every second and it has to tail forcemerge the index (2 seconds) and mark it as read-only (2s) before it starts
93
- // downsampling. This sleep here tries to get as close as possible to having disruption during the downsample execution.
94
- long sleepTime = randomLongBetween (3000 , 4500 );
95
- logger .info ("-> giving data stream lifecycle [{}] millis to make some progress before starting the disruption" , sleepTime );
96
- Thread .sleep (sleepTime );
97
- List <String > backingIndices = getBackingIndices (client (), dataStreamName );
98
- // first generation index
99
- String sourceIndex = backingIndices .get (0 );
90
+ /**
91
+ * DLM runs every second and it has to tail forcemerge the index (2 seconds) and mark it as read-only (2s) before it starts
92
+ * downsampling. We try to detect if the downsampling has started by checking the downsample status in the target index.
93
+ */
94
+ logger .info ("-> Waiting for the data stream lifecycle to start the downsampling operation before starting the disruption." );
95
+ ensureDownsamplingStatus (targetIndex , IndexMetadata .DownsampleTaskStatus .STARTED , TimeValue .timeValueSeconds (8 ));
100
96
101
- internalCluster (). rollingRestart ( new InternalTestCluster . RestartCallback () {
102
- } );
97
+ logger . info ( "-> Starting the disruption." );
98
+ internalCluster (). rollingRestart ( new InternalTestCluster . RestartCallback () );
103
99
104
- // if the source index has already been downsampled and moved into the data stream just use its name directly
105
- final String targetIndex = sourceIndex .startsWith ("downsample-5m-" ) ? sourceIndex : "downsample-5m-" + sourceIndex ;
106
- assertBusy (() -> {
107
- try {
108
- GetSettingsResponse getSettingsResponse = cluster .client ()
109
- .admin ()
110
- .indices ()
111
- .getSettings (
112
- new GetSettingsRequest (TEST_REQUEST_TIMEOUT ).indices (targetIndex ).indicesOptions (IndicesOptions .LENIENT_EXPAND_OPEN )
113
- )
114
- .actionGet ();
115
- Settings indexSettings = getSettingsResponse .getIndexToSettings ().get (targetIndex );
116
- assertThat (indexSettings , is (notNullValue ()));
117
- assertThat (IndexMetadata .INDEX_DOWNSAMPLE_STATUS .get (indexSettings ), is (IndexMetadata .DownsampleTaskStatus .SUCCESS ));
118
- assertEquals ("5m" , IndexMetadata .INDEX_DOWNSAMPLE_INTERVAL .get (indexSettings ));
119
- } catch (Exception e ) {
120
- throw new AssertionError (e );
121
- }
122
- }, 120 , TimeUnit .SECONDS );
100
+ ensureDownsamplingStatus (targetIndex , IndexMetadata .DownsampleTaskStatus .SUCCESS , TimeValue .timeValueSeconds (120 ));
123
101
ensureGreen (targetIndex );
102
+ logger .info ("-> Relocation has finished" );
103
+ }
104
+
105
+ private void ensureDownsamplingStatus (String downsampledIndex , IndexMetadata .DownsampleTaskStatus expectedStatus , TimeValue timeout ) {
106
+ final var clusterService = internalCluster ().getCurrentMasterNodeInstance (ClusterService .class );
107
+ final var listener = ClusterServiceUtils .addTemporaryStateListener (clusterService , clusterState -> {
108
+ final var indexMetadata = clusterState .metadata ().getProject ().index (downsampledIndex );
109
+ if (indexMetadata == null ) {
110
+ return false ;
111
+ }
112
+ var downsamplingStatus = INDEX_DOWNSAMPLE_STATUS .get (indexMetadata .getSettings ());
113
+ if (expectedStatus == downsamplingStatus ) {
114
+ logger .info ("-> Downsampling status for index [{}] is [{}]" , downsampledIndex , downsamplingStatus );
115
+ return true ;
116
+ }
117
+ return false ;
118
+ });
119
+ safeAwait (listener , timeout .millis (), TimeUnit .MILLISECONDS );
124
120
}
125
121
}
0 commit comments