2020import org .elasticsearch .cluster .routing .RoutingTable ;
2121import org .elasticsearch .common .Strings ;
2222import org .elasticsearch .common .UUIDs ;
23+ import org .elasticsearch .common .settings .Settings ;
2324import org .elasticsearch .core .Tuple ;
2425import org .elasticsearch .index .Index ;
2526import org .elasticsearch .index .shard .ShardId ;
3536import java .util .Set ;
3637import java .util .concurrent .Executor ;
3738
39+ import static org .elasticsearch .cluster .node .DiscoveryNode .STATELESS_ENABLED_SETTING_NAME ;
3840import static org .elasticsearch .cluster .routing .ShardRoutingState .STARTED ;
3941import static org .elasticsearch .cluster .routing .TestShardRouting .shardRoutingBuilder ;
4042import static org .hamcrest .Matchers .equalTo ;
43+ import static org .hamcrest .Matchers .nullValue ;
4144import static org .mockito .Mockito .mock ;
4245
4346public class DownsampleShardPersistentTaskExecutorTests extends ESTestCase {
@@ -57,7 +60,12 @@ public void setup() {
5760 "metrics-app1" ,
5861 List .of (new Tuple <>(start , end ))
5962 );
60- executor = new DownsampleShardPersistentTaskExecutor (mock (Client .class ), DownsampleShardTask .TASK_NAME , mock (Executor .class ));
63+ executor = new DownsampleShardPersistentTaskExecutor (
64+ mock (Client .class ),
65+ DownsampleShardTask .TASK_NAME ,
66+ Settings .EMPTY ,
67+ mock (Executor .class )
68+ );
6169 }
6270
6371 public void testGetAssignment () {
@@ -124,7 +132,65 @@ public void testGetAssignmentMissingIndex() {
124132 assertThat (result .getExplanation (), equalTo ("a node to fail and stop this persistent task" ));
125133 }
126134
135+ public void testGetStatelessAssignment () {
136+ executor = new DownsampleShardPersistentTaskExecutor (
137+ mock (Client .class ),
138+ DownsampleShardTask .TASK_NAME ,
139+ Settings .builder ().put (STATELESS_ENABLED_SETTING_NAME , "true" ).build (),
140+ mock (Executor .class )
141+ );
142+ var backingIndex = initialClusterState .metadata ().getProject (projectId ).dataStreams ().get ("metrics-app1" ).getWriteIndex ();
143+ var searchNode = newNode (Set .of (DiscoveryNodeRole .SEARCH_ROLE ));
144+ var indexNode = newNode (Set .of (DiscoveryNodeRole .INDEX_ROLE ));
145+ var shardId = new ShardId (backingIndex , 0 );
146+ var clusterState = ClusterState .builder (initialClusterState )
147+ .nodes (new DiscoveryNodes .Builder ().add (indexNode ).add (searchNode ).build ())
148+ .putRoutingTable (
149+ projectId ,
150+ RoutingTable .builder ()
151+ .add (
152+ IndexRoutingTable .builder (backingIndex )
153+ .addShard (shardRoutingBuilder (shardId , indexNode .getId (), true , STARTED ).withRecoverySource (null ).build ())
154+ )
155+ .build ()
156+ )
157+ .build ();
158+
159+ var params = new DownsampleShardTaskParams (
160+ new DownsampleConfig (new DateHistogramInterval ("1h" )),
161+ shardId .getIndexName (),
162+ 1 ,
163+ 1 ,
164+ shardId ,
165+ Strings .EMPTY_ARRAY ,
166+ Strings .EMPTY_ARRAY ,
167+ Strings .EMPTY_ARRAY
168+ );
169+ var result = executor .getAssignment (params , Set .of (indexNode , searchNode ), clusterState );
170+ assertThat (result .getExecutorNode (), nullValue ());
171+
172+ // Assign a copy of the shard to a search node
173+ clusterState = ClusterState .builder (clusterState )
174+ .putRoutingTable (
175+ projectId ,
176+ RoutingTable .builder ()
177+ .add (
178+ IndexRoutingTable .builder (backingIndex )
179+ .addShard (shardRoutingBuilder (shardId , indexNode .getId (), true , STARTED ).withRecoverySource (null ).build ())
180+ .addShard (shardRoutingBuilder (shardId , searchNode .getId (), false , STARTED ).withRecoverySource (null ).build ())
181+ )
182+ .build ()
183+ )
184+ .build ();
185+ result = executor .getAssignment (params , Set .of (indexNode , searchNode ), clusterState );
186+ assertThat (result .getExecutorNode (), equalTo (searchNode .getId ()));
187+ }
188+
127189 private static DiscoveryNode newNode () {
190+ return newNode (DiscoveryNodeRole .roles ());
191+ }
192+
193+ private static DiscoveryNode newNode (Set <DiscoveryNodeRole > nodes ) {
128194 return DiscoveryNodeUtils .create (
129195 "node_" + UUIDs .randomBase64UUID (random ()),
130196 buildNewFakeTransportAddress (),
0 commit comments