mirror of
https://github.com/ctripcorp/zeus.git
synced 2024-11-10 17:13:46 +08:00
refactor path validation
This commit is contained in:
parent
46efea06bc
commit
932e392df2
1 changed files with 76 additions and 51 deletions
|
@ -87,7 +87,8 @@ public class DefaultGroupValidator implements GroupValidator {
|
||||||
throw new ValidationException("No virtual server is found bound to this group.");
|
throw new ValidationException("No virtual server is found bound to this group.");
|
||||||
if (groupId == null)
|
if (groupId == null)
|
||||||
groupId = 0L;
|
groupId = 0L;
|
||||||
Map<Long, GroupVirtualServer> paths = new HashMap<>();
|
GroupVirtualServer dummy = new GroupVirtualServer();
|
||||||
|
Map<Long, GroupVirtualServer> addingGvs = new HashMap<>();
|
||||||
|
|
||||||
for (GroupVirtualServer gvs : groupVirtualServers) {
|
for (GroupVirtualServer gvs : groupVirtualServers) {
|
||||||
if (gvs.getRewrite() != null && !gvs.getRewrite().isEmpty()) {
|
if (gvs.getRewrite() != null && !gvs.getRewrite().isEmpty()) {
|
||||||
|
@ -100,75 +101,108 @@ public class DefaultGroupValidator implements GroupValidator {
|
||||||
if (!virtualServerModelValidator.exists(vs.getId())) {
|
if (!virtualServerModelValidator.exists(vs.getId())) {
|
||||||
throw new ValidationException("Virtual server with id " + vs.getId() + " does not exist.");
|
throw new ValidationException("Virtual server with id " + vs.getId() + " does not exist.");
|
||||||
}
|
}
|
||||||
if (paths.containsKey(vs.getId())) {
|
if (addingGvs.containsKey(vs.getId())) {
|
||||||
throw new ValidationException("Group and virtual server is an unique combination.");
|
throw new ValidationException("Group and virtual server is an unique combination.");
|
||||||
|
} else {
|
||||||
|
addingGvs.put(vs.getId(), dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (escapePathValidation) continue;
|
if (escapePathValidation) {
|
||||||
|
|
||||||
if (gvs.getPath() == null || gvs.getPath().isEmpty()) {
|
|
||||||
throw new ValidationException("Path cannot be empty.");
|
|
||||||
}
|
|
||||||
List<String> pathValues = new ArrayList<>(2);
|
|
||||||
for (String pv : gvs.getPath().split(" ", 0)) {
|
|
||||||
if (pv.isEmpty()) continue;
|
|
||||||
if (pathValues.size() == 2) throw new ValidationException("Invalid path, too many whitespace modifiers is found.");
|
|
||||||
|
|
||||||
pathValues.add(pv);
|
|
||||||
}
|
|
||||||
if (pathValues.size() == 2) {
|
|
||||||
if (!pathPrefixModifier.contains(pathValues.get(0))) {
|
|
||||||
throw new ValidationException("Invalid path, invalid prefix modifier is found.");
|
|
||||||
}
|
|
||||||
// format path value
|
|
||||||
gvs.setPath(pathValues.get(0) + " " + pathValues.get(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
String path = extractValue(gvs.getPath());
|
|
||||||
if (path.isEmpty()) {
|
|
||||||
paths.put(vs.getId(), new GroupVirtualServer().setPath(gvs.getPath()).setPriority(gvs.getPriority() == null ? -1000 : gvs.getPriority()));
|
|
||||||
continue;
|
continue;
|
||||||
|
} else {
|
||||||
|
doPathValidationAndMapping(addingGvs, gvs);
|
||||||
}
|
}
|
||||||
paths.put(vs.getId(), new GroupVirtualServer().setPath(path).setPriority(gvs.getPriority() == null ? 1000 : gvs.getPriority()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paths.size() == 0) return;
|
if (escapePathValidation || addingGvs.size() == 0) return;
|
||||||
|
List<RelGroupVsDo> retainedGvs = rGroupVsDao.findAllByVses(addingGvs.keySet().toArray(new Long[addingGvs.size()]), RGroupVsEntity.READSET_FULL);
|
||||||
|
checkPathOverlappingAcrossVs(groupId, addingGvs, retainedGvs);
|
||||||
|
|
||||||
|
// reset priority after auto reorder
|
||||||
|
for (GroupVirtualServer e : groupVirtualServers) {
|
||||||
|
e.setPriority(addingGvs.get(e.getVirtualServer().getId()).getPriority());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateGroupServers(List<GroupServer> groupServers) throws Exception {
|
||||||
|
groupServerModelValidator.validateGroupServers(groupServers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPathValidationAndMapping(Map<Long, GroupVirtualServer> mappingResult, GroupVirtualServer gvs) throws ValidationException {
|
||||||
|
if (gvs.getPath() == null || gvs.getPath().isEmpty()) {
|
||||||
|
throw new ValidationException("Path cannot be empty.");
|
||||||
|
}
|
||||||
|
List<String> pathValues = new ArrayList<>(2);
|
||||||
|
for (String pv : gvs.getPath().split(" ", 0)) {
|
||||||
|
if (pv.isEmpty()) continue;
|
||||||
|
if (pathValues.size() == 2) throw new ValidationException("Invalid path, too many whitespace modifiers is found.");
|
||||||
|
|
||||||
|
pathValues.add(pv);
|
||||||
|
}
|
||||||
|
if (pathValues.size() == 2) {
|
||||||
|
if (!pathPrefixModifier.contains(pathValues.get(0))) {
|
||||||
|
throw new ValidationException("Invalid path, invalid prefix modifier is found.");
|
||||||
|
}
|
||||||
|
// format path value
|
||||||
|
gvs.setPath(pathValues.get(0) + " " + pathValues.get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = extractValue(gvs.getPath());
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
mappingResult.put(gvs.getVirtualServer().getId(), new GroupVirtualServer().setPath(gvs.getPath()).setPriority(gvs.getPriority() == null ? -1000 : gvs.getPriority()));
|
||||||
|
} else {
|
||||||
|
mappingResult.put(gvs.getVirtualServer().getId(), new GroupVirtualServer().setPath(path).setPriority(gvs.getPriority() == null ? 1000 : gvs.getPriority()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPathOverlappingAcrossVs(Long groupId, Map<Long, GroupVirtualServer> addingGvs, List<RelGroupVsDo> retainedGvs) throws ValidationException {
|
||||||
List<RelGroupVsDo> retained = new ArrayList<>();
|
List<RelGroupVsDo> retained = new ArrayList<>();
|
||||||
for (RelGroupVsDo d : rGroupVsDao.findAllByVses(paths.keySet().toArray(new Long[paths.size()]), RGroupVsEntity.READSET_FULL)) {
|
for (RelGroupVsDo retainedEntry : retainedGvs) {
|
||||||
if (groupId.equals(d.getGroupId()))
|
if (groupId.equals(retainedEntry.getGroupId()))
|
||||||
continue;
|
continue;
|
||||||
if (d.getPriority() == 0) d.setPriority(1000);
|
if (retainedEntry.getPriority() == 0) retainedEntry.setPriority(1000);
|
||||||
|
|
||||||
String value = d.getPath();
|
String retainedPath = retainedEntry.getPath();
|
||||||
try {
|
try {
|
||||||
value = extractValue(d.getPath());
|
retainedPath = extractValue(retainedEntry.getPath());
|
||||||
} catch (ValidationException ex) {
|
} catch (ValidationException ex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroupVirtualServer addingEntry = addingGvs.get(retainedEntry.getVsId());
|
||||||
|
if (addingEntry == null) {
|
||||||
|
throw new ValidationException("Unexpected path validation is reached. Related group and vs: " + groupId + ", " + retainedEntry.getVsId());
|
||||||
|
}
|
||||||
|
|
||||||
|
String addingPath = addingEntry.getPath();
|
||||||
|
try {
|
||||||
|
addingPath = extractValue(addingPath);
|
||||||
|
} catch (ValidationException ex) {
|
||||||
|
}
|
||||||
|
|
||||||
// check if root path is completely equivalent, otherwise escape comparing with root path
|
// check if root path is completely equivalent, otherwise escape comparing with root path
|
||||||
GroupVirtualServer entry = paths.get(d.getVsId());
|
if (retainedPath.isEmpty() || addingPath.isEmpty()) {
|
||||||
if (value.isEmpty()) {
|
if (retainedEntry.getPath().equals(addingEntry.getPath())) {
|
||||||
if (d.getPath().equals(entry.getPath())) {
|
retained.add(retainedEntry);
|
||||||
retained.add(d);
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ol = StringUtils.prefixOverlapped(entry.getPath(), value);
|
int ol = StringUtils.prefixOverlapped(addingPath, retainedPath);
|
||||||
switch (ol) {
|
switch (ol) {
|
||||||
case -1:
|
case -1:
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
retained.add(d);
|
retained.add(retainedEntry);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (entry.getPriority() == null || entry.getPriority() <= d.getPriority()) {
|
if (addingEntry.getPriority() == null || addingEntry.getPriority() <= retainedEntry.getPriority()) {
|
||||||
entry.setPriority(d.getPriority() + 100);
|
addingEntry.setPriority(retainedEntry.getPriority() + 100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (entry.getPriority() == null || entry.getPriority() >= d.getPriority()) {
|
if (addingEntry.getPriority() == null || addingEntry.getPriority() >= retainedEntry.getPriority()) {
|
||||||
entry.setPriority(d.getPriority() - 100);
|
addingEntry.setPriority(retainedEntry.getPriority() - 100);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -183,15 +217,6 @@ public class DefaultGroupValidator implements GroupValidator {
|
||||||
}
|
}
|
||||||
throw new ValidationException("Path is prefix-overlapped across virtual server " + sb.toString() + ".");
|
throw new ValidationException("Path is prefix-overlapped across virtual server " + sb.toString() + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (GroupVirtualServer e : groupVirtualServers) {
|
|
||||||
e.setPriority(paths.get(e.getVirtualServer().getId()).getPriority());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateGroupServers(List<GroupServer> groupServers) throws Exception {
|
|
||||||
groupServerModelValidator.validateGroupServers(groupServers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String extractValue(String path) throws ValidationException {
|
private static String extractValue(String path) throws ValidationException {
|
||||||
|
|
Loading…
Reference in a new issue