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
```
pull/2299/head
John Niang 2022-08-02 12:24:12 +08:00 committed by GitHub
parent 3640dca0a1
commit bd6c2a544b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 3 deletions

View File

@ -19,7 +19,7 @@ public class FieldCriteriaPredicateConverter<E extends Extension>
return false;
}
switch (criteria.operator()) {
case Equals -> {
case Equals, IN -> {
return criteria.values().contains(name);
}
case NotEquals -> {

View File

@ -6,7 +6,7 @@ import org.springframework.lang.Nullable;
public enum Operator implements Converter<String, SelectorCriteria> {
Equals("=", 2) {
Equals("=", 3) {
@Override
@Nullable
public SelectorCriteria convert(@Nullable String selector) {
@ -21,6 +21,23 @@ public enum Operator implements Converter<String, SelectorCriteria> {
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

View File

@ -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 =

View File

@ -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()));