separate validation module

This commit is contained in:
Mengyi Zhou 2017-02-06 17:15:33 +08:00
parent b8625e6678
commit 7d5eecaaf3
21 changed files with 381 additions and 283 deletions

View file

@ -1,11 +0,0 @@
package com.ctrip.zeus.service.model.handler;
import com.ctrip.zeus.model.entity.Group;
/**
* Created by zhoumy on 2015/6/29.
*/
public interface GroupValidator extends ModelValidator<Group> {
boolean exists(Long targetId, boolean virtual) throws Exception;
}

View file

@ -1,70 +0,0 @@
package com.ctrip.zeus.service.model.handler.impl;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.*;
import com.ctrip.zeus.service.model.handler.GroupValidator;
import org.springframework.stereotype.Component;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.annotation.Resource;
/**
* Created by zhoumy on 2015/6/29.
*/
@Component("groupModelValidator")
public class DefaultGroupValidator implements GroupValidator {
@Resource
private RTrafficPolicyGroupDao rTrafficPolicyGroupDao;
@Resource
private RGroupVgDao rGroupVgDao;
@Resource
private RGroupStatusDao rGroupStatusDao;
@Resource
private GroupDao groupDao;
@Override
public boolean exists(Long targetId) throws Exception {
return exists(targetId, false);
}
@Override
public boolean exists(Long targetId, boolean virtual) throws Exception {
boolean result = groupDao.findById(targetId, GroupEntity.READSET_FULL) != null;
RelGroupVgDo value = rGroupVgDao.findByGroup(targetId, RGroupVgEntity.READSET_FULL);
result &= (virtual ^ value == null);
return result;
}
@Override
public void validate(Group target) throws Exception {
throw new NotImplementedException();
}
@Override
public void checkVersionForUpdate(Group target) throws Exception {
RelGroupStatusDo check = rGroupStatusDao.findByGroup(target.getId(), RGroupStatusEntity.READSET_FULL);
if (check == null) {
throw new ValidationException("Group that you try to update does not exist.");
}
if (check.getOfflineVersion() > target.getVersion()) {
throw new ValidationException("Newer version is detected.");
}
if (check.getOfflineVersion() != target.getVersion()) {
throw new ValidationException("Incompatible version.");
}
}
@Override
public void removable(Long targetId) throws Exception {
RelGroupStatusDo check = rGroupStatusDao.findByGroup(targetId, RGroupStatusEntity.READSET_FULL);
if (check == null) return;
if (check.getOnlineVersion() != 0) {
throw new ValidationException("Group that you tried to delete is still active.");
}
if (rTrafficPolicyGroupDao.findByGroup(targetId, RTrafficPolicyGroupEntity.READSET_FULL).size() > 0) {
throw new ValidationException("Group that you tried to delete has one or more traffic policy dependency.");
}
}
}

View file

@ -8,8 +8,9 @@ import com.ctrip.zeus.model.entity.*;
import com.ctrip.zeus.service.model.*;
import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.handler.GroupSync;
import com.ctrip.zeus.service.model.handler.GroupValidator;
import com.ctrip.zeus.service.model.validation.GroupValidator;
import com.ctrip.zeus.service.model.handler.impl.ContentReaders;
import com.ctrip.zeus.service.model.ValidationFacade;
import com.ctrip.zeus.service.query.GroupCriteriaQuery;
import com.ctrip.zeus.service.query.VirtualServerCriteriaQuery;
import com.ctrip.zeus.service.status.StatusService;

View file

@ -6,7 +6,7 @@ import com.ctrip.zeus.model.entity.SlbServer;
import com.ctrip.zeus.service.model.*;
import com.ctrip.zeus.service.model.handler.SlbQuery;
import com.ctrip.zeus.service.model.handler.SlbSync;
import com.ctrip.zeus.service.model.handler.SlbValidator;
import com.ctrip.zeus.service.model.validation.SlbValidator;
import com.ctrip.zeus.service.model.IdVersion;
import com.ctrip.zeus.service.model.handler.impl.ContentReaders;
import com.ctrip.zeus.service.nginx.CertificateService;

View file

@ -2,14 +2,15 @@ package com.ctrip.zeus.service.model.impl;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.*;
import com.ctrip.zeus.service.model.PathRewriteParser;
import com.ctrip.zeus.service.model.PathValidator;
import com.ctrip.zeus.service.model.ValidationFacade;
import com.ctrip.zeus.service.model.common.ErrorType;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.MetaType;
import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.handler.VsEntryFactory;
import com.ctrip.zeus.service.model.validation.GroupValidator;
import com.ctrip.zeus.service.model.validation.PathValidator;
import com.ctrip.zeus.service.model.validation.TrafficPolicyValidator;
import com.ctrip.zeus.service.model.validation.VsEntryFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -24,35 +25,18 @@ public class ValidationFacadeImpl implements ValidationFacade {
private VsEntryFactory vsEntryFactory;
@Resource
private PathValidator pathValidator;
@Resource
private GroupValidator groupModelValidator;
@Resource
private TrafficPolicyValidator trafficPolicyValidator;
@Override
public void validateGroup(Group group, ValidationContext context) {
if (group.getName() == null || group.getName().isEmpty()
|| group.getAppId() == null || group.getAppId().isEmpty()) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, "Field `name` and `app-id` are not allowed empty.");
return;
}
if (group.getHealthCheck() != null
&& (group.getHealthCheck().getUri() == null || group.getHealthCheck().getUri().isEmpty())) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, "Field `health-check` is missing `uri` value.");
return;
}
try {
if (group.isVirtual() && (group.getGroupServers() != null && group.getGroupServers().size() > 0)) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, "Field `group-servers` is not allowed if group is virtual type.");
return;
}
validateMembers(group.getGroupServers());
} catch (ValidationException e) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, e.getMessage());
return;
}
groupModelValidator.validateFields(group, context);
Map<Long, GroupVirtualServer> groupOnVses;
try {
groupOnVses = validateGroupOnVses(group.getGroupVirtualServers(), group.isVirtual());
groupOnVses = groupModelValidator.validateGroupOnVses(group.getGroupVirtualServers(), group.isVirtual());
} catch (ValidationException e) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, e.getMessage());
return;
@ -65,7 +49,7 @@ public class ValidationFacadeImpl implements ValidationFacade {
} catch (Exception e) {
}
try {
validatePolicyRestriction(groupOnVses, policyEntries);
groupModelValidator.validatePolicyRestriction(groupOnVses, policyEntries);
} catch (ValidationException e) {
context.error(group.getId(), MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, e.getMessage());
return;
@ -94,80 +78,12 @@ public class ValidationFacadeImpl implements ValidationFacade {
}
}
private Map<Long, GroupVirtualServer> validateGroupOnVses(List<GroupVirtualServer> groupOnVses, boolean virtual) throws ValidationException {
if (groupOnVses == null || groupOnVses.size() == 0)
throw new ValidationException("Group is missing `group-virtual-server` field.");
Map<Long, GroupVirtualServer> result = new HashMap<>();
for (int i = 0; i < groupOnVses.size(); i++) {
GroupVirtualServer e = groupOnVses.get(i);
if (e.getRewrite() != null && !e.getRewrite().isEmpty()) {
if (!PathRewriteParser.validate(e.getRewrite())) {
throw new ValidationException("Invalid `rewrite` field value. \"rewrite\" : " + e.getRewrite() + ".");
}
}
GroupVirtualServer prev = result.put(e.getVirtualServer().getId(), e);
if (prev != null) {
throw new ValidationException("Group can have and only have one combination to the same virtual-server. \"vs-id\" : " + e.getVirtualServer().getId() + ".");
}
if (virtual && e.getRedirect() == null) {
throw new ValidationException("Field `redirect` is not allowed empty if group is virtual type.");
}
}
return result;
}
private void validatePolicyRestriction(Map<Long, GroupVirtualServer> groupOnVses, List<LocationEntry> policyEntries) throws ValidationException {
if (policyEntries == null || policyEntries.size() == 0) return;
for (LocationEntry e : policyEntries) {
Long vsId = e.getVsId();
GroupVirtualServer gvs = groupOnVses.get(vsId);
if (gvs == null) {
throw new ValidationException("Group is missing combination on vs " + vsId + " referring its traffic policy " + e.getEntryId() + ".");
}
if (gvs.getPriority() == null) {
throw new ValidationException("Group with policies requires priority to be explicitly set.");
}
if (gvs.getPriority() > e.getPriority()) {
throw new ValidationException("Group has higher `priority` than its traffic policy " + e.getEntryId() + " on vs " + vsId + ".");
}
if (!gvs.getPath().equals(e.getPath())) {
throw new ValidationException("Group and its traffic policy " + e.getEntryId() + " do not have the same `path` value on vs " + vsId + ".");
}
}
}
private void validateMembers(List<GroupServer> servers) throws ValidationException {
if (servers == null || servers.size() == 0) return;
Set<byte[]> unique = new HashSet<>();
for (GroupServer s : servers) {
if (s.getIp() == null || s.getIp().isEmpty() || s.getPort() == null) {
throw new ValidationException("Group server ip and port cannot be null.");
}
byte[] ip = s.getIp().getBytes();
byte[] v = new byte[ip.length + 2];
for (int i = 2; i < v.length; i++) {
v[i] = ip[i - 2];
}
v[1] = ':';
v[0] = s.getPort().byteValue();
if (!unique.add(v)) {
throw new ValidationException("Duplicate combination of ip and port " + s.getIp() + ":" + s.getPort() + " is found in group server list.");
}
}
}
@Override
public void validatePolicy(TrafficPolicy policy, ValidationContext context) {
if (policy.getName() == null) {
context.error(policy.getId(), MetaType.TRAFFIC_POLICY, ErrorType.FIELD_VALIDATION, "Field `name` is empty.");
}
trafficPolicyValidator.validateFields(policy, context);
Long[] controlIds;
try {
controlIds = validatePolicyControl(policy);
controlIds = trafficPolicyValidator.validatePolicyControl(policy);
} catch (ValidationException e) {
context.error(policy.getId(), MetaType.TRAFFIC_POLICY, ErrorType.FIELD_VALIDATION, e.getMessage());
return;
@ -176,7 +92,7 @@ public class ValidationFacadeImpl implements ValidationFacade {
try {
Map<Long, List<LocationEntry>> groupEntries = vsEntryFactory.getGroupEntriesByVs(controlIds);
Map<Long, List<LocationEntry>> groupRelatedPolicyEntries = vsEntryFactory.getGroupRelatedPolicyEntriesByVs(controlIds);
policyOnVses = validatePolicyOnVses(policy.getId(), controlIds, groupEntries, policy.getPolicyVirtualServers(), groupRelatedPolicyEntries);
policyOnVses = trafficPolicyValidator.validatePolicyOnVses(policy.getId(), controlIds, groupEntries, policy.getPolicyVirtualServers(), groupRelatedPolicyEntries, null);
} catch (Exception e) {
context.error(policy.getId(), MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, e.getMessage());
return;
@ -205,86 +121,6 @@ public class ValidationFacadeImpl implements ValidationFacade {
}
}
private Long[] validatePolicyControl(TrafficPolicy policy) throws ValidationException {
Long[] groupIds = new Long[policy.getControls().size()];
for (int i = 0; i < policy.getControls().size(); i++) {
groupIds[i] = policy.getControls().get(i).getGroup().getId();
}
Arrays.sort(groupIds);
Long prev = groupIds[0];
for (int i = 1; i < groupIds.length; i++) {
if (prev.equals(groupIds[i])) {
throw new ValidationException("Traffic policy that you try to create/modify declares the same group " + prev + " more than once.");
}
prev = groupIds[i];
}
if (groupIds.length <= 1) {
throw new ValidationException("Traffic policy that you try to create/modify does not have enough traffic-controls.");
}
return groupIds;
}
private Map<Long, PolicyVirtualServer> validatePolicyOnVses(Long policyId, Long[] controlIds, Map<Long, List<LocationEntry>> groupEntries, List<PolicyVirtualServer> policyOnVses, Map<Long, List<LocationEntry>> groupRelatedPolicyEntries) throws ValidationException {
return validatePolicyOnVses(policyId, controlIds, groupEntries, policyOnVses, groupRelatedPolicyEntries, null);
}
private Map<Long, PolicyVirtualServer> validatePolicyOnVses(Long policyId, Long[] controlIds,
Map<Long, List<LocationEntry>> groupEntries, List<PolicyVirtualServer> policyOnVses,
Map<Long, List<LocationEntry>> groupRelatedPolicyEntries,
ValidationContext context) throws ValidationException {
ValidationContext _context = context == null ? new ValidationContext() : context;
Map<Long, PolicyVirtualServer> result = new HashMap<>();
int i = 0;
int[] visited = new int[controlIds.length];
for (PolicyVirtualServer e : policyOnVses) {
Long vsId = e.getVirtualServer().getId();
List<LocationEntry> another = groupRelatedPolicyEntries.get(vsId);
if (another != null && another.size() > 0) {
for (LocationEntry ee : another) {
if (!ee.getEntryId().equals(policyId)) {
String error = "Some other traffic policies have occupied traffic-controls on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(ee.getEntryId(), MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
}
i++;
for (LocationEntry ee : groupEntries.get(vsId)) {
int j = Arrays.binarySearch(controlIds, ee.getEntryId());
if (j < 0) continue;
visited[j] = i;
if (e.getPriority() < ee.getPriority()) {
String error = "Traffic policy has lower `priority` than its control item " + controlIds[j] + " on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(controlIds[j], MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
if (!e.getPath().equals(ee.getPath())) {
String error = "Traffic policy and its control item " + controlIds[j] + " does not have the same `path` value on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(controlIds[j], MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
for (int k = 0; k < visited.length; k++) {
if (visited[k] != i) {
String error = "Group " + controlIds[k] + " is missing combination on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(controlIds[k], MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
PolicyVirtualServer prev = result.put(vsId, e);
if (prev != null) {
String error = "Traffic policy can have and only have one combination to the same virtual-server. \"vs-id\" : " + e.getVirtualServer().getId() + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
return result;
}
@Override
public void validateVs(VirtualServer vs, ValidationContext context) {
@ -313,7 +149,7 @@ public class ValidationFacadeImpl implements ValidationFacade {
List<GroupVirtualServer> gvsToBeChecked = new ArrayList<>(1);
gvsToBeChecked.add(target);
try {
validateGroupOnVses(gvsToBeChecked, group.isVirtual());
groupModelValidator.validateGroupOnVses(gvsToBeChecked, group.isVirtual());
} catch (ValidationException e) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, e.getMessage());
}
@ -328,7 +164,7 @@ public class ValidationFacadeImpl implements ValidationFacade {
for (TrafficPolicy policy : policies) {
Long[] controlIds;
try {
controlIds = validatePolicyControl(policy);
controlIds = trafficPolicyValidator.validatePolicyControl(policy);
} catch (ValidationException e) {
context.error(policy.getId(), MetaType.TRAFFIC_POLICY, ErrorType.FIELD_VALIDATION, e.getMessage());
break;
@ -358,7 +194,7 @@ public class ValidationFacadeImpl implements ValidationFacade {
List<PolicyVirtualServer> _pvsToBeChecked = new ArrayList<>(1);
_pvsToBeChecked.add(target);
try {
validatePolicyOnVses(policy.getId(), controlIds, groupEntriesByVs, _pvsToBeChecked, _groupRelatedPolicyEntry, context);
trafficPolicyValidator.validatePolicyOnVses(policy.getId(), controlIds, groupEntriesByVs, _pvsToBeChecked, _groupRelatedPolicyEntry, context);
} catch (ValidationException e) {
context.error(policy.getId(), MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, e.getMessage());
}

View file

@ -9,8 +9,8 @@ import com.ctrip.zeus.model.entity.VirtualServer;
import com.ctrip.zeus.service.model.SelectionMode;
import com.ctrip.zeus.service.model.VirtualServerRepository;
import com.ctrip.zeus.service.model.handler.SlbQuery;
import com.ctrip.zeus.service.model.handler.SlbValidator;
import com.ctrip.zeus.service.model.handler.VirtualServerValidator;
import com.ctrip.zeus.service.model.validation.SlbValidator;
import com.ctrip.zeus.service.model.validation.VirtualServerValidator;
import com.ctrip.zeus.service.model.handler.impl.ContentReaders;
import com.ctrip.zeus.service.model.handler.impl.VirtualServerEntityManager;
import com.ctrip.zeus.service.nginx.CertificateService;

View file

@ -0,0 +1,169 @@
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.*;
import com.ctrip.zeus.service.model.PathRewriteParser;
import com.ctrip.zeus.service.model.common.ErrorType;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.MetaType;
import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.validation.GroupValidator;
import org.springframework.stereotype.Component;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.annotation.Resource;
import java.util.*;
/**
* Created by zhoumy on 2015/6/29.
*/
@Component("groupModelValidator")
public class DefaultGroupValidator implements GroupValidator {
@Resource
private RGroupVgDao rGroupVgDao;
@Resource
private RGroupStatusDao rGroupStatusDao;
@Resource
private GroupDao groupDao;
@Resource
private RTrafficPolicyGroupDao rTrafficPolicyGroupDao;
@Override
public boolean exists(Long targetId) throws Exception {
return exists(targetId, false);
}
@Override
public void validateFields(Group group, ValidationContext context) {
if (group.getName() == null || group.getName().isEmpty()
|| group.getAppId() == null || group.getAppId().isEmpty()) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, "Field `name` and `app-id` are not allowed empty.");
return;
}
if (group.getHealthCheck() != null
&& (group.getHealthCheck().getUri() == null || group.getHealthCheck().getUri().isEmpty())) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, "Field `health-check` is missing `uri` value.");
return;
}
try {
if (group.isVirtual() && (group.getGroupServers() != null && group.getGroupServers().size() > 0)) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, "Field `group-servers` is not allowed if group is virtual type.");
return;
}
validateMembers(group.getGroupServers());
} catch (ValidationException e) {
context.error(group.getId(), MetaType.GROUP, ErrorType.FIELD_VALIDATION, e.getMessage());
}
}
@Override
public boolean exists(Long targetId, boolean virtual) throws Exception {
boolean result = groupDao.findById(targetId, GroupEntity.READSET_FULL) != null;
RelGroupVgDo value = rGroupVgDao.findByGroup(targetId, RGroupVgEntity.READSET_FULL);
result &= (virtual ^ value == null);
return result;
}
@Override
public Map<Long, GroupVirtualServer> validateGroupOnVses(List<GroupVirtualServer> groupOnVses, boolean virtual) throws ValidationException {
if (groupOnVses == null || groupOnVses.size() == 0)
throw new ValidationException("Group is missing `group-virtual-server` field.");
Map<Long, GroupVirtualServer> result = new HashMap<>();
for (int i = 0; i < groupOnVses.size(); i++) {
GroupVirtualServer e = groupOnVses.get(i);
if (e.getRewrite() != null && !e.getRewrite().isEmpty()) {
if (!PathRewriteParser.validate(e.getRewrite())) {
throw new ValidationException("Invalid `rewrite` field value. \"rewrite\" : " + e.getRewrite() + ".");
}
}
GroupVirtualServer prev = result.put(e.getVirtualServer().getId(), e);
if (prev != null) {
throw new ValidationException("Group can have and only have one combination to the same virtual-server. \"vs-id\" : " + e.getVirtualServer().getId() + ".");
}
if (virtual && e.getRedirect() == null) {
throw new ValidationException("Field `redirect` is not allowed empty if group is virtual type.");
}
}
return result;
}
@Override
public void validateMembers(List<GroupServer> servers) throws ValidationException {
if (servers == null || servers.size() == 0) return;
Set<byte[]> unique = new HashSet<>();
for (GroupServer s : servers) {
if (s.getIp() == null || s.getIp().isEmpty() || s.getPort() == null) {
throw new ValidationException("Group server ip and port cannot be null.");
}
byte[] ip = s.getIp().getBytes();
byte[] v = new byte[ip.length + 2];
for (int i = 2; i < v.length; i++) {
v[i] = ip[i - 2];
}
v[1] = ':';
v[0] = s.getPort().byteValue();
if (!unique.add(v)) {
throw new ValidationException("Duplicate combination of ip and port " + s.getIp() + ":" + s.getPort() + " is found in group server list.");
}
}
}
@Override
public void validatePolicyRestriction(Map<Long, GroupVirtualServer> groupOnVses, List<LocationEntry> policyEntries) throws ValidationException {
if (policyEntries == null || policyEntries.size() == 0) return;
for (LocationEntry e : policyEntries) {
Long vsId = e.getVsId();
GroupVirtualServer gvs = groupOnVses.get(vsId);
if (gvs == null) {
throw new ValidationException("Group is missing combination on vs " + vsId + " referring its traffic policy " + e.getEntryId() + ".");
}
if (gvs.getPriority() == null) {
throw new ValidationException("Group with policies requires priority to be explicitly set.");
}
if (gvs.getPriority() > e.getPriority()) {
throw new ValidationException("Group has higher `priority` than its traffic policy " + e.getEntryId() + " on vs " + vsId + ".");
}
if (!gvs.getPath().equals(e.getPath())) {
throw new ValidationException("Group and its traffic policy " + e.getEntryId() + " do not have the same `path` value on vs " + vsId + ".");
}
}
}
@Override
public void validate(Group target) throws Exception {
throw new NotImplementedException();
}
@Override
public void checkVersionForUpdate(Group target) throws Exception {
RelGroupStatusDo check = rGroupStatusDao.findByGroup(target.getId(), RGroupStatusEntity.READSET_FULL);
if (check == null) {
throw new ValidationException("Group that you try to update does not exist.");
}
if (check.getOfflineVersion() > target.getVersion()) {
throw new ValidationException("Newer version is detected.");
}
if (check.getOfflineVersion() != target.getVersion()) {
throw new ValidationException("Incompatible version.");
}
}
@Override
public void removable(Long targetId) throws Exception {
RelGroupStatusDo check = rGroupStatusDao.findByGroup(targetId, RGroupStatusEntity.READSET_FULL);
if (check == null) return;
if (check.getOnlineVersion() != 0) {
throw new ValidationException("Group that you tried to delete is still active.");
}
if (rTrafficPolicyGroupDao.findByGroupsAndPolicyVersion(new Long[]{targetId}, RTrafficPolicyGroupEntity.READSET_FULL).size() > 0) {
throw new ValidationException("Group that you tried to delete has one or more traffic policy dependency.");
}
}
}

View file

@ -1,11 +1,11 @@
package com.ctrip.zeus.service.model.handler.impl;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.Slb;
import com.ctrip.zeus.model.entity.SlbServer;
import com.ctrip.zeus.service.model.IdVersion;
import com.ctrip.zeus.service.model.handler.SlbValidator;
import com.ctrip.zeus.service.model.validation.SlbValidator;
import com.ctrip.zeus.service.query.SlbCriteriaQuery;
import com.ctrip.zeus.service.query.VirtualServerCriteriaQuery;
import org.springframework.stereotype.Component;

View file

@ -0,0 +1,123 @@
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.PolicyVirtualServer;
import com.ctrip.zeus.model.entity.TrafficPolicy;
import com.ctrip.zeus.service.model.common.ErrorType;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.MetaType;
import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.validation.TrafficPolicyValidator;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* Created by zhoumy on 2017/2/6.
*/
@Service("trafficPolicyValidator")
public class DefaultTrafficPolicyValidator implements TrafficPolicyValidator {
@Override
public boolean exists(Long targetId) throws Exception {
return false;
}
@Override
public void validate(TrafficPolicy target) throws Exception {
}
@Override
public void checkVersionForUpdate(TrafficPolicy target) throws Exception {
}
@Override
public void removable(Long targetId) throws Exception {
}
@Override
public void validateFields(TrafficPolicy policy, ValidationContext context) {
if (policy.getName() == null) {
context.error(policy.getId(), MetaType.TRAFFIC_POLICY, ErrorType.FIELD_VALIDATION, "Field `name` is empty.");
}
}
@Override
public Long[] validatePolicyControl(TrafficPolicy policy) throws ValidationException {
Long[] groupIds = new Long[policy.getControls().size()];
for (int i = 0; i < policy.getControls().size(); i++) {
groupIds[i] = policy.getControls().get(i).getGroup().getId();
}
Arrays.sort(groupIds);
Long prev = groupIds[0];
for (int i = 1; i < groupIds.length; i++) {
if (prev.equals(groupIds[i])) {
throw new ValidationException("Traffic policy that you try to create/modify declares the same group " + prev + " more than once.");
}
prev = groupIds[i];
}
if (groupIds.length <= 1) {
throw new ValidationException("Traffic policy that you try to create/modify does not have enough traffic-controls.");
}
return groupIds;
}
@Override
public Map<Long, PolicyVirtualServer> validatePolicyOnVses(Long policyId, Long[] controlIds, Map<Long, List<LocationEntry>> groupEntries, List<PolicyVirtualServer> policyOnVses, Map<Long, List<LocationEntry>> groupRelatedPolicyEntries, ValidationContext context) throws ValidationException {
ValidationContext _context = context == null ? new ValidationContext() : context;
Map<Long, PolicyVirtualServer> result = new HashMap<>();
int i = 0;
int[] visited = new int[controlIds.length];
for (PolicyVirtualServer e : policyOnVses) {
Long vsId = e.getVirtualServer().getId();
List<LocationEntry> another = groupRelatedPolicyEntries.get(vsId);
if (another != null && another.size() > 0) {
for (LocationEntry ee : another) {
if (!ee.getEntryId().equals(policyId)) {
String error = "Some other traffic policies have occupied traffic-controls on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(ee.getEntryId(), MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
}
i++;
for (LocationEntry ee : groupEntries.get(vsId)) {
int j = Arrays.binarySearch(controlIds, ee.getEntryId());
if (j < 0) continue;
visited[j] = i;
if (e.getPriority() < ee.getPriority()) {
String error = "Traffic policy has lower `priority` than its control item " + controlIds[j] + " on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(controlIds[j], MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
if (!e.getPath().equals(ee.getPath())) {
String error = "Traffic policy and its control item " + controlIds[j] + " does not have the same `path` value on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(controlIds[j], MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
for (int k = 0; k < visited.length; k++) {
if (visited[k] != i) {
String error = "Group " + controlIds[k] + " is missing combination on vs " + vsId + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
_context.error(controlIds[k], MetaType.GROUP, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
PolicyVirtualServer prev = result.put(vsId, e);
if (prev != null) {
String error = "Traffic policy can have and only have one combination to the same virtual-server. \"vs-id\" : " + e.getVirtualServer().getId() + ".";
_context.error(policyId, MetaType.TRAFFIC_POLICY, ErrorType.DEPENDENCY_VALIDATION, error);
if (context == null) throw new ValidationException(error);
}
}
return result;
}
}

View file

@ -1,10 +1,10 @@
package com.ctrip.zeus.service.model.handler.impl;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.Domain;
import com.ctrip.zeus.model.entity.VirtualServer;
import com.ctrip.zeus.service.model.handler.VirtualServerValidator;
import com.ctrip.zeus.service.model.validation.VirtualServerValidator;
import com.ctrip.zeus.service.query.GroupCriteriaQuery;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicStringProperty;

View file

@ -0,0 +1,27 @@
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.Group;
import com.ctrip.zeus.model.entity.GroupServer;
import com.ctrip.zeus.model.entity.GroupVirtualServer;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.ValidationContext;
import java.util.List;
import java.util.Map;
/**
* Created by zhoumy on 2015/6/29.
*/
public interface GroupValidator extends ModelValidator<Group> {
void validateFields(Group group, ValidationContext context);
boolean exists(Long targetId, boolean virtual) throws Exception;
Map<Long, GroupVirtualServer> validateGroupOnVses(List<GroupVirtualServer> groupOnVses, boolean virtual) throws ValidationException;
void validateMembers(List<GroupServer> servers) throws ValidationException;
void validatePolicyRestriction(Map<Long, GroupVirtualServer> groupOnVses, List<LocationEntry> policyEntries) throws ValidationException;
}

View file

@ -1,4 +1,4 @@
package com.ctrip.zeus.service.model.handler;
package com.ctrip.zeus.service.model.validation;
/**
* Created by zhoumy on 2015/9/24.

View file

@ -1,4 +1,4 @@
package com.ctrip.zeus.service.model;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.service.model.common.LocationEntry;

View file

@ -1,9 +1,7 @@
package com.ctrip.zeus.service.model.handler;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.model.entity.Slb;
import java.util.Map;
/**
* Created by zhoumy on 2015/6/30.
*/

View file

@ -0,0 +1,25 @@
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.PolicyVirtualServer;
import com.ctrip.zeus.model.entity.TrafficPolicy;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.ValidationContext;
import java.util.List;
import java.util.Map;
/**
* Created by zhoumy on 2017/2/6.
*/
public interface TrafficPolicyValidator extends ModelValidator<TrafficPolicy> {
void validateFields(TrafficPolicy policy, ValidationContext context);
Long[] validatePolicyControl(TrafficPolicy policy) throws ValidationException;
Map<Long, PolicyVirtualServer> validatePolicyOnVses(Long policyId, Long[] controlIds,
Map<Long, List<LocationEntry>> groupEntries, List<PolicyVirtualServer> policyOnVses,
Map<Long, List<LocationEntry>> groupRelatedPolicyEntries,
ValidationContext context) throws ValidationException;
}

View file

@ -1,9 +1,8 @@
package com.ctrip.zeus.service.model.handler;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.model.entity.VirtualServer;
import java.util.List;
import java.util.Map;
/**
* Created by zhoumy on 2015/9/24.

View file

@ -1,4 +1,4 @@
package com.ctrip.zeus.service.model.handler;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.Group;

View file

@ -1,4 +1,4 @@
package com.ctrip.zeus.service.model.handler.impl;
package com.ctrip.zeus.service.model.validation;
import com.ctrip.zeus.dal.core.*;
import com.ctrip.zeus.exceptions.ValidationException;
@ -7,7 +7,7 @@ import com.ctrip.zeus.service.model.common.ErrorType;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.MetaType;
import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.handler.VsEntryFactory;
import com.ctrip.zeus.service.model.validation.VsEntryFactory;
import org.springframework.stereotype.Repository;
import org.unidal.dal.jdbc.DalException;

View file

@ -7,9 +7,9 @@ import com.ctrip.zeus.dal.core.RelGroupStatusDo;
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.grammar.GrammarException;
import com.ctrip.zeus.service.model.handler.GroupValidator;
import com.ctrip.zeus.service.model.validation.GroupValidator;
import com.ctrip.zeus.service.model.grammar.PathUtils;
import com.ctrip.zeus.service.model.validation.PathValidator;
import com.google.common.collect.Sets;
import org.junit.Assert;
import org.junit.Before;
@ -19,7 +19,6 @@ import org.unidal.dal.jdbc.DalException;
import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;
/**

View file

@ -6,6 +6,7 @@ import com.ctrip.zeus.model.entity.GroupVirtualServer;
import com.ctrip.zeus.service.model.common.LocationEntry;
import com.ctrip.zeus.service.model.common.MetaType;
import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.validation.PathValidator;
import com.ctrip.zeus.support.ObjectJsonParser;
import com.ctrip.zeus.util.TimerUtils;

View file

@ -6,6 +6,7 @@ import com.ctrip.zeus.service.model.common.ValidationContext;
import com.ctrip.zeus.service.model.grammar.GrammarException;
import com.ctrip.zeus.service.model.grammar.PathParseHandler;
import com.ctrip.zeus.service.model.grammar.PathUtils;
import com.ctrip.zeus.service.model.validation.PathValidator;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.junit.Test;