alievmirza commented on code in PR #6902:
URL: https://github.com/apache/ignite-3/pull/6902#discussion_r2540833561
##########
modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DataNodesManager.java:
##########
@@ -913,12 +919,14 @@ public CompletableFuture<Set<String>> dataNodes(int
zoneId, HybridTimestamp time
}
/**
- * Unlike {@link #dataNodes} this method recalculates the data nodes,
writes it to metastorage and history, and returns them.
+ * Unlike {@link #dataNodes} this method recalculates the data nodes for
given zone and writes them to metastorage.
Review Comment:
redundant space
##########
modules/distribution-zones/src/testFixtures/java/org/apache/ignite/internal/distributionzones/DataNodesTestUtil.java:
##########
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.distributionzones;
+
+import static
org.apache.ignite.internal.catalog.commands.CatalogUtils.INFINITE_TIMER_VALUE;
+import static
org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.zoneId;
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
+import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willSucceedFast;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import org.apache.ignite.internal.app.IgniteImpl;
+import org.apache.ignite.internal.catalog.CatalogManager;
+import org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor;
+import
org.apache.ignite.internal.distributionzones.DataNodesManager.ZoneTimerSchedule;
+import
org.apache.ignite.internal.distributionzones.DataNodesManager.ZoneTimers;
+import org.apache.ignite.internal.hlc.ClockService;
+import org.awaitility.Awaitility;
+
+/**
+ * Class that contains useful methods for data nodes testing purposes.
+ */
+public final class DataNodesTestUtil {
+ /**
+ * Creates a zone with given name and both scale up and scale down timers
as infinite.
+ *
+ * @param node Ignite node.
+ * @param zoneName New zone name.
+ */
+ public static void createZoneWithInfiniteTimers(IgniteImpl node, String
zoneName) {
+ DistributionZonesTestUtil.createZone(
+ node.catalogManager(),
+ zoneName,
+ (Integer) INFINITE_TIMER_VALUE,
+ (Integer) INFINITE_TIMER_VALUE,
Review Comment:
Why do we need these casts?
##########
modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DataNodesManagerTest.java:
##########
@@ -604,16 +584,16 @@ private void assertScaleDownScheduledOrDone(String
zoneName) throws InterruptedE
assertTrue(success);
}
- private void assertScaleDownNotScheduled(String zoneName) throws
InterruptedException {
- assertFalse(waitForCondition(() ->
dataNodesManager.zoneTimers(zoneId(zoneName)).scaleDown.taskIsScheduled(),
1000));
+ private int zoneId(String zoneName) {
+ return DistributionZonesTestUtil.zoneId(catalogManager, zoneName);
}
- private boolean scaleUpScheduled(String zoneName) {
- return
dataNodesManager.zoneTimers(zoneId(zoneName)).scaleUp.taskIsScheduled();
+ private CatalogZoneDescriptor descriptor(String zoneName) {
+ return DistributionZonesTestUtil.descriptor(catalogManager, zoneName);
}
- private boolean scaleDownScheduled(String zoneName) {
- return
dataNodesManager.zoneTimers(zoneId(zoneName)).scaleDown.taskIsScheduled();
+ private void assertScaleDownNotScheduled(String zoneName) throws
InterruptedException {
+ assertFalse(waitForCondition(() ->
dataNodesManager.zoneTimers(zoneId(zoneName)).scaleDown.taskIsScheduled(),
1000));
Review Comment:
awaitility
##########
modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/zone/datanodes/DataNodesApi.java:
##########
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.rest.api.cluster.zone.datanodes;
+
+import io.micronaut.http.annotation.Body;
+import io.micronaut.http.annotation.Controller;
+import io.micronaut.http.annotation.Get;
+import io.micronaut.http.annotation.PathVariable;
+import io.micronaut.http.annotation.Post;
+import io.micronaut.http.annotation.Produces;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.internal.rest.api.Problem;
+import org.apache.ignite.internal.rest.constants.MediaType;
+
+/**
+ * Data nodes of distribution zones controller.
+ */
+@Controller("/management/v1/zones")
+@Tag(name = "datanodes")
+public interface DataNodesApi {
+ @Get("{zoneName}/datanodes")
+ @Operation(
+ operationId = "getDataNodesForZone",
+ description = "Returns current data nodes for zone."
+ )
+ @ApiResponse(
+ responseCode = "200",
+ description = "Data nodes are returned.",
+ content = @Content(
+ mediaType = MediaType.APPLICATION_JSON,
+ array = @ArraySchema(schema = @Schema(implementation =
String.class), uniqueItems = true)
+ )
+ )
+ @ApiResponse(responseCode = "400", description = "Bad request.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @ApiResponse(responseCode = "500", description = "Internal error.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.PROBLEM_JSON })
+ CompletableFuture<Set<String>> getDataNodesForZone(
+ @PathVariable
+ @Schema(description = "Case-sensitive zone name to return
datanodes for.")
+ String zoneName
+ );
+
+ @Post("{zoneName}/datanodes/reset")
+ @Operation(
+ operationId = "resetDataNodesForZone",
+ description = "Recalculates and resets data nodes for zone."
+ )
+ @ApiResponse(responseCode = "200", description = "Data nodes are
recalculated and reset.")
+ @ApiResponse(responseCode = "400", description = "Bad request.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @ApiResponse(responseCode = "500", description = "Internal error.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @Produces(MediaType.PROBLEM_JSON)
+ CompletableFuture<Void> resetDataNodesForZone(
+ @PathVariable
+ @Schema(description = "Case-sensitive zone name to recalculate
datanodes for.")
+ String zoneName
+ );
+
+ @Post("/datanodes/reset")
+ @Operation(
+ operationId = "resetDataNodesForZones",
+ description = "Recalculates and resets data nodes for given zones."
+ )
+ @ApiResponse(responseCode = "200", description = "Data nodes are
recalculated and reset.")
+ @ApiResponse(responseCode = "400", description = "Bad request.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @ApiResponse(responseCode = "500", description = "Internal error.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @Produces(MediaType.PROBLEM_JSON)
+ CompletableFuture<Void> resetDataNodesForZones(
+ @Body
+ @Schema(description = "Names specifying zones to recalculate
datanodes for. Case-sensitive, "
Review Comment:
`datanodes` or `data nodes`? the name must be consistent, somewhere you
write `Data nodes`
##########
modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/zone/datanodes/DataNodesApi.java:
##########
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.rest.api.cluster.zone.datanodes;
+
+import io.micronaut.http.annotation.Body;
+import io.micronaut.http.annotation.Controller;
+import io.micronaut.http.annotation.Get;
+import io.micronaut.http.annotation.PathVariable;
+import io.micronaut.http.annotation.Post;
+import io.micronaut.http.annotation.Produces;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.internal.rest.api.Problem;
+import org.apache.ignite.internal.rest.constants.MediaType;
+
+/**
+ * Data nodes of distribution zones controller.
+ */
+@Controller("/management/v1/zones")
+@Tag(name = "datanodes")
Review Comment:
dataNodes
##########
modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DataNodesManager.java:
##########
@@ -913,12 +919,14 @@ public CompletableFuture<Set<String>> dataNodes(int
zoneId, HybridTimestamp time
}
/**
- * Unlike {@link #dataNodes} this method recalculates the data nodes,
writes it to metastorage and history, and returns them.
+ * Unlike {@link #dataNodes} this method recalculates the data nodes for
given zone and writes them to metastorage.
*
* @param zoneName Zone name.
- * @return Recalculated data nodes for the given zone.
+ * @return The future with recalculated data nodes for the given zone.
*/
public CompletableFuture<Set<String>> recalculateDataNodes(String
zoneName) {
Review Comment:
Why do you need to return `CompletableFuture<Set<String>>` if you do not use
it at all?
##########
modules/rest/src/main/java/org/apache/ignite/internal/rest/cluster/DataNodesController.java:
##########
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.rest.cluster;
Review Comment:
please move to zones submodule
##########
modules/distribution-zones/src/integrationTest/java/org/apache/ignite/internal/distributionzones/ItDataNodesManagerTest.java:
##########
Review Comment:
awaitility
##########
modules/rest/src/integrationTest/java/org/apache/ignite/internal/rest/cluster/ItDataNodesControllerTest.java:
##########
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.rest.cluster;
+
+import static org.apache.ignite.internal.TestWrappers.unwrapIgniteImpl;
+import static
org.apache.ignite.internal.distributionzones.DataNodesTestUtil.assertDistributionZoneScaleTimersAreNotScheduled;
+import static
org.apache.ignite.internal.distributionzones.DataNodesTestUtil.assertScaleDownScheduledOrDone;
+import static
org.apache.ignite.internal.distributionzones.DataNodesTestUtil.assertScaleUpScheduledOrDone;
+import static
org.apache.ignite.internal.distributionzones.DataNodesTestUtil.createZoneWithInfiniteTimers;
+import static
org.apache.ignite.internal.distributionzones.DataNodesTestUtil.waitForDataNodes;
+import static
org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.alterZone;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import io.micronaut.core.type.Argument;
+import io.micronaut.http.HttpRequest;
+import io.micronaut.http.HttpResponse;
+import io.micronaut.http.HttpStatus;
+import io.micronaut.http.client.HttpClient;
+import io.micronaut.http.client.annotation.Client;
+import io.micronaut.http.client.exceptions.HttpClientResponseException;
+import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
+import jakarta.inject.Inject;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.ClusterConfiguration;
+import org.apache.ignite.internal.ClusterPerTestIntegrationTest;
+import org.apache.ignite.internal.app.IgniteImpl;
+import
org.apache.ignite.internal.cluster.management.topology.api.LogicalTopologyService;
+import org.apache.ignite.internal.rest.constants.HttpCode;
+import org.awaitility.Awaitility;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/** Test for distributed zones data nodes controller. */
+@MicronautTest
+public class ItDataNodesControllerTest extends ClusterPerTestIntegrationTest {
+ private static final String ZONE_NAME = "test_zone";
+
+ private static final String UNKNOWN_ZONE_NAME = "test_zone_unknown";
+
+ private static final String DATA_NODES_ENDPOINT = "/datanodes";
+
+ private static final String DATA_NODES_RESET_ENDPOINT =
DATA_NODES_ENDPOINT + "/reset";
+
+ private static final String NODE_URL = "http://localhost:" +
ClusterConfiguration.DEFAULT_BASE_HTTP_PORT;
+
+ @Inject
+ @Client(NODE_URL + "/management/v1/zones")
+ private HttpClient client;
+
+ @Override
+ protected int initialNodes() {
+ return 1;
+ }
+
+ @BeforeEach
+ public void setup() {
+ createZoneWithInfiniteTimers(unwrapIgniteImpl(node(0)), ZONE_NAME);
+ }
+
+ @Test
+ public void restDataNodesResetIdempotencyTest() {
+ HttpResponse<String> response =
doRestDataNodesResetForZonesCall(Set.of(ZONE_NAME));
+
+ assertThat(response.getStatus().getCode(), is(HttpCode.OK.code()));
+ }
+
+ @Test
+ public void restDataNodesResetAfterNewNodeAddedTest() throws
InterruptedException {
Review Comment:
`InterruptedException` is not thrown
##########
modules/rest-api/src/main/java/org/apache/ignite/internal/rest/api/cluster/zone/datanodes/DataNodesApi.java:
##########
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.rest.api.cluster.zone.datanodes;
+
+import io.micronaut.http.annotation.Body;
+import io.micronaut.http.annotation.Controller;
+import io.micronaut.http.annotation.Get;
+import io.micronaut.http.annotation.PathVariable;
+import io.micronaut.http.annotation.Post;
+import io.micronaut.http.annotation.Produces;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.internal.rest.api.Problem;
+import org.apache.ignite.internal.rest.constants.MediaType;
+
+/**
+ * Data nodes of distribution zones controller.
+ */
+@Controller("/management/v1/zones")
+@Tag(name = "datanodes")
+public interface DataNodesApi {
+ @Get("{zoneName}/datanodes")
+ @Operation(
+ operationId = "getDataNodesForZone",
+ description = "Returns current data nodes for zone."
+ )
+ @ApiResponse(
+ responseCode = "200",
+ description = "Data nodes are returned.",
+ content = @Content(
+ mediaType = MediaType.APPLICATION_JSON,
+ array = @ArraySchema(schema = @Schema(implementation =
String.class), uniqueItems = true)
+ )
+ )
+ @ApiResponse(responseCode = "400", description = "Bad request.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @ApiResponse(responseCode = "500", description = "Internal error.",
+ content = @Content(mediaType = MediaType.PROBLEM_JSON, schema =
@Schema(implementation = Problem.class)))
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.PROBLEM_JSON })
+ CompletableFuture<Set<String>> getDataNodesForZone(
+ @PathVariable
+ @Schema(description = "Case-sensitive zone name to return
datanodes for.")
+ String zoneName
+ );
+
+ @Post("{zoneName}/datanodes/reset")
+ @Operation(
+ operationId = "resetDataNodesForZone",
+ description = "Recalculates and resets data nodes for zone."
Review Comment:
what do you mean by reset here? if you are talking about timers reset, it
worth to mention it
##########
modules/distribution-zones/src/testFixtures/java/org/apache/ignite/internal/distributionzones/DataNodesTestUtil.java:
##########
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.distributionzones;
+
+import static
org.apache.ignite.internal.catalog.commands.CatalogUtils.INFINITE_TIMER_VALUE;
+import static
org.apache.ignite.internal.distributionzones.DistributionZonesTestUtil.zoneId;
+import static org.apache.ignite.internal.lang.IgniteStringFormatter.format;
+import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willCompleteSuccessfully;
+import static
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willSucceedFast;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
+import org.apache.ignite.internal.app.IgniteImpl;
+import org.apache.ignite.internal.catalog.CatalogManager;
+import org.apache.ignite.internal.catalog.descriptors.CatalogZoneDescriptor;
+import
org.apache.ignite.internal.distributionzones.DataNodesManager.ZoneTimerSchedule;
+import
org.apache.ignite.internal.distributionzones.DataNodesManager.ZoneTimers;
+import org.apache.ignite.internal.hlc.ClockService;
+import org.awaitility.Awaitility;
+
+/**
+ * Class that contains useful methods for data nodes testing purposes.
+ */
+public final class DataNodesTestUtil {
+ /**
+ * Creates a zone with given name and both scale up and scale down timers
as infinite.
+ *
+ * @param node Ignite node.
+ * @param zoneName New zone name.
+ */
+ public static void createZoneWithInfiniteTimers(IgniteImpl node, String
zoneName) {
+ DistributionZonesTestUtil.createZone(
+ node.catalogManager(),
+ zoneName,
+ (Integer) INFINITE_TIMER_VALUE,
+ (Integer) INFINITE_TIMER_VALUE,
+ null
+ );
+
+ CatalogManager catalogManager = node.catalogManager();
+
+ CatalogZoneDescriptor zoneDesc =
catalogManager.catalog(catalogManager.latestCatalogVersion()).zone(zoneName);
+
+ assertNotNull(zoneDesc);
+ }
+
+ /**
+ * Waits for data nodes are recalculated as expected for given zone.
+ *
+ * @param node Ignite node.
+ * @param zoneName Zone name to check data nodes for.
+ * @param expectedDataNodes Expected data node names to wait for.
+ */
+ public static void waitForDataNodes(
+ IgniteImpl node,
+ String zoneName,
+ Set<String> expectedDataNodes
+ ) {
+ ClockService clock = node.clockService();
+
+ int zoneId = zoneId(node.catalogManager(), zoneName);
+
+ DataNodesManager dataNodesManager =
node.distributionZoneManager().dataNodesManager();
+
+ Awaitility.await().atMost(10, TimeUnit.SECONDS).untilAsserted(() -> {
+ CompletableFuture<Set<String>> dataNodesFuture =
dataNodesManager.dataNodes(zoneId, clock.now());
+ assertThat(dataNodesFuture, willSucceedFast());
+ assertEquals(expectedDataNodes, dataNodesFuture.join());
+ });
+ }
+
+ /**
+ * Performs manual data nodes recalculation and waits until recalculated
data nodes will be as expected for given zone.
+ *
+ * @param node Ignite node.
+ * @param zoneName Zone name to check data nodes for.
+ * @param expectedDataNodes Expected data node names to wait for.
+ */
+ public static void recalculateZoneDataNodesManuallyAndWaitForDataNodes(
+ IgniteImpl node,
+ String zoneName,
+ Set<String> expectedDataNodes
+ ) throws InterruptedException {
Review Comment:
`InterruptedException` is not thrown
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]