This commit is contained in:
fanqq 2015-07-31 10:09:13 +08:00
parent e4e0c779c3
commit f7afd49658
15 changed files with 252 additions and 84 deletions

View file

@ -29,7 +29,5 @@ public interface GroupRepository extends Repository {
int delete(Long groupId) throws Exception;
List<String> listGroupsByGroupServer(String groupServerIp) throws Exception;
List<Group> listGroupsByGroupServer(String groupServerIp) throws Exception;
}

View file

@ -14,5 +14,5 @@ public interface GroupValidator {
void removable(Long groupId) throws Exception;
boolean validateGroupVirtualServers(Long groupId, List<GroupVirtualServer> groupVirtualServers) throws Exception;
void validateGroupVirtualServers(Long groupId, List<GroupVirtualServer> groupVirtualServers) throws Exception;
}

View file

@ -1,11 +1,6 @@
package com.ctrip.zeus.service.model.handler;
import com.ctrip.zeus.dal.core.SlbDo;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.Slb;
import org.unidal.dal.jdbc.DalException;
import java.util.List;
/**
* @author:xingchaowang

View file

@ -1,16 +1,20 @@
package com.ctrip.zeus.service.model.handler;
import com.ctrip.zeus.exceptions.ValidationException;
import com.ctrip.zeus.model.entity.Slb;
import com.ctrip.zeus.model.entity.VirtualServer;
import java.util.List;
/**
* Created by zhoumy on 2015/6/30.
*/
public interface SlbValidator {
void validate(Slb slb) throws ValidationException;
void validate(Slb slb) throws Exception;
boolean removable(Slb slb) throws Exception;
void checkVirtualServerDependencies(Slb slb) throws Exception;
boolean modifiable(Slb slb) throws Exception;
void validateVirtualServer(List<VirtualServer> virtualServers) throws Exception;
void removable(Slb slb) throws Exception;
}

View file

