mirror of
https://github.com/ctripcorp/zeus.git
synced 2024-09-20 23:56:05 +08:00
add path overlapping check
This commit is contained in:
parent
c9138d7eb2
commit
edcdd1e42d
|
@ -10,12 +10,11 @@ import com.ctrip.zeus.service.model.PathRewriteParser;
|
|||
import com.ctrip.zeus.service.model.handler.GroupServerValidator;
|
||||
import com.ctrip.zeus.service.model.handler.GroupValidator;
|
||||
import com.ctrip.zeus.service.model.handler.VirtualServerValidator;
|
||||
import com.ctrip.zeus.util.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by zhoumy on 2015/6/29.
|
||||
|
@ -78,31 +77,51 @@ public class DefaultGroupValidator implements GroupValidator {
|
|||
throw new ValidationException("No virtual server is found bound to this group.");
|
||||
if (groupId == null)
|
||||
groupId = 0L;
|
||||
Set<Long> virtualServerIds = new HashSet<>();
|
||||
Set<String> groupPaths = new HashSet<>();
|
||||
for (GroupVirtualServer groupVirtualServer : groupVirtualServers) {
|
||||
if (groupVirtualServer.getRewrite() != null && !groupVirtualServer.getRewrite().isEmpty())
|
||||
if (!PathRewriteParser.validate(groupVirtualServer.getRewrite()))
|
||||
Map<Long, String> paths = new HashMap<>();
|
||||
|
||||
for (GroupVirtualServer gvs : groupVirtualServers) {
|
||||
if (gvs.getRewrite() != null && !gvs.getRewrite().isEmpty()) {
|
||||
if (!PathRewriteParser.validate(gvs.getRewrite())) {
|
||||
throw new ValidationException("Invalid rewrite value.");
|
||||
VirtualServer vs = groupVirtualServer.getVirtualServer();
|
||||
if (!virtualServerModelValidator.exists(vs.getId()))
|
||||
throw new ValidationException("Virtual Server with id " + vs.getId() + " does not exist.");
|
||||
else {
|
||||
if (virtualServerIds.contains(vs.getId()))
|
||||
throw new ValidationException("Group-VirtualServer is an unique combination.");
|
||||
else
|
||||
virtualServerIds.add(vs.getId());
|
||||
}
|
||||
}
|
||||
if (groupPaths.contains(vs.getId() + groupVirtualServer.getPath()))
|
||||
throw new ValidationException("Duplicate path \"" + groupVirtualServer.getPath() + "\" is found on virtual server " + vs.getId() + " from post entity.");
|
||||
else
|
||||
groupPaths.add(vs.getId() + groupVirtualServer.getPath());
|
||||
|
||||
VirtualServer vs = gvs.getVirtualServer();
|
||||
if (!virtualServerModelValidator.exists(vs.getId())) {
|
||||
throw new ValidationException("Virtual server with id " + vs.getId() + " does not exist.");
|
||||
}
|
||||
if (paths.containsKey(vs.getId())) {
|
||||
throw new ValidationException("Group and virtual server is an unique combination.");
|
||||
}
|
||||
|
||||
String path = gvs.getPath();
|
||||
path = path.substring(path.indexOf('/'));
|
||||
paths.put(vs.getId(), path);
|
||||
}
|
||||
for (RelGroupVsDo relGroupVsDo : rGroupVsDao.findAllByVses(virtualServerIds.toArray(new Long[virtualServerIds.size()]), RGroupVsEntity.READSET_FULL)) {
|
||||
if (groupId.equals(relGroupVsDo.getGroupId()))
|
||||
|
||||
List<RelGroupVsDo> retained = new ArrayList<>();
|
||||
for (RelGroupVsDo d : rGroupVsDao.findAllByVses(paths.keySet().toArray(new Long[paths.size()]), RGroupVsEntity.READSET_FULL)) {
|
||||
if (groupId.equals(d.getGroupId()))
|
||||
continue;
|
||||
if (groupPaths.contains(relGroupVsDo.getVsId() + relGroupVsDo.getPath()))
|
||||
throw new ValidationException("Duplicate path \"" + relGroupVsDo.getPath() + "\" is found on virtual server " + relGroupVsDo.getVsId() + " from existing entities.");
|
||||
int i = 0;
|
||||
String value = d.getPath();
|
||||
while (i < value.length()) {
|
||||
char next = value.charAt(i);
|
||||
if (next == '/') {
|
||||
if (StringUtils.prefixOverlapped(paths.get(d.getVsId()), value.substring(i))) retained.add(d);
|
||||
break;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retained.size() > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (RelGroupVsDo d : retained) {
|
||||
sb.append(d.getVsId() + "/" + d.getPath());
|
||||
}
|
||||
throw new ValidationException("Path is prefix-overlapped across virtual server " + sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
src/main/java/com/ctrip/zeus/util/StringUtils.java
Normal file
17
src/main/java/com/ctrip/zeus/util/StringUtils.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package com.ctrip.zeus.util;
|
||||
|
||||
/**
|
||||
* Created by zhoumy on 2016/3/30.
|
||||
*/
|
||||
public class StringUtils {
|
||||
public static boolean prefixOverlapped(String string1, String string2) {
|
||||
int i = 0;
|
||||
while (i < string1.length() && i < string2.length()) {
|
||||
if (string1.charAt(i) == string2.charAt(i) || Character.toLowerCase(string1.charAt(i)) == Character.toLowerCase(string2.charAt(i))) {
|
||||
i++;
|
||||
continue;
|
||||
} else return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
package com.ctrip.zeus.service.model;
|
||||
|
||||
import com.ctrip.zeus.AbstractServerTest;
|
||||
import com.ctrip.zeus.dal.core.RGroupVsDao;
|
||||
import com.ctrip.zeus.dal.core.RelGroupVsDo;
|
||||
import com.ctrip.zeus.exceptions.ValidationException;
|
||||
import com.ctrip.zeus.model.entity.*;
|
||||
import com.ctrip.zeus.service.model.handler.GroupValidator;
|
||||
import com.ctrip.zeus.util.StringUtils;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by zhoumy on 2016/3/31.
|
||||
*/
|
||||
public class PathValidationTest extends AbstractServerTest {
|
||||
@Resource
|
||||
private SlbRepository slbRepository;
|
||||
|
||||
@Resource
|
||||
private RGroupVsDao rGroupVsDao;
|
||||
|
||||
@Resource
|
||||
private GroupValidator groupModelValidator;
|
||||
|
||||
@Test
|
||||
public void testStringUtils() {
|
||||
String s1 = "abcdefg";
|
||||
String s2 = "abc";
|
||||
String s3 = "ABCDefghij";
|
||||
String s4 = "我爱中国";
|
||||
String s5 = "我";
|
||||
String s6 = "我爱中国中国爱我";
|
||||
|
||||
String s7 = "bcdef";
|
||||
String s8 = "爱";
|
||||
|
||||
Assert.assertTrue(StringUtils.prefixOverlapped(s1, s2));
|
||||
Assert.assertTrue(StringUtils.prefixOverlapped(s2, s3));
|
||||
Assert.assertTrue(StringUtils.prefixOverlapped(s3, s1));
|
||||
|
||||
Assert.assertTrue(StringUtils.prefixOverlapped(s4, s5));
|
||||
Assert.assertTrue(StringUtils.prefixOverlapped(s5, s6));
|
||||
Assert.assertTrue(StringUtils.prefixOverlapped(s6, s4));
|
||||
|
||||
Assert.assertFalse(StringUtils.prefixOverlapped(s1, s7));
|
||||
Assert.assertFalse(StringUtils.prefixOverlapped(s4, s8));
|
||||
Assert.assertFalse(StringUtils.prefixOverlapped(s1, s4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddExistingPath() {
|
||||
String path = "~* ^/linkservice($|/|\\?)";
|
||||
List<GroupVirtualServer> array = new ArrayList<>();
|
||||
array.add(new GroupVirtualServer().setPath(path).setVirtualServer(new VirtualServer().setId(1L)));
|
||||
try {
|
||||
groupModelValidator.validateGroupVirtualServers(100L, array);
|
||||
Assert.assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof ValidationException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddOverlappingPath() {
|
||||
String path = "~* ^/linkservice/config($|/|\\?)";
|
||||
List<GroupVirtualServer> array = new ArrayList<>();
|
||||
array.add(new GroupVirtualServer().setPath(path).setVirtualServer(new VirtualServer().setId(1L)));
|
||||
try {
|
||||
groupModelValidator.validateGroupVirtualServers(100L, array);
|
||||
Assert.assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof ValidationException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePath() {
|
||||
String path = "~* ^/baike($|/|\\?)";
|
||||
List<GroupVirtualServer> array = new ArrayList<>();
|
||||
array.add(new GroupVirtualServer().setPath(path).setVirtualServer(new VirtualServer().setId(1L)));
|
||||
try {
|
||||
groupModelValidator.validateGroupVirtualServers(10L, array);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddUpperCasePath() {
|
||||
String path = "~* ^/BAIKE/CONFIG($|/|\\?)";
|
||||
List<GroupVirtualServer> array = new ArrayList<>();
|
||||
array.add(new GroupVirtualServer().setPath(path).setVirtualServer(new VirtualServer().setId(1L)));
|
||||
try {
|
||||
groupModelValidator.validateGroupVirtualServers(100L, array);
|
||||
Assert.assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof ValidationException);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnconventionalPath() {
|
||||
String root = "/";
|
||||
String startWith = "^/CommentAdmin";
|
||||
String noStart = "baike";
|
||||
|
||||
List<GroupVirtualServer> array = new ArrayList<>();
|
||||
array.add(new GroupVirtualServer().setPath(root).setVirtualServer(new VirtualServer().setId(1L)));
|
||||
|
||||
try {
|
||||
groupModelValidator.validateGroupVirtualServers(100L, array);
|
||||
Assert.assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof ValidationException);
|
||||
}
|
||||
|
||||
try {
|
||||
array.get(0).setPath(startWith);
|
||||
groupModelValidator.validateGroupVirtualServers(100L, array);
|
||||
Assert.assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof ValidationException);
|
||||
}
|
||||
|
||||
try {
|
||||
array.get(0).setPath(noStart);
|
||||
groupModelValidator.validateGroupVirtualServers(100L, array);
|
||||
Assert.assertTrue(false);
|
||||
} catch (Exception e) {
|
||||
Assert.assertTrue(e instanceof ValidationException);
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void check() throws Exception {
|
||||
Slb slb = slbRepository.getById(1L);
|
||||
Set<String> existingPaths = Sets.newHashSet("~* /", "~* ^/CommentAdmin/", "~* ^/baike($|/|\\?)",
|
||||
"~* ^/linkservice($|/|\\?)", "~* ^/linkservice/link($|/|\\?)",
|
||||
"~* ^/tour-marketingservice($|/|\\?)", "~* ^/tour-MarketingServiceConfig($|/|\\?)",
|
||||
"~* ^/cruise-interface-costa($|/|\\?)", "~* ^/Cruise-Product-WCFService($|/|\\?)", "~* ^/Cruise-Product-OctopusJob($|/|\\?)");
|
||||
if (slb == null) {
|
||||
slb = new Slb().setName("default").setStatus("TEST")
|
||||
.addVip(new Vip().setIp("10.2.25.93"))
|
||||
.addSlbServer(new SlbServer().setIp("10.2.25.93").setHostName("uat0358"))
|
||||
.addVirtualServer(new VirtualServer().setName("defaultSlbVs1").setSsl(false).setPort("80")
|
||||
.addDomain(new Domain().setName("defaultSlbVs1.ctrip.com")));
|
||||
slbRepository.add(slb);
|
||||
|
||||
for (String path : existingPaths) {
|
||||
for (int i = 0; i < existingPaths.size(); i++) {
|
||||
rGroupVsDao.insert(new RelGroupVsDo().setGroupId(10).setVsId(1).setPath(path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue