mirror of https://github.com/apache/lucene.git
SOLR-9735: validation for specific tags
This commit is contained in:
parent
b530c1397e
commit
e2ae9992c5
|
@ -20,6 +20,7 @@ package org.apache.solr.cloud.autoscaling;
|
|||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
@ -31,10 +32,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
|
||||
import org.apache.solr.cloud.autoscaling.Policy.ReplicaInfo;
|
||||
import org.apache.solr.common.MapWriter;
|
||||
import org.apache.solr.common.cloud.rule.ImplicitSnitch;
|
||||
import org.apache.solr.common.util.StrUtils;
|
||||
import org.apache.solr.common.util.Utils;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static java.util.Collections.unmodifiableSet;
|
||||
import static org.apache.solr.cloud.autoscaling.Clause.TestStatus.PASS;
|
||||
import static org.apache.solr.cloud.autoscaling.Operand.EQUAL;
|
||||
import static org.apache.solr.cloud.autoscaling.Operand.GREATER_THAN;
|
||||
|
@ -337,4 +340,80 @@ public class Clause implements MapWriter, Comparable<Clause> {
|
|||
}
|
||||
|
||||
private static final Set<String> IGNORE_TAGS = new HashSet<>(Arrays.asList(REPLICA, COLLECTION, SHARD, "strict"));
|
||||
|
||||
static class ValidateInfo {
|
||||
final Class type;
|
||||
final Set<String> vals;
|
||||
final Long min;
|
||||
final Long max;
|
||||
|
||||
|
||||
ValidateInfo(Class type, Set<String> vals, Long min, Long max) {
|
||||
this.type = type;
|
||||
this.vals = vals;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Object validate(String name, Object val) {
|
||||
if (val == null) return null;
|
||||
ValidateInfo info = validatetypes.get(name);
|
||||
if (info == null && name.startsWith(ImplicitSnitch.SYSPROP)) info = validatetypes.get(null);
|
||||
if (info == null) throw new RuntimeException("Unknown type :" + name);
|
||||
if (info.type == Long.class) {
|
||||
Long num = parseNumber(name, val);
|
||||
if (info.min != null)
|
||||
if (num < info.min) throw new RuntimeException(name + ": " + val + " must be greater than " + info.min);
|
||||
if (info.max != null)
|
||||
if (num > info.max) throw new RuntimeException(name + ": " + val + " must be less than " + info.max);
|
||||
return num;
|
||||
} else if (info.type == String.class) {
|
||||
if (info.vals != null && !info.vals.contains(val))
|
||||
throw new RuntimeException(name + ": " + val + " must be one of " + StrUtils.join(info.vals, ','));
|
||||
return val;
|
||||
} else {
|
||||
throw new RuntimeException("Invalid type ");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Long parseNumber(String name, Object val) {
|
||||
if (val == null) return null;
|
||||
Number num = 0;
|
||||
if (val instanceof String) {
|
||||
try {
|
||||
num = Long.parseLong((String) val);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
num = Double.parseDouble((String) val);
|
||||
} catch (NumberFormatException e1) {
|
||||
throw new RuntimeException(name + ": " + val + "not a valid number", e);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (val instanceof Number) {
|
||||
num = (Number) val;
|
||||
}
|
||||
return num.longValue();
|
||||
}
|
||||
|
||||
private static final Map<String, ValidateInfo> validatetypes = new HashMap();
|
||||
|
||||
static {
|
||||
validatetypes.put("collection", new ValidateInfo(String.class, null, null, null));
|
||||
validatetypes.put("shard", new ValidateInfo(String.class, null, null, null));
|
||||
validatetypes.put("replica", new ValidateInfo(Long.class, null, 0l, null));
|
||||
validatetypes.put(ImplicitSnitch.PORT, new ValidateInfo(Long.class, null, 1024l, 65535l));
|
||||
validatetypes.put(ImplicitSnitch.DISK, new ValidateInfo(Long.class, null, 0l, Long.MAX_VALUE));
|
||||
validatetypes.put(ImplicitSnitch.NODEROLE, new ValidateInfo(String.class, unmodifiableSet(new HashSet(Arrays.asList("overseer"))), null, null));
|
||||
validatetypes.put(ImplicitSnitch.CORES, new ValidateInfo(Long.class, null, 0l, Long.MAX_VALUE));
|
||||
validatetypes.put(ImplicitSnitch.SYSLOADAVG, new ValidateInfo(Long.class, null, 0l, 100l));
|
||||
validatetypes.put(ImplicitSnitch.HEAPUSAGE, new ValidateInfo(Long.class, null, 0l, Long.MAX_VALUE));
|
||||
validatetypes.put(null, new ValidateInfo(String.class, null, null, null));
|
||||
for (String ip : ImplicitSnitch.IP_SNITCHES) validatetypes.put(ip, new ValidateInfo(Long.class, null, 0l, 255l));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,57 @@ public class TestPolicy extends SolrTestCaseJ4 {
|
|||
return result;
|
||||
}
|
||||
|
||||
public void testValidate() {
|
||||
expectError("replica", -1, "must be greater than" );
|
||||
expectError("replica","hello", "not a valid number" );
|
||||
assertEquals( 1l, Clause.validate("replica", "1"));
|
||||
assertEquals("c", Clause.validate("collection", "c"));
|
||||
assertEquals( "s", Clause.validate("shard", "s"));
|
||||
assertEquals( "overseer", Clause.validate("nodeRole", "overseer"));
|
||||
|
||||
expectError("nodeRole", "wrong","must be one of");
|
||||
|
||||
expectError("sysLoadAvg", "101","must be less than ");
|
||||
expectError("sysLoadAvg", 101,"must be less than ");
|
||||
expectError("sysLoadAvg", "-1","must be greater than");
|
||||
expectError("sysLoadAvg", -1,"must be greater than");
|
||||
|
||||
assertEquals(12l,Clause.validate("sysLoadAvg", "12.46"));
|
||||
assertEquals(12l,Clause.validate("sysLoadAvg", 12.46d));
|
||||
|
||||
|
||||
expectError("ip_1", "300","must be less than ");
|
||||
expectError("ip_1", 300,"must be less than ");
|
||||
expectError("ip_1", "-1","must be greater than");
|
||||
expectError("ip_1", -1,"must be greater than");
|
||||
|
||||
assertEquals(1l,Clause.validate("ip_1", "1"));
|
||||
|
||||
expectError("heapUsage", "-1","must be greater than");
|
||||
expectError("heapUsage", -1,"must be greater than");
|
||||
assertEquals(69l,Clause.validate("heapUsage", "69.9"));
|
||||
assertEquals(69l,Clause.validate("heapUsage", 69.9d));
|
||||
|
||||
expectError("port", "70000","must be less than ");
|
||||
expectError("port", 70000,"must be less than ");
|
||||
expectError("port", "1000","must be greater than");
|
||||
expectError("port", 1000,"must be greater than");
|
||||
|
||||
expectError("cores", "-1","must be greater than");
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void expectError(String name, Object val, String msg){
|
||||
try {
|
||||
Clause.validate(name, val);
|
||||
fail("expected exception containing "+msg);
|
||||
} catch (Exception e) {
|
||||
assertTrue("expected exception containing "+msg,e.getMessage().contains(msg));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testOperands() {
|
||||
Clause c = new Clause((Map<String, Object>) Utils.fromJSONString("{replica:'<2', node:'#ANY'}"));
|
||||
assertFalse(c.replica.isPass(3));
|
||||
|
|
Loading…
Reference in New Issue