From bd6c2a544b4f8a83ef64ce316042f45004033fc2 Mon Sep 17 00:00:00 2001 From: John Niang Date: Tue, 2 Aug 2022 12:24:12 +0800 Subject: [PATCH] Add IN operator for fieldSelector and labelSelector (#2290) #### What type of PR is this? /kind feature /kind api-change /area core /milestone 2.0 /release-note-none #### What this PR does / why we need it: - Add `IN` operator for fieldSelector and labelSelector. - Adapt name field selector with `IN` operator. ```release-note None ``` --- .../FieldCriteriaPredicateConverter.java | 2 +- .../extension/router/selector/Operator.java | 19 ++++++++++++++++- .../FieldCriteriaPredicateConverterTest.java | 21 +++++++++++++++++++ .../router/selector/OperatorTest.java | 9 +++++++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/main/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverter.java b/src/main/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverter.java index df4129a1c..7bd95e5f6 100644 --- a/src/main/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverter.java +++ b/src/main/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverter.java @@ -19,7 +19,7 @@ public class FieldCriteriaPredicateConverter return false; } switch (criteria.operator()) { - case Equals -> { + case Equals, IN -> { return criteria.values().contains(name); } case NotEquals -> { diff --git a/src/main/java/run/halo/app/extension/router/selector/Operator.java b/src/main/java/run/halo/app/extension/router/selector/Operator.java index 97dc9e011..04f748094 100644 --- a/src/main/java/run/halo/app/extension/router/selector/Operator.java +++ b/src/main/java/run/halo/app/extension/router/selector/Operator.java @@ -6,7 +6,7 @@ import org.springframework.lang.Nullable; public enum Operator implements Converter { - Equals("=", 2) { + Equals("=", 3) { @Override @Nullable public SelectorCriteria convert(@Nullable String selector) { @@ -21,6 +21,23 @@ public enum Operator implements Converter { return null; } }, + IN("=(", 2) { + @Override + public SelectorCriteria convert(String selector) { + if (preFlightCheck(selector, 5)) { + var idx = selector.indexOf(getOperator()); + if (idx > 0 && (idx + getOperator().length()) < selector.length() - 2 + && selector.charAt(selector.length() - 1) == ')') { + var key = selector.substring(0, idx); + var valuesString = + selector.substring(idx + getOperator().length(), selector.length() - 1); + String[] values = valuesString.split(","); + return new SelectorCriteria(key, this, Set.of(values)); + } + } + return null; + } + }, NotEquals("!=", 1) { @Override @Nullable diff --git a/src/test/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverterTest.java b/src/test/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverterTest.java index 79b342ace..34eff15d1 100644 --- a/src/test/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverterTest.java +++ b/src/test/java/run/halo/app/extension/router/selector/FieldCriteriaPredicateConverterTest.java @@ -63,6 +63,27 @@ class FieldCriteriaPredicateConverterTest { assertFalse(predicate.test(fake)); } + @Test + void shouldConvertNameInCorrectly() { + var criteria = new SelectorCriteria("name", Operator.IN, Set.of("value1", "value2")); + var predicate = converter.convert(criteria); + assertNotNull(predicate); + + var fake = new FakeExtension(); + var metadata = new Metadata(); + fake.setMetadata(metadata); + assertFalse(predicate.test(fake)); + + metadata.setName("not-contain-value"); + assertFalse(predicate.test(fake)); + + metadata.setName("value1"); + assertTrue(predicate.test(fake)); + + metadata.setName("value2"); + assertTrue(predicate.test(fake)); + } + @Test void shouldReturnAlwaysFalseIfCriteriaKeyNotSupported() { var criteria = diff --git a/src/test/java/run/halo/app/extension/router/selector/OperatorTest.java b/src/test/java/run/halo/app/extension/router/selector/OperatorTest.java index 2e3044d19..ee349b4d1 100644 --- a/src/test/java/run/halo/app/extension/router/selector/OperatorTest.java +++ b/src/test/java/run/halo/app/extension/router/selector/OperatorTest.java @@ -3,6 +3,7 @@ package run.halo.app.extension.router.selector; import static org.junit.jupiter.api.Assertions.assertEquals; import static run.halo.app.extension.router.selector.Operator.Equals; import static run.halo.app.extension.router.selector.Operator.Exist; +import static run.halo.app.extension.router.selector.Operator.IN; import static run.halo.app.extension.router.selector.Operator.NotEquals; import static run.halo.app.extension.router.selector.Operator.NotExist; @@ -46,7 +47,13 @@ class OperatorTest { new TestCase("name", Exist, new SelectorCriteria("name", Exist, Set.of())), new TestCase("", Exist, null), new TestCase("!", Exist, new SelectorCriteria("!", Exist, Set.of())), - new TestCase("a", Exist, new SelectorCriteria("a", Exist, Set.of())) + new TestCase("a", Exist, new SelectorCriteria("a", Exist, Set.of())), + + new TestCase("name", IN, null), + new TestCase("name=(fake-name)", IN, + new SelectorCriteria("name", IN, Set.of("fake-name"))), + new TestCase("name=(first-name,second-name)", IN, + new SelectorCriteria("name", IN, Set.of("first-name", "second-name"))) ).forEach(testCase -> { log.debug("Testing: {}", testCase); assertEquals(testCase.expected(), testCase.converter().convert(testCase.source()));