package com.sobey.cmop.mvc.service.iaas; import java.util.Collection; import java.util.List; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.sobey.cmop.mvc.comm.BaseSevcie; import com.sobey.cmop.mvc.constant.IpPoolConstant; import com.sobey.cmop.mvc.constant.NetworkConstant; import com.sobey.cmop.mvc.constant.ResourcesConstant; import com.sobey.cmop.mvc.dao.EipPortItemDao; import com.sobey.cmop.mvc.dao.NetworkEipItemDao; import com.sobey.cmop.mvc.entity.Apply; import com.sobey.cmop.mvc.entity.Change; import com.sobey.cmop.mvc.entity.EipPortItem; import com.sobey.cmop.mvc.entity.NetworkEipItem; import com.sobey.cmop.mvc.entity.Resources; import com.sobey.cmop.mvc.entity.ServiceTag; /** * 公网IPNetworkEipItem相关的管理类. * * @author liukai */ @Service @Transactional(readOnly = true) public class EipService extends BaseSevcie { private static Logger logger = LoggerFactory.getLogger(EipService.class); @Resource private NetworkEipItemDao networkEipItemDao; @Resource private EipPortItemDao eipPortItemDao; // ========= EipPortItem ==========// /** * 新增,保存ELB映射端口. * * @param elbPortItem * @return */ @Transactional(readOnly = false) public EipPortItem saveOrUpdateEipPortItem(EipPortItem eipPortItem) { return eipPortItemDao.save(eipPortItem); } /** * 获得指定NetworkEipItem下的所有端口ElbPortItem * * @param computeItemId * @return */ public List<EipPortItem> getEipPortItemListByEipId(Integer eipId) { return eipPortItemDao.findByNetworkEipItemId(eipId); } /** * 删除端口信息 * * @param eipPortItems */ @Transactional(readOnly = false) public void deleteEipPortItem(Collection<EipPortItem> eipPortItems) { eipPortItemDao.delete(eipPortItems); } // ========= NetworkEipItem ==========// public NetworkEipItem getNetworkEipItem(Integer id) { return networkEipItemDao.findOne(id); } @Transactional(readOnly = false) public NetworkEipItem saveOrUpdate(NetworkEipItem networkEipItem) { return networkEipItemDao.save(networkEipItem); } @Transactional(readOnly = false) public void deleteNetworkEipItem(Integer id) { if (this.getNetworkEipItem(id) != null) { networkEipItemDao.delete(id); } } /** * 获得指定用户的所有eip * * @return */ public List<NetworkEipItem> getNetworkEipItemListByUserId(Integer userId) { return networkEipItemDao.findByApplyUserId(userId); } public List<NetworkEipItem> getNetworkEipItemListByComputeItemId(Integer computeItemId) { return networkEipItemDao.findByComputeItemId(computeItemId); } /** * 保存EIP的服务申请.(在服务申请时调用) * * @param applyId * @param ispTypes * ISP运营商的ID * @param linkTypes * 关联类型,区分关联的是ELB还是实例. 0:ELB ; 1: 实例 * @param linkIds * 关联ID * @param protocols * 协议数组 格式{1-2-3,4-5-6}下同 * @param sourcePorts * 源端口数组 * @param targetPorts * 目标端口数组 * @param redirectAttributes * 关联实例数组 * @return */ @Transactional(readOnly = false) public void saveEIPToApply(Integer applyId, String[] ispTypes, String[] linkTypes, String[] linkIds, String[] protocols, String[] sourcePorts, String[] targetPorts) { Apply apply = comm.applyService.getApply(applyId); logger.info("创建EIP的数量:" + ispTypes.length); for (int i = 0; i < ispTypes.length; i++) { String identifier = comm.applyService.generateIdentifier(ResourcesConstant.ServiceType.EIP.toInteger()); NetworkEipItem networkEipItem = new NetworkEipItem(); networkEipItem.setApply(apply); networkEipItem.setIdentifier(identifier); networkEipItem.setIpAddress(IpPoolConstant.DEFAULT_IPADDRESS); networkEipItem.setOldIp(IpPoolConstant.DEFAULT_IPADDRESS); networkEipItem.setIspType(Integer.valueOf(ispTypes[i])); // 判断关联类型,根据关联类型和关联ID获得对象后封装至NetworkEipItem. if (linkIds != null && linkIds.length > 0) { networkEipItem = this.fillComputeOrElbToNetworkEipItem(networkEipItem, linkTypes[i], linkIds[i]); } this.saveOrUpdate(networkEipItem); // EIP的端口映射 if (sourcePorts != null && sourcePorts.length > 0) { String[] protocolArray = StringUtils.split(protocols[i], NetworkConstant.SEPARATE_PORT_SYMBOL); String[] sourcePortArray = StringUtils.split(sourcePorts[i], NetworkConstant.SEPARATE_PORT_SYMBOL); String[] targetPortArray = StringUtils.split(targetPorts[i], NetworkConstant.SEPARATE_PORT_SYMBOL); for (int j = 0; j < protocolArray.length; j++) { EipPortItem eipPortItem = new EipPortItem(networkEipItem, protocolArray[j], sourcePortArray[j], targetPortArray[j]); this.saveOrUpdateEipPortItem(eipPortItem); } } } } /** * 修改EIP的服务申请.(在服务申请时调用) * * <pre> * 1.先将EIP下的所有映射信息删除. * 2.判断关联ID是compute还是elb的. * 3.保存ELB和端口映射. * </pre> * * @param networkEipItem * EIP对象 * @param linkType * 关联类型 * @param linkId * 关联ID * @param protocols * 协议数组 * @param sourcePorts * 源端口数组 * @param targetPorts * 目标端口数组 */ @Transactional(readOnly = false) public void updateEIPToApply(NetworkEipItem networkEipItem, String linkType, String linkId, String[] protocols, String[] sourcePorts, String[] targetPorts) { // Step.1 this.deleteEipPortItem(this.getEipPortItemListByEipId(networkEipItem.getId())); // Step.2 // 判断关联类型,根据关联类型和关联ID获得对象后封装至NetworkEipItem. networkEipItem = this.fillComputeOrElbToNetworkEipItem(networkEipItem, linkType, linkId); // Step.3 this.saveOrUpdate(networkEipItem); // ELB的端口映射 if (sourcePorts != null && sourcePorts.length > 0) { for (int i = 0; i < protocols.length; i++) { EipPortItem eipPortItem = new EipPortItem(networkEipItem, protocols[i], sourcePorts[i], targetPorts[i]); this.saveOrUpdateEipPortItem(eipPortItem); } } } /** * 变更EIP * * @param resources * 资源对象 * @param serviceTagId * 服务标签ID * @param linkType * 关联类型 * @param linkId * 关联ID * @param protocols * 协议数组 * @param sourcePorts * 源端口数组 * @param targetPorts * 目标端口数组 * @param changeDescription * 变更说明 */ @Transactional(readOnly = false) public void saveResourcesByEip(Resources resources, Integer serviceTagId, String linkType, String linkId, String[] protocols, String[] sourcePorts, String[] targetPorts, String changeDescription) { /* 新增或更新资源Resources的服务变更Change. */ Change change = comm.changeServcie.saveOrUpdateChangeByResources(resources, changeDescription); NetworkEipItem networkEipItem = this.getNetworkEipItem(resources.getServiceId()); List<EipPortItem> eipPortItems = this.getEipPortItemListByEipId(networkEipItem.getId()); /* 比较资源变更前和变更后的值. */ boolean isChange = comm.compareResourcesService.compareEip(resources, change, networkEipItem, eipPortItems, linkType, linkId, protocols, sourcePorts, targetPorts); // 删除变更前的端口映射 this.deleteEipPortItem(eipPortItems); ServiceTag serviceTag = comm.serviceTagService.getServiceTag(serviceTagId); // 当资源有更改的时候,更改状态.如果和资源不相关的如:服务标签,指派人等变更,则不变更资源的状态. if (isChange) { serviceTag.setStatus(ResourcesConstant.Status.已变更.toInteger()); resources.setStatus(ResourcesConstant.Status.已变更.toInteger()); } resources.setServiceTag(serviceTag); comm.serviceTagService.saveOrUpdate(serviceTag); // 判断关联类型,根据关联类型和关联ID获得对象后封装至NetworkEipItem. networkEipItem = this.fillComputeOrElbToNetworkEipItem(networkEipItem, linkType, linkId); this.saveOrUpdate(networkEipItem); // EIP的端口映射 if (sourcePorts != null && sourcePorts.length > 0) { for (int i = 0; i < protocols.length; i++) { EipPortItem eipPortItem = new EipPortItem(networkEipItem, protocols[i], sourcePorts[i], targetPorts[i]); this.saveOrUpdateEipPortItem(eipPortItem); } } // 更新resources comm.resourcesService.saveOrUpdate(resources); } /** * 判断关联类型,根据关联类型和关联ID获得对象后封装至NetworkEipItem. * * @return */ private NetworkEipItem fillComputeOrElbToNetworkEipItem(NetworkEipItem networkEipItem, String linkType, String linkId) { if (NetworkConstant.LinkType.关联实例.toString().equals(linkType)) { // 关联实例 if (!"".equals(linkId)) { networkEipItem.setComputeItem(comm.computeService.getComputeItem(Integer.valueOf(linkId))); } else { networkEipItem.setComputeItem(null); } networkEipItem.setNetworkElbItem(null); } else if (NetworkConstant.LinkType.关联ELB.toString().equals(linkType) && !"".equals(linkId)) { // 关联ELB if (!"".equals(linkId)) { networkEipItem.setNetworkElbItem(comm.elbService.getNetworkElbItem(Integer.valueOf(linkId))); } else { networkEipItem.setNetworkElbItem(null); } networkEipItem.setComputeItem(null); } return networkEipItem; } public List<NetworkEipItem> getEipListByApplyId(Integer applyId) { return networkEipItemDao.findByApplyId(applyId); } }