This is an automated email from the ASF dual-hosted git repository.

sk0x50 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 6f3c9a0fc2 IGNITE-18093 Introduced distribution zone manager for the 
purposes of zones configuration. Fixes #1339
6f3c9a0fc2 is described below

commit 6f3c9a0fc2fc4bd6f8263416305f0f9724e7e4be
Author: Sergey Uttsel <[email protected]>
AuthorDate: Mon Nov 28 09:50:00 2022 +0200

    IGNITE-18093 Introduced distribution zone manager for the purposes of zones 
configuration. Fixes #1339
    
    Signed-off-by: Slava Koptilin <[email protected]>
---
 .../ignite/configuration/NamedListChange.java      |   5 +-
 .../internal/configuration/tree/NamedListNode.java |   4 +
 .../java/org/apache/ignite/lang/ErrorGroups.java   |  15 +
 modules/distribution-zones/build.gradle            |  42 ++
 modules/distribution-zones/pom.xml                 | 135 +++++++
 .../DistributionZoneConfigurationParameters.java   | 179 +++++++++
 .../distributionzones/DistributionZoneManager.java | 208 ++++++++++
 .../DistributionZoneConfigurationSchema.java       |  55 +++
 .../DistributionZonesConfigurationSchema.java      |  37 ++
 .../DistributionZoneAlreadyExistsException.java    |  51 +++
 .../DistributionZoneNotFoundException.java         |  60 +++
 .../exception/DistributionZoneRenameException.java |  51 +++
 ...istributionZoneConfigurationParametersTest.java | 106 +++++
 .../DistributionZoneManagerTest.java               | 442 +++++++++++++++++++++
 .../ErrorGroupsGenerator.cs                        |   2 +-
 .../dotnet/Apache.Ignite.Tests/ErrorGroupTests.cs  |   4 +
 modules/runner/build.gradle                        |   1 +
 modules/runner/pom.xml                             |   5 +
 .../org/apache/ignite/internal/app/IgniteImpl.java |  15 +
 parent/pom.xml                                     |   6 +
 pom.xml                                            |   1 +
 settings.gradle                                    |   2 +
 22 files changed, 1423 insertions(+), 3 deletions(-)

diff --git 
a/modules/configuration-api/src/main/java/org/apache/ignite/configuration/NamedListChange.java
 
b/modules/configuration-api/src/main/java/org/apache/ignite/configuration/NamedListChange.java
index c4e1865b90..912a56572a 100644
--- 
a/modules/configuration-api/src/main/java/org/apache/ignite/configuration/NamedListChange.java
+++ 
b/modules/configuration-api/src/main/java/org/apache/ignite/configuration/NamedListChange.java
@@ -99,8 +99,9 @@ public interface NamedListChange<VIEWT, CHANGET extends 
VIEWT> extends NamedList
     NamedListChange<VIEWT, CHANGET> update(String key, Consumer<CHANGET> 
valConsumer);
 
     /**
-     * Renames the existing value in the named list configuration. Element 
with key {@code oldKey} must exist and key
-     * {@code newKey} must not. Error will occur if {@code newKey} has just 
been deleted on the same
+     * Renames the existing value in the named list configuration. Does 
nothing if {@code oldKey} and {@code newKey} are the same.
+     * Element with key {@code oldKey} must exist and key {@code newKey} must 
not.
+     * Error will occur if {@code newKey} has just been deleted on the same
      * {@link NamedListChange} instance (to distinguish between
      * {@link ConfigurationNamedListListener#onRename(String, String, 
ConfigurationNotificationEvent)} and
      * {@link 
ConfigurationNamedListListener#onUpdate(ConfigurationNotificationEvent)} on 
{@code newKey}).
diff --git 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/tree/NamedListNode.java
 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/tree/NamedListNode.java
index da94ba0a92..694c7208d0 100644
--- 
a/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/tree/NamedListNode.java
+++ 
b/modules/configuration/src/main/java/org/apache/ignite/internal/configuration/tree/NamedListNode.java
@@ -271,6 +271,10 @@ public final class NamedListNode<N> implements 
NamedListChange<N, N>, Traversabl
         Objects.requireNonNull(oldKey, "oldKey");
         Objects.requireNonNull(newKey, "newKey");
 
+        if (oldKey.equals(newKey)) {
+            return this;
+        }
+
         ElementDescriptor element = map.get(oldKey);
 
         if (element == null) {
diff --git a/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroups.java 
b/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroups.java
index 1e38e7f5e6..6d47deadeb 100755
--- a/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroups.java
+++ b/modules/core/src/main/java/org/apache/ignite/lang/ErrorGroups.java
@@ -320,4 +320,19 @@ public class ErrorGroups {
         /** Failed to create a directory. */
         public static final int DIRECTORY_CREATION_ERR = 
STORAGE_ERR_GROUP.registerErrorCode(1);
     }
+
+    /** Distribution zones error group. */
+    public static class DistributionZones {
+        /** Distribution zones group. */
+        public static final ErrorGroup DISTRIBUTION_ZONES_ERR_GROUP = 
ErrorGroup.newGroup("DISTRZONES", 10);
+
+        /** Distribution zone already exists. */
+        public static final int ZONE_ALREADY_EXISTS_ERR = 
DISTRIBUTION_ZONES_ERR_GROUP.registerErrorCode(1);
+
+        /** Distribution zone is not found. */
+        public static final int ZONE_NOT_FOUND_ERR = 
DISTRIBUTION_ZONES_ERR_GROUP.registerErrorCode(2);
+
+        /** Distribution zone rename error. */
+        public static final int ZONE_RENAME_ERR = 
DISTRIBUTION_ZONES_ERR_GROUP.registerErrorCode(3);
+    }
 }