@ -1,17 +1,17 @@
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.Group;
import com.ctrip.zeus.model.entity.GroupSlb;
import com.ctrip.zeus.model.entity.GroupVirtualServer;
import com.ctrip.zeus.model.entity.VirtualServer;
import com.ctrip.zeus.service.activate.ActiveConfService;
import com.ctrip.zeus.service.model.PathRewriteParser;
import com.ctrip.zeus.service.model.VirtualServerRepository;
import com.ctrip.zeus.service.model.handler.GroupValidator;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -24,7 +24,9 @@ public class DefaultGroupValidator implements GroupValidator {
@Resource
private ActiveConfService activeConfService;
@Resource
private VirtualServerRepository virtualServerRepository;
private SlbVirtualServerDao slbVirtualServerDao;
@Resource
private GroupSlbDao groupSlbDao;
@Override
public void validate(Group group) throws Exception {
@ -32,8 +34,7 @@ public class DefaultGroupValidator implements GroupValidator {
|| group.getAppId() == null || group.getAppId().isEmpty()) {
throw new ValidationException("Group with null value cannot be persisted.");
}
if (!validateGroupVirtualServers(group.getId(), group.getGroupVirtualServers()))
throw new ValidationException("Virtual server has invalid data.");
validateGroupVirtualServers(group.getId(), group.getGroupVirtualServers());
}
@Override
@ -44,9 +45,9 @@ public class DefaultGroupValidator implements GroupValidator {
}
@Override
public boolean validateGroupVirtualServers(Long groupId, List<GroupVirtualServer> groupVirtualServers) throws Exception {
public void validateGroupVirtualServers(Long groupId, List<GroupVirtualServer> groupVirtualServers) throws Exception {
if (groupVirtualServers == null || groupVirtualServers.size() == 0)
return false;
throw new ValidationException("No virtual server is found bound to this group.");
if (groupId == null)
groupId = 0L;
Set<Long> virtualServerIds = new HashSet<>();
@ -56,9 +57,9 @@ public class DefaultGroupValidator implements GroupValidator {
if (!PathRewriteParser.validate(groupVirtualServer.getRewrite()))
throw new ValidationException("Invalid rewrite value.");
VirtualServer vs = groupVirtualServer.getVirtualServer();
VirtualServer checkVs = virtualServerRepository.getById(vs.getId());
SlbVirtualServerDo checkVs = slbVirtualServerDao.findByPK(vs.getId(), SlbVirtualServerEntity.READSET_FULL);
if (checkVs == null) {
checkVs = virtualServerRepository.getBySlbAndName(vs.getSlbId(), vs.getName());
checkVs = slbVirtualServerDao.findBySlbAndName(vs.getSlbId(), vs.getName(), SlbVirtualServerEntity.READSET_FULL);
vs.setId(checkVs.getId());
}
if (checkVs == null)
@ -66,24 +67,23 @@ public class DefaultGroupValidator implements GroupValidator {
else
virtualServerIds.add(vs.getId());
if (groupPaths.contains(vs.getId() + groupVirtualServer.getPath()))
return false;
throw new ValidationException("Duplicate path \"" + groupVirtualServer.getPath() + "\" is found on virtual server " + vs.getId() + ".");
else
groupPaths.add(vs.getId() + groupVirtualServer.getPath());
}
for (Long virtualServerId : virtualServerIds) {
Long[] groupIds = virtualServerRepository.findGroupsByVirtualServer(virtualServerId);
for (int i = 0; i < groupIds.length; i++) {
if (groupIds[i].equals(groupId))
groupIds[i] = 0L;
List<Long> groupIds = new ArrayList<>();
for (GroupSlbDo groupSlb : groupSlbDao.findAllByVirtualServer(virtualServerId, GroupSlbEntity.READSET_FULL)) {
if (!groupId.equals(groupSlb.getGroupId()))
groupIds.add(groupSlb.getGroupId());
}
for (GroupVirtualServer gvs : virtualServerRepository.listGroupVsByGroups(groupIds)) {
if (groupPaths.contains(gvs.getVirtualServer().getId() + gvs.getPath()))
return false;
for (GroupSlbDo groupSlbDo : groupSlbDao.findAllByGroups(groupIds.toArray(new Long[groupIds.size()]), GroupSlbEntity.READSET_FULL)) {
if (groupPaths.contains(groupSlbDo.getSlbVirtualServerId() + groupSlbDo.getPath()))
throw new ValidationException("Duplicate path \"" + groupSlbDo.getPath() + "\" is found on virtual server " + groupSlbDo.getSlbVirtualServerId() + ".");
else
groupPaths.add(gvs.getVirtualServer().getId() + gvs.getPath());
groupPaths.add(groupSlbDo.getSlbVirtualServerId() + groupSlbDo.getPath());
}
}
return true;
}
}

View file

@ -18,25 +18,46 @@ import java.util.Set;
*/
@Component("slbModelValidator")
public class DefaultSlbValidator implements SlbValidator {
@Resource
private GroupSlbDao groupSlbDao;
@Resource
private SlbVirtualServerDao slbVirtualServerDao;
@Resource
private GroupSlbDao groupSlbDao;
@Override
public void validate(Slb slb) throws ValidationException {
public void validate(Slb slb) throws Exception {
if (slb == null || slb.getName() == null || slb.getName().isEmpty()) {
throw new ValidationException("Slb with null value cannot be persisted.");
}
if (slb.getSlbServers() == null || slb.getSlbServers().size() == 0) {
throw new ValidationException("Slb with invalid server data cannot be persisted.");
throw new ValidationException("Slb without slb servers cannot be persisted.");
}
validateVirtualServer(slb.getVirtualServers());
}
@Override
public void checkVirtualServerDependencies(Slb slb) throws Exception {
Set<Long> deleted = new HashSet<>();
for (SlbVirtualServerDo virtualServer : slbVirtualServerDao.findAllBySlb(slb.getId(), SlbVirtualServerEntity.READSET_FULL)) {
deleted.add(virtualServer.getId());
}
Set<String> existingHost = new HashSet<>();
for (VirtualServer virtualServer : slb.getVirtualServers()) {
deleted.remove(virtualServer);
}
for (Long vsId : deleted) {
if (groupSlbDao.findAllByVirtualServer(vsId, GroupSlbEntity.READSET_FULL).size() > 0)
throw new ValidationException("Virtual server with id " + vsId + "cannot be deleted. Dependencies exist.");
}
}
@Override
public void validateVirtualServer(List<VirtualServer> virtualServers) throws Exception {
Set<String> existingHost = new HashSet<>();
for (VirtualServer virtualServer : virtualServers) {
for (Domain domain : virtualServer.getDomains()) {
String key = domain.getName() + ":" + virtualServer.getPort();
if (existingHost.contains(key))
throw new ValidationException("Duplicate domain and port is found: " + key);
throw new ValidationException("Duplicate domain and port combination is found: " + key);
else
existingHost.add(key);
}
@ -44,12 +65,8 @@ public class DefaultSlbValidator implements SlbValidator {
}
@Override
public boolean removable(Slb slb) throws Exception {
return groupSlbDao.findAllBySlb(slb.getId(), GroupSlbEntity.READSET_FULL).size() == 0;
}
@Override
public boolean modifiable(Slb slb) throws Exception {
return true;
public void removable(Slb slb) throws Exception {
if (groupSlbDao.findAllBySlb(slb.getId(), GroupSlbEntity.READSET_FULL).size() > 0)
throw new ValidationException("Slb with id " + slb.getId() + " cannot be deleted. Dependencies exist.");
}
}

View file

@ -33,7 +33,7 @@ public class SlbSyncImpl implements SlbSync {
private VirtualServerRepository virtualServerRepository;
@Resource
private SlbValidator slbModelValidator;
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
@ -61,15 +61,12 @@ public class SlbSyncImpl implements SlbSync {
throw new ValidationException("Slb does not exist.");
if (check.getVersion() > slb.getVersion())
throw new ValidationException("Newer Slb version is detected.");
if (slbModelValidator.modifiable(slb)) {
SlbDo d = C.toSlbDo(slb.getId(), slb);
slbDao.updateById(d, SlbEntity.UPDATESET_FULL);
Long id = d.getId();
syncSlbVips(id, slb.getVips());
syncSlbServers(id, slb.getSlbServers());
} else {
throw new ValidationException(check.getName() + " cannot be updated. Dependency exists.");
}
slbModelValidator.checkVirtualServerDependencies(slb);
SlbDo d = C.toSlbDo(slb.getId(), slb);
slbDao.updateById(d, SlbEntity.UPDATESET_FULL);
Long id = d.getId();
syncSlbVips(id, slb.getVips());
syncSlbServers(id, slb.getSlbServers());
}
@Override
@ -77,13 +74,11 @@ public class SlbSyncImpl implements SlbSync {
SlbDo d = slbDao.findById(slbId, SlbEntity.READSET_FULL);
if (d == null)
return 0;
if (slbModelValidator.removable(C.toSlb(d))) {
slbVipDao.deleteBySlb(new SlbVipDo().setSlbId(slbId));
slbServerDao.deleteBySlb(new SlbServerDo().setSlbId(slbId));
virtualServerRepository.batchDeleteVirtualServers(slbId);
return slbDao.deleteByPK(d);
}
throw new ValidationException(d.getName() + " cannot be deleted. Dependency exists.");
slbModelValidator.removable(C.toSlb(d));
slbVipDao.deleteBySlb(new SlbVipDo().setSlbId(slbId));
slbServerDao.deleteBySlb(new SlbServerDo().setSlbId(slbId));
virtualServerRepository.batchDeleteVirtualServers(slbId);
return slbDao.deleteByPK(d);
}
private void syncSlbVips(Long slbId, List<Vip> vips) throws DalException {

View file

@ -99,12 +99,8 @@ public class GroupRepositoryImpl implements GroupRepository {
}
@Override
public List<String> listGroupsByGroupServer(String groupServerIp) throws Exception {
public List<Group> listGroupsByGroupServer(String groupServerIp) throws Exception {
Long[] groupIds = groupMemberRepository.findGroupsByGroupServerIp(groupServerIp);
List<String> result = new ArrayList<>();
for (Group group : groupQuery.batchGet(groupIds)) {
result.add(group.getName());
}
return result;
return groupQuery.batchGet(groupIds);
}
}

View file

@ -1,6 +1,5 @@
package com.ctrip.zeus.service.model.impl;
import com.ctrip.zeus.client.LocalClient;
import com.ctrip.zeus.dal.core.NginxServerDao;
import com.ctrip.zeus.dal.core.NginxServerDo;
import com.ctrip.zeus.exceptions.ValidationException;

View file

@ -4,9 +4,7 @@ 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.GroupVirtualServer;
import com.ctrip.zeus.model.entity.Slb;
import com.ctrip.zeus.model.entity.VirtualServer;
import com.ctrip.zeus.service.model.SlbRepository;
import com.ctrip.zeus.service.model.VirtualServerRepository;
import com.ctrip.zeus.support.C;
import com.google.common.base.Function;
@ -31,7 +29,7 @@ public class VirtualServerRepositoryImpl implements VirtualServerRepository {
@Resource
private SlbDomainDao slbDomainDao;
@Resource
private SlbRepository slbRepository;
private SlbDao slbDao;
@Override
public List<GroupVirtualServer> listGroupVsByGroups(Long[] groupIds) throws Exception {
@ -141,9 +139,12 @@ public class VirtualServerRepositoryImpl implements VirtualServerRepository {
GroupSlbDo originServer = originServers.get(groupVirtualServer.getVirtualServer().getId());
if (originServer != null)
originServers.remove(originServer.getSlbVirtualServerId());
Slb slb = slbRepository.getByVirtualServer(groupVirtualServer.getVirtualServer().getId());
SlbVirtualServerDo d = slbVirtualServerDao.findByPK(groupVirtualServer.getVirtualServer().getId(), SlbVirtualServerEntity.READSET_FULL);
if (d == null)
throw new ValidationException("Virtual server with id " + groupVirtualServer.getVirtualServer().getId() + " cannot be found.");
SlbDo slb = slbDao.findById(d.getSlbId(), SlbEntity.READSET_FULL);
if (slb == null)
throw new ValidationException("Cannot find the corresponding slb from virtual server.");
throw new ValidationException("Cannot find the corresponding slb from virtual server with id " + d.getId() + ".");
groupVirtualServer.getVirtualServer().setSlbId(slb.getId());
groupSlbDao.insert(toGroupSlbDo(groupId, groupVirtualServer));
}
@ -189,8 +190,7 @@ public class VirtualServerRepositoryImpl implements VirtualServerRepository {
private void querySlbDomains(Long slbVirtualServerId, VirtualServer virtualServer) throws DalException {
List<SlbDomainDo> list = slbDomainDao.findAllBySlbVirtualServer(slbVirtualServerId, SlbDomainEntity.READSET_FULL);
for (SlbDomainDo d : list) {
Domain e = C.toDomain(d);
virtualServer.addDomain(e);
virtualServer.addDomain(new Domain().setName(d.getName()));
}
}

View file

@ -0,0 +1,11 @@
package com.ctrip.zeus.service.task.constant;
/**
* Created by fanqq on 2015/7/30.
*/
public class TaskOpsType {
public static final String ACTIVATE_GROUP= "Activate_Group";
public static final String ACTIVATE_SLB= "Activate_SLB";
public static final String SERVER_OPS= "Server_Ops";
public static final String MEMBER_OPS= "Member_Ops";
}

View file

@ -0,0 +1,11 @@
package com.ctrip.zeus.service.task.constant;
/**
* Created by fanqq on 2015/7/30.
*/
public class TaskStatus {
public static final String PENDING= "Pending";
public static final String DOING= "Doing";
public static final String FAIL= "Fail";
public static final String SUCCESS= "Success";
}

View file

@ -2,7 +2,15 @@ package com.ctrip.zeus.service.woker.impl;
import com.ctrip.zeus.lock.DbLockFactory;
import com.ctrip.zeus.lock.DistLock;
import com.ctrip.zeus.model.entity.Group;
import com.ctrip.zeus.model.entity.GroupVirtualServer;
import com.ctrip.zeus.model.entity.Slb;
import com.ctrip.zeus.model.entity.VirtualServer;
import com.ctrip.zeus.service.model.GroupRepository;
import com.ctrip.zeus.service.model.SlbRepository;
import com.ctrip.zeus.service.task.TaskService;
import com.ctrip.zeus.service.task.constant.TaskOpsType;
import com.ctrip.zeus.service.task.constant.TaskStatus;
import com.ctrip.zeus.service.woker.TaskExecutor;
import com.ctrip.zeus.task.entity.OpsTask;
import com.netflix.config.DynamicIntProperty;
@ -12,7 +20,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.*;
/**
* Created by fanqq on 2015/7/29.
@ -24,11 +32,19 @@ public class TaskExecutorImpl implements TaskExecutor {
private DbLockFactory dbLockFactory;
@Resource
private TaskService taskService;
@Resource
private GroupRepository groupRepository;
@Resource
private SlbRepository slbRepository;
private static DynamicIntProperty lockTimeout = DynamicPropertyFactory.getInstance().getIntProperty("lock.timeout", 5000);
Logger logger = LoggerFactory.getLogger(this.getClass());
private HashMap<String , OpsTask> serverOps = new HashMap<>();
private HashMap<Long , OpsTask> activateGroupOps = new HashMap<>();
private HashMap<Long , OpsTask> activateSlbOps = new HashMap<>();
private HashMap<String , OpsTask> memberOps = new HashMap<>();
private List<VirtualServer> buildVirtualServer = new ArrayList<>();
private List<OpsTask> tasks = null;
@Override
public void execute(Long slbId) {
DistLock buildLock = dbLockFactory.newLock( "TaskWorker_" + slbId );
@ -44,7 +60,6 @@ public class TaskExecutorImpl implements TaskExecutor {
private void executeJob(Long slbId){
//1. get pending tasks , if size == 0 return
List<OpsTask> tasks = null;
try {
tasks = taskService.getPendingTasks(slbId);
}catch (Exception e){
@ -53,8 +68,133 @@ public class TaskExecutorImpl implements TaskExecutor {
}
if (tasks.size()==0) return;
//2. get all tasks datas
try {
getTaskData(slbId);
}catch (Exception e){
// failed
}
}
private void getTaskData(Long slbId){
//2. get all tasks datas
for (OpsTask task : tasks){
//Activate group
if (task.getOpsType().equals(TaskOpsType.ACTIVATE_GROUP)){
boolean flag = false;
try {
Group group = groupRepository.getById(task.getGroupId());
if (group==null){
task.setFailCause("Group Not Found!GroupId : "+ task.getGroupId());
task.setStatus(TaskStatus.FAIL);
continue;
}
for (GroupVirtualServer vs : group.getGroupVirtualServers()){
if(vs.getVirtualServer().getSlbId().equals(slbId)) {
buildVirtualServer.add(vs.getVirtualServer());
flag = true;
}
}
} catch (Exception e) {
logger.error("Get Group Fail! Can not read group from db!",e);
task.setFailCause("Get Group Fail!GroupId : "+ task.getGroupId());
task.setStatus(TaskStatus.FAIL);
continue;
}
if (!flag){
task.setFailCause("Task Info Error, Task target slbId is incorrect!GroupId : "+ task.getGroupId()+" SlbId:"+slbId);
task.setStatus(TaskStatus.FAIL);
continue;
}
activateGroupOps.put(task.getGroupId(),task);
}
//activate slb
if (task.getOpsType().equals(TaskOpsType.ACTIVATE_SLB)){
if (task.getSlbId().equals(slbId))
{
try {
Slb slb = slbRepository.getById(slbId);
if (slb==null){
task.setFailCause("Slb Not Found!SlbId : "+ task.getSlbId());
task.setStatus(TaskStatus.FAIL);
continue;
}
for (VirtualServer vs : slb.getVirtualServers()){
buildVirtualServer.add(vs);
}
}catch (Exception e){
logger.error("Get Slb Fail! Can not read Slb from db!",e);
task.setFailCause("Slb Not Found!SlbId : "+ task.getSlbId());
task.setStatus(TaskStatus.FAIL);
continue;
}
activateSlbOps.put(task.getSlbId(),task);
}
}
// server ops
if (task.getOpsType().equals(TaskOpsType.SERVER_OPS)){
boolean flag = false;
try {
List<Group> groupList = groupRepository.listGroupsByGroupServer(task.getIpList());
if (groupList==null){
task.setFailCause("Not Found Group by server ip!Server Ip : "+ task.getIpList());
task.setStatus(TaskStatus.FAIL);
continue;
}
for (Group group : groupList){
for (GroupVirtualServer groupVirtualServer : group.getGroupVirtualServers()){
if (groupVirtualServer.getVirtualServer().getSlbId().equals(slbId)){
buildVirtualServer.add(groupVirtualServer.getVirtualServer());
flag = true;
}
}
}
} catch (Exception e) {
task.setFailCause("Can Not Found Group by server ip!Server Ip : "+ task.getIpList());
task.setStatus(TaskStatus.FAIL);
continue;
}
if (flag){
serverOps.put(task.getIpList(),task);
}else{
task.setFailCause("Task Info Error, Task target slbId is incorrect!Server Ip : "+ task.getIpList()+" TargetSlbId:"+slbId);
task.setStatus(TaskStatus.FAIL);
}
}
//member ops
if (task.getOpsType().equals(TaskOpsType.MEMBER_OPS)){
boolean flag = false;
try {
Group group = groupRepository.getById(task.getGroupId());
if (group==null){
task.setFailCause("Group Not Found!GroupId : "+ task.getGroupId());
task.setStatus(TaskStatus.FAIL);
continue;
}
for (GroupVirtualServer vs : group.getGroupVirtualServers()){
if(vs.getVirtualServer().getSlbId().equals(slbId)) {
buildVirtualServer.add(vs.getVirtualServer());
flag = true;
}
}
} catch (Exception e) {
logger.error("Get Group Fail! Can not read group from db!",e);
task.setFailCause("Get Group Fail!GroupId : "+ task.getGroupId());
task.setStatus(TaskStatus.FAIL);
continue;
}
if (!flag){
task.setFailCause("Task Info Error, Task target slbId is incorrect!GroupId : "+ task.getGroupId()+" SlbId:"+slbId);
task.setStatus(TaskStatus.FAIL);
continue;
}
String[] iplist = task.getIpList().split(";");
for (String ip : iplist)
{
memberOps.put(task.getGroupId().toString()+"_"+ip,task);
}
}
}
}
}

View file

@ -370,13 +370,14 @@
<entity name="conf-group-active" table="conf_group_active" alias="cga">
<member name="id" field="id" value-type="long" length="19" nullable="false" key="true" auto-increment="true" />
<member name="group-id" field="group_id" value-type="long" length="19" nullable="false" />
<member name="slb-id" field="slb_id" value-type="long" length="19" nullable="false" />
<member name="content" field="content" value-type="String" length="16777215" />
<member name="version" field="version" value-type="int" length="10" />
<member name="created-time" field="created_time" value-type="Date" />
<member name="data-change-last-time" field="DataChange_LastTime" value-type="Date" nullable="false" />
<var name="key-id" value-type="long" key-member="id" />
<primary-key name="PRIMARY" members="id" />
<index name="group_id" unique="true" members="group_id ASC" />
<index name="group_id_slb_id" unique="true" members="group_id ASC, slb_id ASC" />
<index name="idx_DataChange_LastTime" members="DataChange_LastTime ASC" />
<readsets>
<readset name="FULL" all="true" />

View file

@ -11,6 +11,7 @@
FROM <TABLE/>
WHERE <FIELD name='status'/> = ${status}
AND <FIELD name='target-slb-id'/> = ${target-slb-id}
ORDER BY <FIELD name='id'/>
]]>
</statement>
</query>