diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index b2259a0e226..eb2a0783b73 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -81,6 +81,7 @@ import com.cloud.network.dao.NetworkDomainDaoImpl; import com.cloud.network.dao.NetworkRuleConfigDaoImpl; import com.cloud.network.lb.ElasticLoadBalancerManagerImpl; import com.cloud.network.lb.LoadBalancingRulesManagerImpl; +import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl; import com.cloud.network.ovs.OvsNetworkManagerImpl; import com.cloud.network.ovs.OvsTunnelManagerImpl; import com.cloud.network.ovs.dao.GreTunnelDaoImpl; @@ -270,6 +271,8 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("DcDetailsDao", DcDetailsDaoImpl.class); addDao("SwiftDao", SwiftDaoImpl.class); addDao("AgentTransferMapDao", HostTransferMapDaoImpl.class); + addDao("ElasticLbVmMap", ElasticLbVmMapDaoImpl.class); + } @Override diff --git a/server/src/com/cloud/network/ElasticLbVmMapVO.java b/server/src/com/cloud/network/ElasticLbVmMapVO.java new file mode 100644 index 00000000000..394f3ac2793 --- /dev/null +++ b/server/src/com/cloud/network/ElasticLbVmMapVO.java @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.network; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.SecondaryTable; +import javax.persistence.SecondaryTables; +import javax.persistence.Table; + +import com.cloud.utils.net.Ip; + +@Entity +@Table(name = ("elastic_lb_vm_map")) +@SecondaryTables({ + @SecondaryTable(name = "user_ip_address", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "ip_addr_id", referencedColumnName = "id") }) + }) +public class ElasticLbVmMapVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "lb_id") + private Long lbId; + + @Column(name = "ip_addr_id") + private long ipAddressId; + + @Column(name = "elb_vm_id") + private long elbVmId; + + /*@Column(name = "name", table = "load_balancing_rules", insertable = false, updatable = false) + private String lbName;*/ + + @Column(name = "public_ip_address", table = "user_ip_address", insertable = false, updatable = false) + @Enumerated(value=EnumType.STRING) + private Ip address = null; + + public ElasticLbVmMapVO() { + } + + public ElasticLbVmMapVO(long ipId, long elbVmId) { + this.ipAddressId = ipId; + this.elbVmId = elbVmId; + } + + public Long getId() { + return id; + } + + public long getLbId() { + return lbId; + } + + + public long getElbVmId() { + return elbVmId; + } + + +// public String getLbName() { +// return lbName; +// } + + + public long getIpAddressId() { + return ipAddressId; + } + + public void setLbId(Long lbId) { + this.lbId = lbId; + } + + public Ip getAddress() { + return address; + } + +} + diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManager.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManager.java index 3fa840e7f00..a7a65b16000 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManager.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManager.java @@ -30,8 +30,8 @@ import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; public interface ElasticLoadBalancerManager { - public static final int DEFAULT_ELB_VM_RAMSIZE = 512; // 512 MB - public static final int DEFAULT_ELB_VM_CPU_MHZ = 500; // 500 MHz + public static final int DEFAULT_ELB_VM_RAMSIZE = 128; // 512 MB + public static final int DEFAULT_ELB_VM_CPU_MHZ = 256; // 500 MHz public boolean applyLoadBalancerRules(Network network, List rules) diff --git a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 267c3e29070..b2ddb990654 100644 --- a/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/server/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved. * * This software is licensed under the GNU General Public License v3 or later. * @@ -18,8 +18,6 @@ package com.cloud.network.lb; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,10 +40,8 @@ import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; import com.cloud.dc.Pod; import com.cloud.dc.PodVlanMapVO; -import com.cloud.dc.VlanVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; @@ -60,20 +56,19 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; +import com.cloud.network.ElasticLbVmMapVO; import com.cloud.network.IPAddressVO; -import com.cloud.network.IpAddress; import com.cloud.network.LoadBalancerVO; import com.cloud.network.Network; +import com.cloud.network.Network.GuestIpType; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; -import com.cloud.network.PublicIpAddress; -import com.cloud.network.Network.GuestIpType; -import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.LoadBalancingRule.LbDestination; +import com.cloud.network.lb.dao.ElasticLbVmMapDao; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; @@ -83,7 +78,6 @@ import com.cloud.network.rules.LoadBalancer; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.org.Cluster; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.VMTemplateVO; @@ -96,7 +90,7 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; -import com.cloud.utils.net.NetUtils; +import com.cloud.utils.db.Transaction; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; @@ -153,6 +147,8 @@ public class ElasticLoadBalancerManagerImpl implements VlanDao _vlanDao; @Inject PodVlanMapDao _podVlanMapDao; + @Inject + ElasticLbVmMapDao _elbVmMapDao; String _name; @@ -271,11 +267,12 @@ public class ElasticLoadBalancerManagerImpl implements } protected DomainRouterVO findElbVmForLb(FirewallRule lb) {//TODO: use a table to lookup - List elbVms = _routerDao.listByNetworkAndRole(lb.getNetworkId(), Role.LB); - if (elbVms != null && elbVms.size() > 0) - return elbVms.get(0); - - return null; + ElasticLbVmMapVO map = _elbVmMapDao.findOneByIp(lb.getSourceIpAddressId()); + if (map == null) { + return null; + } + DomainRouterVO elbVm = _routerDao.findById(map.getElbVmId()); + return elbVm; } public boolean applyLoadBalancerRules(Network network, @@ -366,7 +363,6 @@ public class ElasticLoadBalancerManagerImpl implements return null; } - @DB public DomainRouterVO deployELBVm(Network guestNetwork, DeployDestination dest, Account owner, Map params) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { long dcId = dest.getDataCenter().getId(); @@ -397,13 +393,7 @@ public class ElasticLoadBalancerManagerImpl implements DataCenterDeployment plan = null; DomainRouterVO elbVm = null; - //router = _routerDao.findByNetworkAndPodAndRole(guestNetwork.getId(), podId, Role.LB); - plan = new DataCenterDeployment(dcId, null, null, null, null); - - // } else { - // s_logger.debug("Not deploying elastic ip vm"); - // return null; - // } + plan = new DataCenterDeployment(dcId, dest.getPod().getId(), null, null, null); if (elbVm == null) { long id = _routerDao.getNextInSequence(Long.class, "id"); @@ -452,27 +442,50 @@ public class ElasticLoadBalancerManagerImpl implements } @Override + @DB public void handleCreateLoadBalancerRule( LoadBalancer lb, Account account) { + long ipId = lb.getSourceIpAddressId(); IPAddressVO ipAddr = _ipAddressDao.findById(ipId); Long networkId= ipAddr.getSourceNetworkId(); NetworkVO network=_networkDao.findById(networkId); - DomainRouterVO elbVm = null; - if (network.getGuestType() == GuestIpType.Direct) { - LoadBalancerVO lbvo; - lbvo = _lbDao.findByAccountAndName(account.getId(), lb.getName()); - if (lbvo == null) { - elbVm = findELBVmWithCapacity(network, ipAddr); - if (elbVm == null) { - elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId()); - } - IPAddressVO ipvo = _ipAddressDao.findById(ipId); - ipvo.setAssociatedWithNetworkId(networkId); - _ipAddressDao.update(ipvo.getId(), ipvo); - - } - + + if (network.getGuestType() != GuestIpType.Direct) { + s_logger.info("Elastic LB Manager: not handling guest traffic of type " + network.getGuestType()); + return; } + DomainRouterVO elbVm = null; + + LoadBalancerVO lbvo; + lbvo = _lbDao.findByAccountAndName(account.getId(), lb.getName()); + if (lbvo == null) { + elbVm = findELBVmWithCapacity(network, ipAddr); + if (elbVm == null) { + elbVm = deployLoadBalancerVM(networkId, ipAddr, account.getId()); + if (elbVm == null) { + s_logger.warn("Failed to deploy a new ELB vm for ip " + ipAddr + " in network " + network + "lb name=" + lb.getName()); + return; //TODO: throw exception + } + } + + } else { + ElasticLbVmMapVO elbVmMap = _elbVmMapDao.findOneByIp(lb.getSourceIpAddressId()); + if (elbVmMap != null) { + elbVm = _routerDao.findById(elbVmMap.getElbVmId()); + } + } + if (elbVm == null) { + s_logger.warn("No ELB VM can be found or deployed"); + return; + } + Transaction txn = Transaction.currentTxn(); + txn.start(); + IPAddressVO ipvo = _ipAddressDao.findById(ipId); + ipvo.setAssociatedWithNetworkId(networkId); + _ipAddressDao.update(ipvo.getId(), ipvo); + ElasticLbVmMapVO mapping = new ElasticLbVmMapVO(ipId, elbVm.getId()); + _elbVmMapDao.persist(mapping); + txn.commit(); } diff --git a/server/src/com/cloud/network/lb/dao/ElasticLbVmMapDao.java b/server/src/com/cloud/network/lb/dao/ElasticLbVmMapDao.java new file mode 100644 index 00000000000..50729f5647c --- /dev/null +++ b/server/src/com/cloud/network/lb/dao/ElasticLbVmMapDao.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.network.lb.dao; + +import java.util.List; + +import com.cloud.network.ElasticLbVmMapVO; +import com.cloud.utils.db.GenericDao; + +public interface ElasticLbVmMapDao extends GenericDao { + ElasticLbVmMapVO findOneByLbIdAndElbVmId(long lbId, long elbVmId); + ElasticLbVmMapVO findOneByIpIdAndElbVmId(long ipId, long elbVmId); + ElasticLbVmMapVO findOneByIp(long ipId); + + List listByElbVmId(long elbVmId); + List listByLbId(long lbId); + int deleteLB(long lbId); + +} diff --git a/server/src/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java b/server/src/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java new file mode 100644 index 00000000000..71a5d4b5663 --- /dev/null +++ b/server/src/com/cloud/network/lb/dao/ElasticLbVmMapDaoImpl.java @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2011 Citrix Systems, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package com.cloud.network.lb.dao; + +import java.util.List; + +import javax.ejb.Local; + +import com.cloud.network.ElasticLbVmMapVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Local(value={ElasticLbVmMapDao.class}) +public class ElasticLbVmMapDaoImpl extends GenericDaoBase implements ElasticLbVmMapDao { + private SearchBuilder AllFieldsSearch; + + protected ElasticLbVmMapDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("ipId", AllFieldsSearch.entity().getIpAddressId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("lbId", AllFieldsSearch.entity().getLbId(), SearchCriteria.Op.EQ); + AllFieldsSearch.and("elbVmId", AllFieldsSearch.entity().getElbVmId(), SearchCriteria.Op.EQ); + AllFieldsSearch.done(); + + } + + @Override + public ElasticLbVmMapVO findOneByLbIdAndElbVmId(long lbId, long elbVmId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("lbId", lbId); + sc.setParameters("elbVmId", elbVmId); + return findOneBy(sc); + } + + @Override + public List listByLbId(long lbId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("lbId", lbId); + return listBy(sc); + } + + @Override + public List listByElbVmId(long elbVmId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("elbVmId", elbVmId); + return listBy(sc); + } + + @Override + public int deleteLB(long lbId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("lbId", lbId); + return super.expunge(sc); + } + + @Override + public ElasticLbVmMapVO findOneByIpIdAndElbVmId(long ipId, long elbVmId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ipId", ipId); + sc.setParameters("elbVmId", elbVmId); + return findOneBy(sc); + } + + @Override + public ElasticLbVmMapVO findOneByIp(long ipId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ipId", ipId); + return findOneBy(sc); + } + + +} diff --git a/server/test/com/cloud/network/dao/ElbVmMapDaoTest.java b/server/test/com/cloud/network/dao/ElbVmMapDaoTest.java new file mode 100644 index 00000000000..50dd7aefcf3 --- /dev/null +++ b/server/test/com/cloud/network/dao/ElbVmMapDaoTest.java @@ -0,0 +1,20 @@ +package com.cloud.network.dao; + +import junit.framework.TestCase; + +import com.cloud.network.ElasticLbVmMapVO; +import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl; +import com.cloud.utils.component.ComponentLocator; + +public class ElbVmMapDaoTest extends TestCase { + public void testTags() { + ElasticLbVmMapDaoImpl dao = ComponentLocator.inject(ElasticLbVmMapDaoImpl.class); + + ElasticLbVmMapVO map = dao.findOneByIp(3); + if (map == null) { + System.out.println("Not Found"); + } else { + System.out.println("Found"); + } + } +} diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 3d49570ec02..329edd072bb 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -1542,4 +1542,15 @@ CREATE TABLE `cloud`.`op_host_transfer` ( CONSTRAINT `fk_op_host_transfer__future_mgmt_server_id` FOREIGN KEY `fk_op_host_transfer__future_mgmt_server_id`(`future_mgmt_server_id`) REFERENCES `mshost`(`msid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`elastic_lb_vm_map` ( + `id` bigint unsigned NOT NULL auto_increment, + `ip_addr_id` bigint unsigned NOT NULL, + `elb_vm_id` bigint unsigned NOT NULL, + `lb_id` bigint unsigned, + PRIMARY KEY (`id`), + CONSTRAINT `fk_elastic_lb_vm_map__ip_id` FOREIGN KEY `fk_elastic_lb_vm_map__ip_id` (`ip_addr_id`) REFERENCES `user_ip_address` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_elastic_lb_vm_map__elb_vm_id` FOREIGN KEY `fk_elastic_lb_vm_map__elb_vm_id` (`elb_vm_id`) REFERENCES `domain_router` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_elastic_lb_vm_map__lb_id` FOREIGN KEY `fk_elastic_lb_vm_map__lb_id` (`lb_id`) REFERENCES `load_balancing_rules` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1;