diff --git a/modules/distribution-zones/build.gradle 
b/modules/distribution-zones/build.gradle
new file mode 100644
index 0000000000..c4bf2b78e3
--- /dev/null
+++ b/modules/distribution-zones/build.gradle
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+apply from: "$rootDir/buildscripts/java-core.gradle"
+apply from: "$rootDir/buildscripts/publishing.gradle"
+apply from: "$rootDir/buildscripts/java-junit5.gradle"
+apply from: "$rootDir/buildscripts/java-integration-test.gradle"
+apply from: "$rootDir/buildscripts/java-test-fixtures.gradle"
+
+
+dependencies {
+    annotationProcessor project(":ignite-configuration-annotation-processor")
+    api project(':ignite-configuration-api')
+    implementation project(':ignite-core')
+    implementation project(':ignite-configuration')
+    implementation project(':ignite-api')
+
+    implementation libs.jetbrains.annotations
+    implementation libs.fastutil.core
+
+    testImplementation libs.mockito.core
+    testImplementation libs.mockito.junit
+
+    testImplementation(testFixtures(project(':ignite-core')))
+    testImplementation(testFixtures(project(':ignite-configuration')))
+}
+
+description = 'ignite-distribution-zones'
diff --git a/modules/distribution-zones/pom.xml 
b/modules/distribution-zones/pom.xml
new file mode 100644
index 0000000000..ed8174685d
--- /dev/null
+++ b/modules/distribution-zones/pom.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ignite-distribution-zones</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-configuration-api</artifactId>
+        </dependency>
+
+        <!-- 3rd party dependencies -->
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-configuration</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-configuration</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>default-testJar</id>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.ignite</groupId>
+                        
<artifactId>ignite-configuration-annotation-processor</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <annotationProcessorPaths>
+                        <path>
+                            <groupId>org.apache.ignite</groupId>
+                            
<artifactId>ignite-configuration-annotation-processor</artifactId>
+                            <version>${project.version}</version>
+                        </path>
+                    </annotationProcessorPaths>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZoneConfigurationParameters.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZoneConfigurationParameters.java
new file mode 100644
index 0000000000..a1332e20d3
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZoneConfigurationParameters.java
@@ -0,0 +1,179 @@
+/*
+ * 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 org.jetbrains.annotations.Nullable;
+
+/**
+ * Distribution zone configuration.
+ */
+public class DistributionZoneConfigurationParameters {
+    /** Zone name. */
+    private final String name;
+
+    /** Data nodes auto adjust timeout. */
+    private final Integer dataNodesAutoAdjust;
+
+    /** Data nodes auto adjust scale up timeout. */
+    private final Integer dataNodesAutoAdjustScaleUp;
+
+    /** Data nodes auto adjust scale down timeout. */
+    private final Integer dataNodesAutoAdjustScaleDown;
+
+    /**
+     * The constructor.
+     */
+    private DistributionZoneConfigurationParameters(
+            String name,
+            Integer dataNodesAutoAdjust,
+            Integer dataNodesAutoAdjustScaleUp,
+            Integer dataNodesAutoAdjustScaleDown
+    ) {
+        this.name = name;
+        this.dataNodesAutoAdjust = dataNodesAutoAdjust;
+        this.dataNodesAutoAdjustScaleUp = dataNodesAutoAdjustScaleUp;
+        this.dataNodesAutoAdjustScaleDown = dataNodesAutoAdjustScaleDown;
+    }
+
+    /**
+     * Gets the zone name.
+     *
+     * @return The zone name.
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Gets timeout in seconds between node added or node left topology event 
itself and data nodes switch.
+     *
+     * @return Data nodes auto adjust timeout.
+     */
+    @Nullable public Integer dataNodesAutoAdjust() {
+        return dataNodesAutoAdjust;
+    }
+
+    /**
+     * Gets timeout in seconds between node added topology event itself and 
data nodes switch.
+     *
+     * @return Data nodes auto adjust scale up timeout.
+     */
+    @Nullable public Integer dataNodesAutoAdjustScaleUp() {
+        return dataNodesAutoAdjustScaleUp;
+    }
+
+    /**
+     * Gets timeout in seconds between node left topology event itself and 
data nodes switch.
+     *
+     * @return Data nodes auto adjust scale down timeout.
+     */
+    @Nullable public Integer dataNodesAutoAdjustScaleDown() {
+        return dataNodesAutoAdjustScaleDown;
+    }
+
+    /**
+     * Builder for distribution zone configuration.
+     */
+    public static class Builder {
+        /** Zone name. */
+        private String name;
+
+        /** Data nodes auto adjust timeout. */
+        private Integer dataNodesAutoAdjust;
+
+        /** Data nodes auto adjust scale up timeout. */
+        private Integer dataNodesAutoAdjustScaleUp;
+
+        /** Data nodes auto adjust scale down timeout. */
+        private Integer dataNodesAutoAdjustScaleDown;
+
+        /**
+         * Constructor.
+         *
+         * @param name Name.
+         */
+        public Builder(String name) {
+            if (name == null || name.isEmpty()) {
+                throw new IllegalArgumentException("Illegal distribution zone 
name [name=" + name + ']');
+            }
+
+            this.name = name;
+        }
+
+        /**
+         * Sets timeout in seconds between node added or node left topology 
event itself and data nodes switch.
+         *
+         * @param dataNodesAutoAdjust Timeout.
+         * @return This instance.
+         */
+        public Builder dataNodesAutoAdjust(int dataNodesAutoAdjust) {
+            this.dataNodesAutoAdjust = dataNodesAutoAdjust;
+
+            return this;
+        }
+
+        /**
+         * Sets timeout in seconds between node added topology event itself 
and data nodes switch.
+         *
+         * @param dataNodesAutoAdjustScaleUp Timeout.
+         * @return This instance.
+         */
+        public Builder dataNodesAutoAdjustScaleUp(int 
dataNodesAutoAdjustScaleUp) {
+            this.dataNodesAutoAdjustScaleUp = dataNodesAutoAdjustScaleUp;
+
+            return this;
+        }
+
+        /**
+         * Sets timeout in seconds between node left topology event itself and 
data nodes switch.
+         *
+         * @param dataNodesAutoAdjustScaleDown Timeout in seconds between node 
left topology event itself
+         *     and data nodes switch.
+         * @return This instance.
+         */
+        public Builder dataNodesAutoAdjustScaleDown(int 
dataNodesAutoAdjustScaleDown) {
+            this.dataNodesAutoAdjustScaleDown = dataNodesAutoAdjustScaleDown;
+
+            return this;
+        }
+
+        /**
+         * Builds the distribution zone configuration.
+         *
+         * @return Distribution zone configuration.
+         */
+        public DistributionZoneConfigurationParameters build() {
+            if (dataNodesAutoAdjust != null
+                    && (dataNodesAutoAdjustScaleUp != null || 
dataNodesAutoAdjustScaleDown != null)
+            ) {
+                throw new IllegalArgumentException(
+                        "Not compatible parameters [dataNodesAutoAdjust=" + 
dataNodesAutoAdjust
+                                + ", dataNodesAutoAdjustScaleUp=" + 
dataNodesAutoAdjustScaleUp
+                                + ", dataNodesAutoAdjustScaleDown=" + 
dataNodesAutoAdjustScaleDown + ']'
+                );
+            }
+
+            return new DistributionZoneConfigurationParameters(
+                    name,
+                    dataNodesAutoAdjust,
+                    dataNodesAutoAdjustScaleUp,
+                    dataNodesAutoAdjustScaleDown
+            );
+        }
+    }
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZoneManager.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZoneManager.java
new file mode 100644
index 0000000000..e16493756e
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZoneManager.java
@@ -0,0 +1,208 @@
+/*
+ * 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.lang.ErrorGroups.Common.UNEXPECTED_ERR;
+
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import org.apache.ignite.configuration.NamedListChange;
+import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZoneChange;
+import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZoneView;
+import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZonesConfiguration;
+import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneAlreadyExistsException;
+import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneNotFoundException;
+import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneRenameException;
+import org.apache.ignite.internal.manager.IgniteComponent;
+import org.apache.ignite.internal.util.IgniteSpinBusyLock;
+import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.lang.IgniteInternalException;
+import org.apache.ignite.lang.NodeStoppingException;
+
+/**
+ * Distribution zones manager.
+ */
+public class DistributionZoneManager implements IgniteComponent {
+    /** Distribution zone configuration. */
+    private final DistributionZonesConfiguration zonesConfiguration;
+
+    /** Busy lock to stop synchronously. */
+    private final IgniteSpinBusyLock busyLock = new IgniteSpinBusyLock();
+
+    /**
+     * Creates a new distribution zone manager.
+     *
+     * @param zonesConfiguration Distribution zones configuration.
+     */
+    public DistributionZoneManager(DistributionZonesConfiguration 
zonesConfiguration) {
+        this.zonesConfiguration = zonesConfiguration;
+    }
+
+    /**
+     * Creates a new distribution zone with the given {@code name} 
asynchronously.
+     *
+     * @param distributionZoneCfg Distribution zone configuration.
+     * @return Future representing pending completion of the operation.
+     */
+    public CompletableFuture<Void> 
createZone(DistributionZoneConfigurationParameters distributionZoneCfg) {
+        Objects.requireNonNull(distributionZoneCfg, "Distribution zone 
configuration is null.");
+
+        if (!busyLock.enterBusy()) {
+            throw new IgniteException(new NodeStoppingException());
+        }
+
+        try {
+            return zonesConfiguration.change(zonesChange -> 
zonesChange.changeDistributionZones(zonesListChange -> {
+                try {
+                    zonesListChange.create(distributionZoneCfg.name(), 
zoneChange -> {
+                        if (distributionZoneCfg.dataNodesAutoAdjust() == null) 
{
+                            
zoneChange.changeDataNodesAutoAdjust(Integer.MAX_VALUE);
+                        } else {
+                            
zoneChange.changeDataNodesAutoAdjust(distributionZoneCfg.dataNodesAutoAdjust());
+                        }
+
+                        if (distributionZoneCfg.dataNodesAutoAdjustScaleUp() 
== null) {
+                            
zoneChange.changeDataNodesAutoAdjustScaleUp(Integer.MAX_VALUE);
+                        } else {
+                            zoneChange.changeDataNodesAutoAdjustScaleUp(
+                                    
distributionZoneCfg.dataNodesAutoAdjustScaleUp());
+                        }
+
+                        if (distributionZoneCfg.dataNodesAutoAdjustScaleDown() 
== null) {
+                            
zoneChange.changeDataNodesAutoAdjustScaleDown(Integer.MAX_VALUE);
+                        } else {
+                            
zoneChange.changeDataNodesAutoAdjustScaleDown(distributionZoneCfg.dataNodesAutoAdjustScaleDown());
+                        }
+
+                        int intZoneId = zonesChange.globalIdCounter() + 1;
+                        zonesChange.changeGlobalIdCounter(intZoneId);
+
+                        zoneChange.changeZoneId(intZoneId);
+                    });
+                } catch (IllegalArgumentException e) {
+                    throw new 
DistributionZoneAlreadyExistsException(distributionZoneCfg.name(), e);
+                } catch (Exception e) {
+                    throw new IgniteInternalException(UNEXPECTED_ERR, 
distributionZoneCfg.name(), e);
+                }
+            }));
+        } finally {
+            busyLock.leaveBusy();
+        }
+    }
+
+    /**
+     * Alters a distribution zone.
+     *
+     * @param name Distribution zone name.
+     * @param distributionZoneCfg Distribution zone configuration.
+     * @return Future representing pending completion of the operation.
+     */
+    public CompletableFuture<Void> alterZone(String name, 
DistributionZoneConfigurationParameters distributionZoneCfg) {
+        Objects.requireNonNull(name, "Distribution zone name is null.");
+        Objects.requireNonNull(distributionZoneCfg, "Distribution zone 
configuration is null.");
+
+        if (!busyLock.enterBusy()) {
+            throw new IgniteException(new NodeStoppingException());
+        }
+
+        try {
+            return zonesConfiguration.change(zonesChange -> 
zonesChange.changeDistributionZones(zonesListChange -> {
+                NamedListChange<DistributionZoneView, DistributionZoneChange> 
renameChange;
+
+                try {
+                    renameChange = zonesListChange
+                            .rename(name, distributionZoneCfg.name());
+                } catch (IllegalArgumentException e) {
+                    throw new DistributionZoneRenameException(name, 
distributionZoneCfg.name(), e);
+                } catch (Exception e) {
+                    throw new IgniteInternalException(UNEXPECTED_ERR, 
distributionZoneCfg.name(), e);
+                }
+
+                try {
+                    renameChange
+                            .update(
+                                    distributionZoneCfg.name(), zoneChange -> {
+                                        if 
(distributionZoneCfg.dataNodesAutoAdjust() != null) {
+                                            
zoneChange.changeDataNodesAutoAdjust(distributionZoneCfg.dataNodesAutoAdjust());
+                                            
zoneChange.changeDataNodesAutoAdjustScaleUp(Integer.MAX_VALUE);
+                                            
zoneChange.changeDataNodesAutoAdjustScaleDown(Integer.MAX_VALUE);
+                                        }
+
+                                        if 
(distributionZoneCfg.dataNodesAutoAdjustScaleUp() != null) {
+                                            
zoneChange.changeDataNodesAutoAdjustScaleUp(
+                                                    
distributionZoneCfg.dataNodesAutoAdjustScaleUp());
+                                            
zoneChange.changeDataNodesAutoAdjust(Integer.MAX_VALUE);
+                                        }
+
+                                        if 
(distributionZoneCfg.dataNodesAutoAdjustScaleDown() != null) {
+                                            
zoneChange.changeDataNodesAutoAdjustScaleDown(
+                                                    
distributionZoneCfg.dataNodesAutoAdjustScaleDown());
+                                            
zoneChange.changeDataNodesAutoAdjust(Integer.MAX_VALUE);
+                                        }
+                                    });
+                } catch (IllegalArgumentException e) {
+                    throw new 
DistributionZoneNotFoundException(distributionZoneCfg.name(), e);
+                } catch (Exception e) {
+                    throw new IgniteInternalException(UNEXPECTED_ERR, 
distributionZoneCfg.name(), e);
+                }
+            }));
+        } finally {
+            busyLock.leaveBusy();
+        }
+    }
+
+    /**
+     * Drops a distribution zone with the name specified.
+     *
+     * @param name Distribution zone name.
+     * @return Future representing pending completion of the operation.
+     */
+    public CompletableFuture<Void> dropZone(String name) {
+        Objects.requireNonNull(name, "Distribution zone name is null.");
+
+        if (!busyLock.enterBusy()) {
+            throw new IgniteException(new NodeStoppingException());
+        }
+
+        try {
+            return zonesConfiguration.change(zonesChange -> 
zonesChange.changeDistributionZones(zonesListChange -> {
+                DistributionZoneView view = zonesListChange.get(name);
+
+                if (view == null) {
+                    throw new DistributionZoneNotFoundException(name);
+                }
+
+                zonesListChange.delete(name);
+            }));
+        } finally {
+            busyLock.leaveBusy();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void start() {
+
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void stop() throws Exception {
+
+    }
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZoneConfigurationSchema.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZoneConfigurationSchema.java
new file mode 100644
index 0000000000..c5dfaa6257
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZoneConfigurationSchema.java
@@ -0,0 +1,55 @@
+/*
+ * 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.configuration;
+
+import org.apache.ignite.configuration.annotation.Config;
+import org.apache.ignite.configuration.annotation.InjectedName;
+import org.apache.ignite.configuration.annotation.Value;
+import org.apache.ignite.configuration.validation.Immutable;
+import org.apache.ignite.configuration.validation.Range;
+
+/**
+ * Distribution zone configuration schema class.
+ */
+@Config
+public class DistributionZoneConfigurationSchema {
+    /** Zone name. */
+    @InjectedName
+    public String name;
+
+    /** Integer zone id. */
+    @Immutable
+    @Range(min = 1)
+    @Value(hasDefault = true)
+    public int zoneId = 1;
+
+    /** Timeout in seconds between node added or node left topology event 
itself and data nodes switch. */
+    @Range(min = 0)
+    @Value(hasDefault = true)
+    public int dataNodesAutoAdjust = Integer.MAX_VALUE;
+
+    /** Timeout in seconds between node added topology event itself and data 
nodes switch. */
+    @Range(min = 0)
+    @Value(hasDefault = true)
+    public int dataNodesAutoAdjustScaleUp = Integer.MAX_VALUE;
+
+    /** Timeout in seconds between node left topology event itself and data 
nodes switch. */
+    @Range(min = 0)
+    @Value(hasDefault = true)
+    public int dataNodesAutoAdjustScaleDown = Integer.MAX_VALUE;
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationSchema.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationSchema.java
new file mode 100644
index 0000000000..d1be021425
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationSchema.java
@@ -0,0 +1,37 @@
+/*
+ * 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.configuration;
+
+import org.apache.ignite.configuration.annotation.ConfigurationRoot;
+import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.configuration.annotation.NamedConfigValue;
+import org.apache.ignite.configuration.annotation.Value;
+
+/**
+ * Distribution zones configuration schema.
+ */
+@ConfigurationRoot(rootName = "zone", type = ConfigurationType.DISTRIBUTED)
+public class DistributionZonesConfigurationSchema {
+    /** Global integer id counter. Used as an auto-increment counter to 
generate integer identifiers for distribution zone. */
+    @Value(hasDefault = true)
+    public int globalIdCounter = 0;
+
+    /** List of configured distribution zones. */
+    @NamedConfigValue
+    public DistributionZoneConfigurationSchema distributionZones;
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneAlreadyExistsException.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneAlreadyExistsException.java
new file mode 100644
index 0000000000..13e2ff5ea5
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneAlreadyExistsException.java
@@ -0,0 +1,51 @@
+/*
+ * 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.exception;
+
+import static 
org.apache.ignite.lang.ErrorGroups.DistributionZones.ZONE_ALREADY_EXISTS_ERR;
+
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteInternalException;
+
+/**
+ * This exception is thrown when a new distribution zone failed to be created,
+ * because a distribution zone with same name already exists.
+ */
+public class DistributionZoneAlreadyExistsException extends 
IgniteInternalException {
+    /**
+     * The constructor.
+     *
+     * @param zoneName Zone name.
+     * @param cause Optional nested exception (can be {@code null}).
+     */
+    public DistributionZoneAlreadyExistsException(String zoneName, Throwable 
cause) {
+        super(ZONE_ALREADY_EXISTS_ERR, "Distribution zone already exists 
[zoneName=" + zoneName + ']', cause);
+    }
+
+    /**
+     * The constructor is used for creating an exception instance that is 
thrown from a remote server.
+     *
+     * @param traceId Trace id.
+     * @param code Error code.
+     * @param message Error message.
+     * @param cause Cause exception.
+     */
+    public DistributionZoneAlreadyExistsException(UUID traceId, int code, 
String message, Throwable cause) {
+        super(traceId, code, message, cause);
+    }
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneNotFoundException.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneNotFoundException.java
new file mode 100644
index 0000000000..a12853fbe9
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneNotFoundException.java
@@ -0,0 +1,60 @@
+/*
+ * 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.exception;
+
+import static 
org.apache.ignite.lang.ErrorGroups.DistributionZones.ZONE_NOT_FOUND_ERR;
+
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteInternalException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Exception is thrown when appropriate distribution zone can`t be found.
+ */
+public class DistributionZoneNotFoundException extends IgniteInternalException 
{
+    /**
+     * The constructor.
+     *
+     * @param zoneName Zone name.
+     */
+    public DistributionZoneNotFoundException(String zoneName) {
+        this("Distribution zone is not found [zoneName=" + zoneName + ']', 
null);
+    }
+
+    /**
+     * The constructor.
+     *
+     * @param zoneName Zone name.
+     * @param cause Optional nested exception (can be {@code null}).
+     */
+    public DistributionZoneNotFoundException(String zoneName, @Nullable 
Throwable cause) {
+        super(ZONE_NOT_FOUND_ERR, "Distribution zone is not found [zoneName=" 
+ zoneName + ']', cause);
+    }
+
+    /**
+     * The constructor is used for creating an exception instance that is 
thrown from a remote server.
+     *
+     * @param traceId Trace id.
+     * @param code Error code.
+     * @param message Error message.
+     * @param cause Cause exception.
+     */
+    public DistributionZoneNotFoundException(UUID traceId, int code, String 
message, Throwable cause) {
+        super(traceId, code, message, cause);
+    }
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneRenameException.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneRenameException.java
new file mode 100644
index 0000000000..ff51eae889
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/exception/DistributionZoneRenameException.java
@@ -0,0 +1,51 @@
+/*
+ * 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.exception;
+
+import static 
org.apache.ignite.lang.ErrorGroups.DistributionZones.ZONE_RENAME_ERR;
+
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteInternalException;
+
+/**
+ * This exception is thrown when a distribution zone with old name doesn't 
exist or a distribution zone with new name already exists.
+ */
+public class DistributionZoneRenameException extends IgniteInternalException {
+    /**
+     * The constructor.
+     *
+     * @param oldName Old name.
+     * @param newName New name.
+     */
+    public DistributionZoneRenameException(String oldName, String newName, 
Throwable cause) {
+        super(ZONE_RENAME_ERR, "Distribution zone with old name doesn't exist 
or "
+                + "distribution zone with new name already exists [oldName=" + 
oldName + "newName=" + newName + ']', cause);
+    }
+
+    /**
+     * The constructor is used for creating an exception instance that is 
thrown from a remote server.
+     *
+     * @param traceId Trace id.
+     * @param code Error code.
+     * @param message Error message.
+     * @param cause Cause exception.
+     */
+    public DistributionZoneRenameException(UUID traceId, int code, String 
message, Throwable cause) {
+        super(traceId, code, message, cause);
+    }
+}
diff --git 
a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneConfigurationParametersTest.java
 
b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneConfigurationParametersTest.java
new file mode 100644
index 0000000000..09889cd752
--- /dev/null
+++ 
b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneConfigurationParametersTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for {@link DistributionZoneConfigurationParameters}.
+ */
+class DistributionZoneConfigurationParametersTest {
+    private static final String ZONE_NAME = "zone1";
+
+    @Test
+    public void testDefaultValues() {
+        DistributionZoneConfigurationParameters zoneCfg = new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).build();
+
+        assertEquals(ZONE_NAME, zoneCfg.name());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjust());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleDown());
+    }
+
+    @Test
+    public void testAutoAdjust() {
+        DistributionZoneConfigurationParameters zoneCfg = new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                .dataNodesAutoAdjust(100)
+                .build();
+
+        assertEquals(ZONE_NAME, zoneCfg.name());
+        assertEquals(100, zoneCfg.dataNodesAutoAdjust());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleDown());
+    }
+
+    @Test
+    public void testAutoAdjustScaleUp() {
+        DistributionZoneConfigurationParameters zoneCfg = new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                .dataNodesAutoAdjustScaleUp(100)
+                .build();
+
+        assertEquals(ZONE_NAME, zoneCfg.name());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjust());
+        assertEquals(100, zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleDown());
+    }
+
+    @Test
+    public void testAutoAdjustScaleDown() {
+        DistributionZoneConfigurationParameters zoneCfg = new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                .dataNodesAutoAdjustScaleDown(100)
+                .build();
+
+        assertEquals(ZONE_NAME, zoneCfg.name());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjust());
+        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertEquals(100, zoneCfg.dataNodesAutoAdjustScaleDown());
+    }
+
+    @Test
+    public void testIncompatibleValues1() {
+        assertThrows(IllegalArgumentException.class,
+                () -> new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .dataNodesAutoAdjust(1)
+                        .dataNodesAutoAdjustScaleUp(1)
+                        .build());
+    }
+
+    @Test
+    public void testIncompatibleValues2() {
+        assertThrows(IllegalArgumentException.class,
+                () -> new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .dataNodesAutoAdjust(1)
+                        .dataNodesAutoAdjustScaleDown(1)
+                        .build());
+    }
+
+    @Test
+    public void testNullName() {
+        assertThrows(IllegalArgumentException.class,
+                () -> new 
DistributionZoneConfigurationParameters.Builder(null));
+    }
+
+    @Test
+    public void testEmptyName() {
+        assertThrows(IllegalArgumentException.class,
+                () -> new DistributionZoneConfigurationParameters.Builder(""));
+    }
+}
diff --git 
a/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java
 
b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java
new file mode 100644
index 0000000000..4681a27678
--- /dev/null
+++ 
b/modules/distribution-zones/src/test/java/org/apache/ignite/internal/distributionzones/DistributionZoneManagerTest.java
@@ -0,0 +1,442 @@
+/*
+ * 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.configuration.annotation.ConfigurationType.DISTRIBUTED;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.configuration.ConfigurationChangeException;
+import org.apache.ignite.internal.configuration.ConfigurationRegistry;
+import 
org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
+import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZoneConfiguration;
+import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZonesConfiguration;
+import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneAlreadyExistsException;
+import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneNotFoundException;
+import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneRenameException;
+import org.apache.ignite.internal.testframework.IgniteAbstractTest;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for distribution zone manager.
+ */
+class DistributionZoneManagerTest extends IgniteAbstractTest {
+    private static final String ZONE_NAME = "zone1";
+
+    private static final String NEW_ZONE_NAME = "zone2";
+
+    private final ConfigurationRegistry registry = new ConfigurationRegistry(
+            List.of(DistributionZonesConfiguration.KEY),
+            Map.of(),
+            new TestConfigurationStorage(DISTRIBUTED),
+            List.of(),
+            List.of()
+    );
+
+    private DistributionZoneManager distributionZoneManager;
+
+    @BeforeEach
+    public void setUp() {
+        registry.start();
+
+        registry.initializeDefaults();
+
+        DistributionZonesConfiguration zonesConfiguration = 
registry.getConfiguration(DistributionZonesConfiguration.KEY);
+        distributionZoneManager = new 
DistributionZoneManager(zonesConfiguration);
+    }
+
+    @AfterEach
+    public void tearDown() throws Exception {
+        registry.stop();
+    }
+
+    @Test
+    public void testCreateZoneWithAutoAdjust() throws Exception {
+        distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).dataNodesAutoAdjust(100).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(ZONE_NAME, zone1.name().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(100, zone1.dataNodesAutoAdjust().value());
+    }
+
+    @Test
+    public void testCreateZoneWithAutoAdjustScaleUp() throws Exception {
+        distributionZoneManager.createZone(
+                new DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .dataNodesAutoAdjustScaleUp(100).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(ZONE_NAME, zone1.name().value());
+        assertEquals(100, zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(Integer.MAX_VALUE, zone1.dataNodesAutoAdjust().value());
+
+        distributionZoneManager.dropZone(ZONE_NAME).get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNull(zone1);
+    }
+
+    @Test
+    public void testCreateZoneWithAutoAdjustScaleDown() throws Exception {
+        distributionZoneManager.createZone(
+                new DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .dataNodesAutoAdjustScaleDown(200).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(ZONE_NAME, zone1.name().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(200, zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(Integer.MAX_VALUE, zone1.dataNodesAutoAdjust().value());
+
+        distributionZoneManager.dropZone(ZONE_NAME).get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNull(zone1);
+    }
+
+    @Test
+    public void testCreateZoneIfExists() throws Exception {
+        Exception e = null;
+
+        distributionZoneManager.createZone(
+                new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).dataNodesAutoAdjust(100).build()
+        ).get(5, TimeUnit.SECONDS);
+
+        try {
+            distributionZoneManager.createZone(
+                    new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).dataNodesAutoAdjust(100).build()
+            ).get(5, TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause().getCause() instanceof 
DistributionZoneAlreadyExistsException, e.toString());
+    }
+
+    @Test
+    public void testDropZoneIfNotExists() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.dropZone(ZONE_NAME).get(5, 
TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause().getCause() instanceof 
DistributionZoneNotFoundException, e.toString());
+    }
+
+    @Test
+    public void testUpdateZone() throws Exception {
+        distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).dataNodesAutoAdjust(100).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(ZONE_NAME, zone1.name().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(100, zone1.dataNodesAutoAdjust().value());
+
+
+        distributionZoneManager.alterZone(ZONE_NAME, new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        
.dataNodesAutoAdjustScaleUp(200).dataNodesAutoAdjustScaleDown(300).build())
+                .get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(200, zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(300, zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(Integer.MAX_VALUE, zone1.dataNodesAutoAdjust().value());
+
+
+        distributionZoneManager.alterZone(ZONE_NAME, new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .dataNodesAutoAdjustScaleUp(400).build())
+                .get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(400, zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(300, zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(Integer.MAX_VALUE, zone1.dataNodesAutoAdjust().value());
+
+
+        distributionZoneManager.alterZone(ZONE_NAME, new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .dataNodesAutoAdjust(500).build())
+                .get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNotNull(zone1);
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(Integer.MAX_VALUE, 
zone1.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(500, zone1.dataNodesAutoAdjust().value());
+    }
+
+    @Test
+    public void testRenameZone() throws Exception {
+        distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).dataNodesAutoAdjust(100).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        distributionZoneManager.alterZone(ZONE_NAME,
+                        new 
DistributionZoneConfigurationParameters.Builder(NEW_ZONE_NAME).build())
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        DistributionZoneConfiguration zone2 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY)
+                .distributionZones()
+                .get(NEW_ZONE_NAME);
+
+        assertNull(zone1);
+        assertNotNull(zone2);
+        assertEquals(NEW_ZONE_NAME, zone2.name().value());
+        assertEquals(Integer.MAX_VALUE, 
zone2.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(Integer.MAX_VALUE, 
zone2.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(100, zone2.dataNodesAutoAdjust().value());
+    }
+
+    @Test
+    public void testUpdateAndRenameZone() throws Exception {
+        distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).dataNodesAutoAdjust(100).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        distributionZoneManager.alterZone(ZONE_NAME,
+                        new 
DistributionZoneConfigurationParameters.Builder(NEW_ZONE_NAME).dataNodesAutoAdjust(400).build())
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        DistributionZoneConfiguration zone2 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY)
+                .distributionZones()
+                .get(NEW_ZONE_NAME);
+
+        assertNull(zone1);
+        assertNotNull(zone2);
+        assertEquals(NEW_ZONE_NAME, zone2.name().value());
+        assertEquals(Integer.MAX_VALUE, 
zone2.dataNodesAutoAdjustScaleUp().value());
+        assertEquals(Integer.MAX_VALUE, 
zone2.dataNodesAutoAdjustScaleDown().value());
+        assertEquals(400, zone2.dataNodesAutoAdjust().value());
+    }
+
+    @Test
+    public void testAlterZoneRename1() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.alterZone(ZONE_NAME, new 
DistributionZoneConfigurationParameters.Builder(NEW_ZONE_NAME)
+                    .dataNodesAutoAdjust(100).build()).get(5, 
TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause().getCause() instanceof 
DistributionZoneRenameException, e.toString());
+    }
+
+    @Test
+    public void testAlterZoneRename2() throws Exception {
+        Exception e = null;
+
+        distributionZoneManager.createZone(new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                .dataNodesAutoAdjust(100).build()).get(5, TimeUnit.SECONDS);
+
+        distributionZoneManager.createZone(new 
DistributionZoneConfigurationParameters.Builder(NEW_ZONE_NAME)
+                .dataNodesAutoAdjust(100).build()).get(5, TimeUnit.SECONDS);
+
+        try {
+            distributionZoneManager.alterZone(ZONE_NAME, new 
DistributionZoneConfigurationParameters.Builder(NEW_ZONE_NAME)
+                    .dataNodesAutoAdjust(100).build()).get(5, 
TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause().getCause() instanceof 
DistributionZoneRenameException, e.toString());
+    }
+
+    @Test
+    public void testAlterZoneIfExists() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.alterZone(ZONE_NAME, new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                    .dataNodesAutoAdjust(100).build()).get(5, 
TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause().getCause() instanceof 
DistributionZoneNotFoundException, e.toString());
+    }
+
+    @Test
+    public void testCreateZoneWithWrongAutoAdjust() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.createZone(new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                    .dataNodesAutoAdjust(-10).build()).get(5, 
TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause() instanceof ConfigurationChangeException, 
e.toString());
+    }
+
+    @Test
+    public void testCreateZoneWithWrongSeparatedAutoAdjust1() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.createZone(new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                    
.dataNodesAutoAdjustScaleUp(-100).dataNodesAutoAdjustScaleDown(1).build()).get(5,
 TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause() instanceof ConfigurationChangeException, 
e.toString());
+    }
+
+    @Test
+    public void testCreateZoneWithWrongSeparatedAutoAdjust2() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.createZone(new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                    
.dataNodesAutoAdjustScaleUp(1).dataNodesAutoAdjustScaleDown(-100).build()).get(5,
 TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e.getCause() instanceof ConfigurationChangeException, 
e.toString());
+    }
+
+    @Test
+    public void testCreateZoneWithNullConfiguration() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.createZone(null).get(5, TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e instanceof NullPointerException, e.toString());
+        assertEquals("Distribution zone configuration is null.", 
e.getMessage(), e.toString());
+    }
+
+    @Test
+    public void testAlterZoneWithNullName() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.alterZone(null, new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).build())
+                    .get(5, TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e instanceof NullPointerException, e.toString());
+        assertEquals("Distribution zone name is null.", e.getMessage(), 
e.toString());
+    }
+
+    @Test
+    public void testAlterZoneWithNullConfiguration() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.alterZone(ZONE_NAME, null)
+                    .get(5, TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e instanceof NullPointerException, e.toString());
+        assertEquals("Distribution zone configuration is null.", 
e.getMessage(), e.toString());
+    }
+
+    @Test
+    public void testDropZoneWithNullName() {
+        Exception e = null;
+
+        try {
+            distributionZoneManager.dropZone(null)
+                    .get(5, TimeUnit.SECONDS);
+        } catch (Exception e0) {
+            e = e0;
+        }
+
+        assertTrue(e != null);
+        assertTrue(e instanceof NullPointerException, e.toString());
+        assertEquals("Distribution zone name is null.", e.getMessage(), 
e.toString());
+    }
+}
diff --git 
a/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs
 
b/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs
index 169c8bc5d2..9ed77fe7af 100644
--- 
a/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs
+++ 
b/modules/platforms/dotnet/Apache.Ignite.Internal.Generators/ErrorGroupsGenerator.cs
@@ -58,7 +58,7 @@ namespace Apache.Ignite.Internal.Generators
             // ErrorGroup TX_ERR_GROUP = ErrorGroup.newGroup("TX", 7);
             var javaErrorGroups = Regex.Matches(
                     javaErrorGroupsText,
-                    @"public static class ([A-Za-z]+) {\s+/\*\*.*?\*/\s+public 
static final ErrorGroup ([\w_]+)_ERR_GROUP = ErrorGroup.newGroup\(""([A-Z]+)"", 
(\d+)",
+                    @"public static class ([A-Za-z]+) {\s+/\*\*.*?\*/\s+public 
static final ErrorGroup ([\w_]+)_ERR_GROUP = ErrorGroup.newGroup\(""([\w_]+)"", 
(\d+)",
                     RegexOptions.Singleline | RegexOptions.CultureInvariant)
                 .Cast<Match>()
                 .Select(x => (ClassName: x.Groups[1].Value, GroupName: 
x.Groups[2].Value, ShortGroupName: x.Groups[3].Value, Code: 
int.Parse(x.Groups[4].Value, CultureInfo.InvariantCulture)))
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/ErrorGroupTests.cs 
b/modules/platforms/dotnet/Apache.Ignite.Tests/ErrorGroupTests.cs
index 1b1fd9a9b5..fb62ee9c0f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/ErrorGroupTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/ErrorGroupTests.cs
@@ -173,6 +173,10 @@ namespace Apache.Ignite.Tests
             Assert.AreEqual(8, ErrorGroups.Replicator.GroupCode);
             Assert.AreEqual("REP", ErrorGroups.Replicator.GroupName);
             Assert.AreEqual("REP", ErrorGroups.GetGroupName(8));
+
+            Assert.AreEqual(10, ErrorGroups.DistributionZones.GroupCode);
+            Assert.AreEqual("DISTRZONES", 
ErrorGroups.DistributionZones.GroupName);
+            Assert.AreEqual("DISTRZONES", ErrorGroups.GetGroupName(10));
         }
 
         [Test]
diff --git a/modules/runner/build.gradle b/modules/runner/build.gradle
index c88d6665f5..f4a7cffc9f 100644
--- a/modules/runner/build.gradle
+++ b/modules/runner/build.gradle
@@ -51,6 +51,7 @@ dependencies {
     implementation project(':ignite-cluster-management')
     implementation project(':ignite-metrics')
     implementation project(':ignite-replicator')
+    implementation project(':ignite-distribution-zones')
     implementation libs.jetbrains.annotations
     implementation libs.micronaut.inject
     implementation libs.micronaut.validation
diff --git a/modules/runner/pom.xml b/modules/runner/pom.xml
index 9628a668b8..ac460eefd3 100644
--- a/modules/runner/pom.xml
+++ b/modules/runner/pom.xml
@@ -123,6 +123,11 @@
             <artifactId>ignite-metrics</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-distribution-zones</artifactId>
+        </dependency>
+
         <!-- 3rd party dependencies -->
         <dependency>
             <groupId>org.slf4j</groupId>
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index bee5d6a461..4afdfb0f44 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -57,6 +57,8 @@ import 
org.apache.ignite.internal.configuration.ServiceLoaderModulesProvider;
 import org.apache.ignite.internal.configuration.storage.ConfigurationStorage;
 import 
org.apache.ignite.internal.configuration.storage.DistributedConfigurationStorage;
 import 
org.apache.ignite.internal.configuration.storage.LocalConfigurationStorage;
+import org.apache.ignite.internal.distributionzones.DistributionZoneManager;
+import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZonesConfiguration;
 import org.apache.ignite.internal.hlc.HybridClock;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.index.IndexManager;
@@ -230,6 +232,8 @@ public class IgniteImpl implements Ignite {
     /** Metric manager. */
     private final MetricManager metricManager;
 
+    private final DistributionZoneManager distributionZoneManager;
+
     /** Creator for volatile {@link 
org.apache.ignite.internal.raft.storage.LogStorageFactory} instances. */
     private final VolatileLogStorageFactoryCreator 
volatileLogStorageFactoryCreator;
 
@@ -436,6 +440,11 @@ public class IgniteImpl implements Ignite {
                 sql,
                 () -> cmgMgr.clusterState().thenApply(s -> 
s.clusterTag().clusterId())
         );
+
+        DistributionZonesConfiguration zonesConfiguration = 
clusterCfgMgr.configurationRegistry()
+                .getConfiguration(DistributionZonesConfiguration.KEY);
+
+        distributionZoneManager = new 
DistributionZoneManager(zonesConfiguration);
     }
 
     private RestComponent createRestComponent(String name) {
@@ -544,6 +553,7 @@ public class IgniteImpl implements Ignite {
                                     metaStorageMgr,
                                     clusterCfgMgr,
                                     metricManager,
+                                    distributionZoneManager,
                                     computeComponent,
                                     replicaMgr,
                                     txManager,
@@ -794,4 +804,9 @@ public class IgniteImpl implements Ignite {
     public ClusterNode node() {
         return clusterSvc.topologyService().localMember();
     }
+
+    @TestOnly
+    public DistributionZoneManager distributionZoneManager() {
+        return distributionZoneManager;
+    }
 }
diff --git a/parent/pom.xml b/parent/pom.xml
index e698c6fabb..ab3c4bca9f 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -297,6 +297,12 @@
                 <version>${project.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>org.apache.ignite</groupId>
+                <artifactId>ignite-distribution-zones</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
             <dependency>
                 <groupId>org.apache.ignite</groupId>
                 <artifactId>ignite-cluster-management</artifactId>
diff --git a/pom.xml b/pom.xml
index ce543b9a99..a91a0c2fcd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -54,6 +54,7 @@
         <module>modules/configuration-annotation-processor</module>
         <module>modules/configuration-api</module>
         <module>modules/core</module>
+        <module>modules/distribution-zones</module>
         <module>modules/file-io</module>
         <module>modules/index</module>
         <module>modules/jacoco-report</module>
diff --git a/settings.gradle b/settings.gradle
index 5d722e1a26..ff78663c9d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -64,6 +64,7 @@ include(':packaging-cli')
 include(':packaging-db')
 include(':packaging')
 include(':ignite-replicator')
+include(':ignite-distribution-zones')
 
 project(":ignite-examples").projectDir = file('examples')
 project(":ignite-page-memory").projectDir = file('modules/page-memory')
@@ -113,6 +114,7 @@ project(":ignite-replicator").projectDir = 
file('modules/replicator')
 project(":packaging-cli").projectDir = file('packaging/cli')
 project(":packaging-db").projectDir = file('packaging/db')
 project(":packaging").projectDir = file('packaging')
+project(":ignite-distribution-zones").projectDir = 
file('modules/distribution-zones')
 
 ext.isCiServer = System.getenv().containsKey("IGNITE_CI")
 

Reply via email to