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

sanpwc 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 f572c3fdef IGNITE-18952 The filter added as a configuration parameter 
of a Distribution zone (#1902)
f572c3fdef is described below

commit f572c3fdefd11309fe9a915de5f98fa6eaa62e85
Author: Mirza Aliev <[email protected]>
AuthorDate: Wed Apr 5 18:09:39 2023 +0400

    IGNITE-18952 The filter added as a configuration parameter of a 
Distribution zone (#1902)
---
 modules/distribution-zones/build.gradle            |   5 +
 .../DistributionZoneConfigurationParameters.java   |  34 +++-
 .../distributionzones/DistributionZoneManager.java |   8 +
 .../distributionzones/DistributionZonesUtil.java   |  23 +++
 .../DistributionZoneConfigurationSchema.java       |   8 +
 .../DistributionZonesConfigurationModule.java      |   8 +
 .../configuration/FilterValidator.java             |  48 ++++++
 ...esConfigurationModule.java => ValidFilter.java} |  31 ++--
 ...istributionZoneConfigurationParametersTest.java |  29 ++--
 .../DistributionZoneManagerTest.java               | 178 +++++++++++++++------
 10 files changed, 293 insertions(+), 79 deletions(-)

diff --git a/modules/distribution-zones/build.gradle 
b/modules/distribution-zones/build.gradle
index 1bc304835c..4cf22252bd 100644
--- a/modules/distribution-zones/build.gradle
+++ b/modules/distribution-zones/build.gradle
@@ -37,6 +37,11 @@ dependencies {
     implementation libs.jetbrains.annotations
     implementation libs.fastutil.core
     implementation libs.auto.service.annotations
+    implementation(libs.jsonpath.core) {
+        //IDEA test runner doesn't apply Gradle dependency resolve strategy, 
this is just not implemented
+        //So, exclude asm-core transitive dependency to protect of jar-hell.
+        exclude group: 'org.ow2.asm', module: 'asm'
+    }
 
     testImplementation libs.mockito.core
     testImplementation libs.mockito.junit
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
index 27796b7cd0..d30e331afc 100644
--- 
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
@@ -41,6 +41,9 @@ public class DistributionZoneConfigurationParameters {
     /** Number of zone partitions. */
     private final Integer partitions;
 
+    /** Nodes' filter. */
+    private final String filter;
+
     /**
      * The constructor.
      */
@@ -50,7 +53,8 @@ public class DistributionZoneConfigurationParameters {
             Integer partitions,
             Integer dataNodesAutoAdjust,
             Integer dataNodesAutoAdjustScaleUp,
-            Integer dataNodesAutoAdjustScaleDown
+            Integer dataNodesAutoAdjustScaleDown,
+            String filter
     ) {
         this.name = name;
         this.replicas = replicas;
@@ -58,6 +62,7 @@ public class DistributionZoneConfigurationParameters {
         this.dataNodesAutoAdjust = dataNodesAutoAdjust;
         this.dataNodesAutoAdjustScaleUp = dataNodesAutoAdjustScaleUp;
         this.dataNodesAutoAdjustScaleDown = dataNodesAutoAdjustScaleDown;
+        this.filter = filter;
     }
 
     /**
@@ -96,7 +101,6 @@ public class DistributionZoneConfigurationParameters {
         return dataNodesAutoAdjustScaleDown;
     }
 
-
     /**
      * Gets number of zone replicas.
      *
@@ -115,6 +119,15 @@ public class DistributionZoneConfigurationParameters {
         return partitions;
     }
 
+    /**
+     * Gets nodes' filter.
+     *
+     * @return Nodes' filter.
+     */
+    public String filter() {
+        return filter;
+    }
+
     /**
      * Builder for distribution zone configuration.
      */
@@ -137,6 +150,9 @@ public class DistributionZoneConfigurationParameters {
         /** Number of zone partitions. */
         private Integer partitions;
 
+        /* Nodes' filter. */
+        private String filter;
+
         /**
          * Constructor.
          *
@@ -211,6 +227,17 @@ public class DistributionZoneConfigurationParameters {
             return this;
         }
 
+        /**
+         * Sets nodes' filter.
+         *
+         * @param filter Nodes' filter.
+         * @return This instance.
+         */
+        public Builder filter(String filter) {
+            this.filter = filter;
+
+            return this;
+        }
 
         /**
          * Builds the distribution zone configuration.
@@ -234,7 +261,8 @@ public class DistributionZoneConfigurationParameters {
                     partitions,
                     dataNodesAutoAdjust,
                     dataNodesAutoAdjustScaleUp,
-                    dataNodesAutoAdjustScaleDown
+                    dataNodesAutoAdjustScaleDown,
+                    filter
             );
         }
     }
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
index acb0b31747..791caeb4ca 100644
--- 
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
@@ -280,6 +280,10 @@ public class DistributionZoneManager implements 
IgniteComponent {
                             
zoneChange.changeReplicas(distributionZoneCfg.replicas());
                         }
 
+                        if (distributionZoneCfg.filter() != null) {
+                            
zoneChange.changeFilter(distributionZoneCfg.filter());
+                        }
+
                         if (distributionZoneCfg.dataNodesAutoAdjust() == null) 
{
                             
zoneChange.changeDataNodesAutoAdjust(INFINITE_TIMER_VALUE);
                         } else {
@@ -740,6 +744,10 @@ public class DistributionZoneManager implements 
IgniteComponent {
             zoneChange.changePartitions(distributionZoneCfg.partitions());
         }
 
+        if (distributionZoneCfg.filter() != null) {
+            zoneChange.changeFilter(distributionZoneCfg.filter());
+        }
+
         if (distributionZoneCfg.dataNodesAutoAdjust() != null) {
             
zoneChange.changeDataNodesAutoAdjust(distributionZoneCfg.dataNodesAutoAdjust());
             zoneChange.changeDataNodesAutoAdjustScaleUp(INFINITE_TIMER_VALUE);
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZonesUtil.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZonesUtil.java
index 488fd5479d..7b50953e5b 100644
--- 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZonesUtil.java
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/DistributionZonesUtil.java
@@ -29,6 +29,8 @@ import static 
org.apache.ignite.internal.metastorage.dsl.Operations.remove;
 import static org.apache.ignite.internal.util.ByteUtils.bytesToLong;
 import static org.apache.ignite.internal.util.ByteUtils.fromBytes;
 
+import com.jayway.jsonpath.InvalidPathException;
+import com.jayway.jsonpath.JsonPath;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
@@ -44,6 +46,7 @@ import 
org.apache.ignite.internal.metastorage.dsl.SimpleCondition;
 import org.apache.ignite.internal.metastorage.dsl.Update;
 import org.apache.ignite.internal.util.ByteUtils;
 import org.apache.ignite.lang.ByteArray;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Util class for Distribution Zones flow.
@@ -347,4 +350,24 @@ public class DistributionZonesUtil {
 
         throw new DistributionZoneNotFoundException(zoneId);
     }
+
+    /**
+     * Check if a passed filter is a valid {@link JsonPath} query.
+     *
+     * @param filter Filter.
+     * @return {@code null} if the passed filter is a valid filter, string 
with the error message otherwise.
+     */
+    public static @Nullable String validate(String filter) {
+        try {
+            JsonPath.compile(filter);
+        } catch (InvalidPathException e) {
+            if (e.getMessage() != null) {
+                return e.getMessage();
+            } else {
+                return "Unknown JsonPath compilation error.";
+            }
+        }
+
+        return null;
+    }
 }
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
index 1d6fbfa80d..b507a9d40c 100644
--- 
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
@@ -67,4 +67,12 @@ public class DistributionZoneConfigurationSchema {
     @Range(min = 0)
     @Value(hasDefault = true)
     public int dataNodesAutoAdjustScaleDown = INFINITE_TIMER_VALUE;
+
+    /**
+     * Filter to form nodes which must be included to data nodes of this zone.
+     * Default value is {@code $..*}, which is a {@link 
com.jayway.jsonpath.JsonPath} expression for including all attributes of nodes.
+     */
+    @ValidFilter
+    @Value(hasDefault = true)
+    public String filter = "$..*";
 }
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
index 3dae7fb885..9d4ad649a9 100644
--- 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
@@ -20,15 +20,23 @@ package 
org.apache.ignite.internal.distributionzones.configuration;
 import com.google.auto.service.AutoService;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 import org.apache.ignite.configuration.ConfigurationModule;
 import org.apache.ignite.configuration.RootKey;
 import org.apache.ignite.configuration.annotation.ConfigurationType;
+import org.apache.ignite.configuration.validation.Validator;
 
 /**
  * Configuration module for distribution zones configs.
  */
 @AutoService(ConfigurationModule.class)
 public class DistributionZonesConfigurationModule implements 
ConfigurationModule {
+    /** {@inheritDoc} */
+    @Override
+    public Set<Validator<?, ?>> validators() {
+        return Set.of(FilterValidator.INSTANCE);
+    }
+
     /** {@inheritDoc} */
     @Override
     public ConfigurationType type() {
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/FilterValidator.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/FilterValidator.java
new file mode 100644
index 0000000000..06d1b1ddfd
--- /dev/null
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/FilterValidator.java
@@ -0,0 +1,48 @@
+/*
+ * 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.validation.ValidationContext;
+import org.apache.ignite.configuration.validation.ValidationIssue;
+import org.apache.ignite.configuration.validation.Validator;
+import org.apache.ignite.internal.distributionzones.DistributionZonesUtil;
+
+/**
+ * Validator for a filter of a distribution zone.
+ */
+public class FilterValidator implements Validator<ValidFilter, String> {
+    /** Static instance. */
+    public static final FilterValidator INSTANCE = new FilterValidator();
+
+    /** {@inheritDoc} */
+    @Override
+    public void validate(ValidFilter annotation, ValidationContext<String> 
ctx) {
+        String filter = ctx.getNewValue();
+
+        String validationResult = DistributionZonesUtil.validate(filter);
+
+        if (validationResult != null) {
+            ctx.addIssue(
+                    new ValidationIssue(
+                            ctx.currentKey(),
+                            String.format("Failed to parse filter %s, the 
cause: %s", filter, validationResult)
+                    )
+            );
+        }
+    }
+}
diff --git 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/ValidFilter.java
similarity index 54%
copy from 
modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
copy to 
modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/ValidFilter.java
index 3dae7fb885..62efdcd921 100644
--- 
a/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/DistributionZonesConfigurationModule.java
+++ 
b/modules/distribution-zones/src/main/java/org/apache/ignite/internal/distributionzones/configuration/ValidFilter.java
@@ -17,27 +17,18 @@
 
 package org.apache.ignite.internal.distributionzones.configuration;
 
-import com.google.auto.service.AutoService;
-import java.util.Collection;
-import java.util.List;
-import org.apache.ignite.configuration.ConfigurationModule;
-import org.apache.ignite.configuration.RootKey;
-import org.apache.ignite.configuration.annotation.ConfigurationType;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.ignite.configuration.annotation.ConfigValue;
 
 /**
- * Configuration module for distribution zones configs.
+ * An annotation to check that the {@link 
DistributionZoneConfigurationSchema#filter} is a correct filter, that could be 
parsed.
+ *
+ * <p>Can be applied to a {@link ConfigValue}.
  */
-@AutoService(ConfigurationModule.class)
-public class DistributionZonesConfigurationModule implements 
ConfigurationModule {
-    /** {@inheritDoc} */
-    @Override
-    public ConfigurationType type() {
-        return ConfigurationType.DISTRIBUTED;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public Collection<RootKey<?, ?>> rootKeys() {
-        return List.of(DistributionZonesConfiguration.KEY);
-    }
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ValidFilter {
 }
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
index 09889cd752..28715b171d 100644
--- 
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
@@ -18,6 +18,7 @@
 package org.apache.ignite.internal.distributionzones;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import org.junit.jupiter.api.Test;
@@ -33,9 +34,9 @@ class DistributionZoneConfigurationParametersTest {
         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());
+        assertNull(zoneCfg.dataNodesAutoAdjust());
+        assertNull(zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertNull(zoneCfg.dataNodesAutoAdjustScaleDown());
     }
 
     @Test
@@ -46,8 +47,8 @@ class DistributionZoneConfigurationParametersTest {
 
         assertEquals(ZONE_NAME, zoneCfg.name());
         assertEquals(100, zoneCfg.dataNodesAutoAdjust());
-        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleUp());
-        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleDown());
+        assertNull(zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertNull(zoneCfg.dataNodesAutoAdjustScaleDown());
     }
 
     @Test
@@ -57,9 +58,9 @@ class DistributionZoneConfigurationParametersTest {
                 .build();
 
         assertEquals(ZONE_NAME, zoneCfg.name());
-        assertEquals(null, zoneCfg.dataNodesAutoAdjust());
+        assertNull(zoneCfg.dataNodesAutoAdjust());
         assertEquals(100, zoneCfg.dataNodesAutoAdjustScaleUp());
-        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleDown());
+        assertNull(zoneCfg.dataNodesAutoAdjustScaleDown());
     }
 
     @Test
@@ -69,11 +70,21 @@ class DistributionZoneConfigurationParametersTest {
                 .build();
 
         assertEquals(ZONE_NAME, zoneCfg.name());
-        assertEquals(null, zoneCfg.dataNodesAutoAdjust());
-        assertEquals(null, zoneCfg.dataNodesAutoAdjustScaleUp());
+        assertNull(zoneCfg.dataNodesAutoAdjust());
+        assertNull(zoneCfg.dataNodesAutoAdjustScaleUp());
         assertEquals(100, zoneCfg.dataNodesAutoAdjustScaleDown());
     }
 
+    @Test
+    public void testFilter() {
+        DistributionZoneConfigurationParameters zoneCfg = new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                .filter("['nodeAttributes'][?(@.['region'] == 'EU')]")
+                .build();
+
+        assertEquals(ZONE_NAME, zoneCfg.name());
+        assertEquals("['nodeAttributes'][?(@.['region'] == 'EU')]", 
zoneCfg.filter());
+    }
+
     @Test
     public void testIncompatibleValues1() {
         assertThrows(IllegalArgumentException.class,
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
index fd51c2806d..422640db6a 100644
--- 
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
@@ -21,46 +21,43 @@ import static 
org.apache.ignite.configuration.annotation.ConfigurationType.DISTR
 import static 
org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_ZONE_ID;
 import static 
org.apache.ignite.internal.distributionzones.DistributionZoneManager.DEFAULT_ZONE_NAME;
 import static 
org.apache.ignite.internal.distributionzones.DistributionZoneManager.INFINITE_TIMER_VALUE;
+import static 
org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause;
 import static org.hamcrest.MatcherAssert.assertThat;
 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.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
-import org.apache.ignite.configuration.NamedConfigurationTree;
-import org.apache.ignite.configuration.NamedListView;
 import 
org.apache.ignite.configuration.validation.ConfigurationValidationException;
 import org.apache.ignite.internal.configuration.ConfigurationRegistry;
 import 
org.apache.ignite.internal.configuration.storage.TestConfigurationStorage;
+import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
+import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
 import 
org.apache.ignite.internal.distributionzones.DistributionZoneConfigurationParameters.Builder;
 import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZoneConfiguration;
 import 
org.apache.ignite.internal.distributionzones.configuration.DistributionZonesConfiguration;
+import 
org.apache.ignite.internal.distributionzones.configuration.FilterValidator;
 import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneAlreadyExistsException;
 import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneBindTableException;
 import 
org.apache.ignite.internal.distributionzones.exception.DistributionZoneNotFoundException;
-import org.apache.ignite.internal.schema.configuration.TableChange;
-import org.apache.ignite.internal.schema.configuration.TableConfiguration;
-import org.apache.ignite.internal.schema.configuration.TableView;
 import org.apache.ignite.internal.schema.configuration.TablesConfiguration;
 import org.apache.ignite.internal.testframework.IgniteAbstractTest;
 import org.hamcrest.Matchers;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 
 /**
  * Tests for distribution zone manager.
  */
+@ExtendWith(ConfigurationExtension.class)
+@SuppressWarnings("ThrowableNotThrown")
 class DistributionZoneManagerTest extends IgniteAbstractTest {
     private static final String ZONE_NAME = "zone1";
 
@@ -68,7 +65,7 @@ class DistributionZoneManagerTest extends IgniteAbstractTest {
 
     private final ConfigurationRegistry registry = new ConfigurationRegistry(
             List.of(DistributionZonesConfiguration.KEY),
-            Set.of(),
+            Set.of(FilterValidator.INSTANCE),
             new TestConfigurationStorage(DISTRIBUTED),
             List.of(),
             List.of()
@@ -76,6 +73,7 @@ class DistributionZoneManagerTest extends IgniteAbstractTest {
 
     private DistributionZoneManager distributionZoneManager;
 
+    @InjectConfiguration("mock.tables.fooTable {}")
     private TablesConfiguration tablesConfiguration;
 
     @BeforeEach
@@ -84,18 +82,6 @@ class DistributionZoneManagerTest extends IgniteAbstractTest 
{
 
         registry.initializeDefaults();
 
-        tablesConfiguration = mock(TablesConfiguration.class);
-
-        NamedConfigurationTree<TableConfiguration, TableView, TableChange> 
tables = mock(NamedConfigurationTree.class);
-
-        when(tablesConfiguration.tables()).thenReturn(tables);
-
-        NamedListView<TableView> value = mock(NamedListView.class);
-
-        when(tables.value()).thenReturn(value);
-
-        when(value.namedListKeys()).thenReturn(new ArrayList<>());
-
         DistributionZonesConfiguration zonesConfiguration = 
registry.getConfiguration(DistributionZonesConfiguration.KEY);
 
         distributionZoneManager = new DistributionZoneManager(
@@ -200,7 +186,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof DistributionZoneAlreadyExistsException,
                 "Unexpected type of exception (requires 
DistributionZoneAlreadyExistsException): " + e
@@ -376,7 +362,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof DistributionZoneNotFoundException,
                 "Unexpected type of exception (requires 
DistributionZoneRenameException): " + e
@@ -402,7 +388,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof DistributionZoneAlreadyExistsException,
                 "Unexpected type of exception (requires 
DistributionZoneRenameException): " + e
@@ -422,7 +408,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof DistributionZoneNotFoundException,
                 "Unexpected type of exception (requires 
DistributionZoneNotFoundException): " + e
@@ -442,7 +428,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof ConfigurationValidationException,
                 "Unexpected type of exception (requires 
ConfigurationValidationException): " + e
@@ -462,7 +448,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof ConfigurationValidationException,
                 "Unexpected type of exception (requires 
ConfigurationValidationException): " + e
@@ -482,7 +468,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof ConfigurationValidationException,
                 "Unexpected type of exception (requires 
ConfigurationValidationException): " + e
@@ -501,7 +487,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -525,7 +511,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -549,7 +535,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -573,7 +559,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -646,7 +632,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof DistributionZoneBindTableException,
                 "Unexpected type of exception (requires 
DistributionZoneBindTableException): " + e
@@ -667,7 +653,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -693,7 +679,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -719,7 +705,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -743,7 +729,7 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
             e = e0;
         }
 
-        assertTrue(e != null, "Expected exception was not thrown.");
+        assertNotNull(e, "Expected exception was not thrown.");
         assertTrue(
                 e.getCause() instanceof IllegalArgumentException,
                 "Unexpected type of exception (requires 
IllegalArgumentException): " + e
@@ -755,17 +741,115 @@ class DistributionZoneManagerTest extends 
IgniteAbstractTest {
         );
     }
 
-    private void bindZoneToTable(String zoneName) {
-        int zoneId = distributionZoneManager.getZoneId(zoneName);
+    @Test
+    public void testCreateZoneWithFilter() throws Exception {
+        String expectedFilter = "['nodeAttributes'][?(@.['region'] == 'EU')]";
+
+        distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME).filter(expectedFilter).build()
+        ).get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertEquals(expectedFilter, zone1.filter().value());
+
+        distributionZoneManager.dropZone(ZONE_NAME).get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
 
-        NamedConfigurationTree<TableConfiguration, TableView, TableChange> 
tables = mock(NamedConfigurationTree.class, RETURNS_DEEP_STUBS);
+        assertNull(zone1, "Zone was not dropped.");
+    }
 
-        when(tablesConfiguration.tables()).thenReturn(tables);
+    @Test
+    public void testAlterZoneWithFilter() throws Exception {
+        String expectedFilter = "['nodeAttributes'][?(@.['region'] == 'EU')]";
 
-        TableView tableView = mock(TableView.class);
+        distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                                .filter(expectedFilter).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
 
-        when(tables.value().size()).thenReturn(1);
-        when(tables.value().get(anyInt())).thenReturn(tableView);
-        when(tableView.zoneId()).thenReturn(zoneId);
+        assertEquals(expectedFilter, zone1.filter().value());
+
+        String newExpectedFilter = "['nodeAttributes'][?(@.['storage'] == 
'SSD')]";
+
+        distributionZoneManager.alterZone(
+                        ZONE_NAME,
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                                .filter(newExpectedFilter).build()
+                ).get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertEquals(newExpectedFilter, zone1.filter().value());
+
+        distributionZoneManager.dropZone(ZONE_NAME).get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNull(zone1, "Zone was not dropped.");
+    }
+
+    @Test
+    public void testCreateZoneWithNotValidFilter() {
+        assertThrowsWithCause(
+                () -> distributionZoneManager.createZone(
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                                .filter("['nodeAttributes'[?(@.['region'] == 
'EU')]").build()
+                ).get(5, TimeUnit.SECONDS),
+                ConfigurationValidationException.class,
+                "Failed to parse filter ['nodeAttributes'[?(@.['region'] == 
'EU')], the cause: Property must be separated by comma"
+        );
+    }
+
+    @Test
+    @SuppressWarnings("ThrowableNotThrown")
+    public void testAlterZoneWithNotValidFilter() throws Exception {
+        String expectedFilter = "['nodeAttributes'][?(@.['region'] == 'EU')]";
+
+        distributionZoneManager.createZone(
+                new DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                        .filter(expectedFilter).build()
+                )
+                .get(5, TimeUnit.SECONDS);
+
+        DistributionZoneConfiguration zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertEquals(expectedFilter, zone1.filter().value());
+
+        String notValidFilter = "['nodeAttributes[?(@.['region'] == 'EU')]";
+
+        assertThrowsWithCause(
+                () -> distributionZoneManager.alterZone(
+                        ZONE_NAME,
+                        new 
DistributionZoneConfigurationParameters.Builder(ZONE_NAME)
+                                .filter(notValidFilter).build()
+                        ).get(5, TimeUnit.SECONDS),
+                ConfigurationValidationException.class,
+                "Failed to parse filter ['nodeAttributes[?(@.['region'] == 
'EU')], the cause: Property must be separated by comma"
+        );
+
+        distributionZoneManager.dropZone(ZONE_NAME).get(5, TimeUnit.SECONDS);
+
+        zone1 = 
registry.getConfiguration(DistributionZonesConfiguration.KEY).distributionZones()
+                .get(ZONE_NAME);
+
+        assertNull(zone1, "Zone was not dropped.");
+    }
+
+    private void bindZoneToTable(String zoneName) throws Exception {
+        int zoneId = distributionZoneManager.getZoneId(zoneName);
+
+        tablesConfiguration.change(ch -> ch.changeTables(tables -> 
tables.update("fooTable", chg -> chg.changeZoneId(zoneId))))
+                .get(5, TimeUnit.SECONDS);
     }
 }


Reply via email to