diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index dd876f75ed3..e2857b8165e 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -94,6 +94,7 @@ public class ApiConstants { public static final String GSLB_SERVICE_DOMAIN_NAME = "gslbdomainname"; public static final String GSLB_SERVICE_TYPE = "gslbservicetype"; public static final String GSLB_STICKY_SESSION_METHOD = "gslbstickysessionmethodname"; + public static final String GSLB_LBRULE_WEIGHT_MAP = "gslblbruleweightsmap"; public static final String GUEST_CIDR_ADDRESS = "guestcidraddress"; public static final String GUEST_VLAN_RANGE = "guestvlanrange"; public static final String HA_ENABLE = "haenable"; diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java index 1575cd34d07..c66cc4637f4 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/AssignToGlobalLoadBalancerRuleCmd.java @@ -17,8 +17,10 @@ package org.apache.cloudstack.api.command.user.region.ha.gslb; +import com.cloud.dao.EntityManager; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.rules.LoadBalancer; import com.cloud.region.ha.GlobalLoadBalancerRule; import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.user.Account; @@ -31,7 +33,12 @@ import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; import javax.inject.Inject; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.UUID; @APICommand(name = "assignToGlobalLoadBalancerRule", description="Assign load balancer rule or list of load " + "balancer rules to a global load balancer rules.", responseObject=SuccessResponse.class) @@ -41,6 +48,8 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { private static final String s_name = "assigntogloballoadbalancerruleresponse"; + @Inject public EntityManager _entityMgr; + ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @@ -54,6 +63,12 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { "will be assigned to gloabal load balacner rule") private List loadBalancerRulesIds; + @Parameter(name=ApiConstants.GSLB_LBRULE_WEIGHT_MAP, type= CommandType.MAP, + description = "Map of LB rule id's and corresponding weights (between 1-100) in the GSLB rule, if not specified weight of " + + "a LB rule is defaulted to 1. Specified as 'gslblbruleweightsmap[0].loadbalancerid=UUID" + + "&gslblbruleweightsmap[0].weight=10'", required=false) + private Map gslbLbRuleWieghtMap; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -66,6 +81,36 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { return loadBalancerRulesIds; } + public Map getLoadBalancerRuleWeightMap() { + Map lbRuleWeightMap = new HashMap(); + + if (gslbLbRuleWieghtMap == null || gslbLbRuleWieghtMap.isEmpty()) { + return null; + } + + Collection lbruleWeightsCollection = gslbLbRuleWieghtMap.values(); + Iterator iter = lbruleWeightsCollection.iterator(); + while (iter.hasNext()) { + HashMap map = (HashMap) iter.next(); + Long weight; + LoadBalancer lbrule = _entityMgr.findByUuid(LoadBalancer.class, map.get("loadbalancerid")); + if (lbrule == null) { + throw new InvalidParameterValueException("Unable to find load balancer rule with ID: " + map.get("loadbalancerid")); + } + try { + weight = Long.parseLong(map.get("weight")); + if (weight < 1 || weight > 100) { + throw new InvalidParameterValueException("Invalid weight " + weight + " given for the LB rule id: " + map.get("loadbalancerid")); + } + } catch (NumberFormatException nfe) { + throw new InvalidParameterValueException("Unable to translate weight given for the LB rule id: " + map.get("loadbalancerid")); + } + lbRuleWeightMap.put(lbrule.getId(), weight); + } + + return lbRuleWeightMap; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java b/core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java index cca5de83102..44268e4cc1d 100644 --- a/core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java +++ b/core/src/com/cloud/agent/api/routing/SiteLoadBalancerConfig.java @@ -45,6 +45,9 @@ public class SiteLoadBalancerConfig { // zone id in which site is located long dataCenterId; + // wight corresponding to this site + long weight = 1; + public SiteLoadBalancerConfig(boolean revoked, String serviceType, String servicePublicIp, String servicePort, long dataCenterId) { this.revoked = revoked; @@ -118,4 +121,14 @@ public class SiteLoadBalancerConfig { public boolean forRevoke() { return revoked; } + + public void setWeight(long weight) { + assert(weight >= 1 && weight <= 100); + this.weight = weight; + } + + public long getWeight() { + return weight; + } + } \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java index 6a1e17decc3..b9c89a739b7 100644 --- a/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java +++ b/engine/schema/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java @@ -40,17 +40,21 @@ public class GlobalLoadBalancerLbRuleMapVO implements InternalIdentity { @Column(name="gslb_rule_id") private long gslbLoadBalancerId; + @Column(name="weight") + private long weight; + @Column(name="revoke") private boolean revoke = false; public GlobalLoadBalancerLbRuleMapVO() { - + this.weight = 1; } - public GlobalLoadBalancerLbRuleMapVO(long loadBalancerId, long gslbLoadBalancerId) { + public GlobalLoadBalancerLbRuleMapVO(long loadBalancerId, long gslbLoadBalancerId, long weight) { this.loadBalancerId = loadBalancerId; this.gslbLoadBalancerId = gslbLoadBalancerId; this.revoke = false; + this.weight = weight; } public long getId() { @@ -80,4 +84,12 @@ public class GlobalLoadBalancerLbRuleMapVO implements InternalIdentity { public void setRevoke(boolean revoke) { this.revoke = revoke; } + + public void setWeight(long weight) { + this.weight = weight; + } + + public long getWeight() { + return weight; + } } diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java index d25d4160e6b..eecae8a7ba5 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/resource/NetscalerResource.java @@ -902,7 +902,7 @@ public class NetscalerResource implements ServerResource { servicePublicIp, servicePublicPort, siteName); // Bind 'gslbservice' service object to GSLB virtual server - GSLB.createVserverServiceBinding(_netscalerService, serviceName, vserverName); + GSLB.createVserverServiceBinding(_netscalerService, serviceName, vserverName, site.getWeight()); // create a monitor for the service running on the site GSLB.createGslbServiceMonitor(_netscalerService, servicePublicIp, serviceName); @@ -1334,13 +1334,16 @@ public class NetscalerResource implements ServerResource { } } - private static void createVserverServiceBinding(nitro_service client, String serviceName, String vserverName) + private static void createVserverServiceBinding(nitro_service client, String serviceName, String vserverName, + long weight) throws ExecutionException { String errMsg; try { + assert(weight >= 1 && weight <= 100); gslbvserver_gslbservice_binding binding = new gslbvserver_gslbservice_binding(); binding.set_name(vserverName); binding.set_servicename(serviceName); + binding.set_weight(weight); gslbvserver_gslbservice_binding.add(client, binding); if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully created service: " + serviceName + " and virtual server: " diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java index d6e8d2d0cec..ad36fae60ec 100644 --- a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java @@ -235,6 +235,8 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR } } + Map lbRuleWeightMap = assignToGslbCmd.getLoadBalancerRuleWeightMap(); + Transaction txn = Transaction.currentTxn(); txn.start(); @@ -243,6 +245,9 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR GlobalLoadBalancerLbRuleMapVO newGslbLbMap = new GlobalLoadBalancerLbRuleMapVO(); newGslbLbMap.setGslbLoadBalancerId(gslbRuleId); newGslbLbMap.setLoadBalancerId(lbRuleId); + if (lbRuleWeightMap != null && lbRuleWeightMap.get(lbRuleId) != null) { + newGslbLbMap.setWeight(lbRuleWeightMap.get(lbRuleId)); + } _gslbLbMapDao.persist(newGslbLbMap); } @@ -633,6 +638,7 @@ public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingR siteLb.setGslbProviderPublicIp(_gslbProvider.getZoneGslbProviderPublicIp(dataCenterId, physicalNetworkId)); siteLb.setGslbProviderPrivateIp(_gslbProvider.getZoneGslbProviderPrivateIp(dataCenterId, physicalNetworkId)); + siteLb.setWeight(gslbLbMapVo.getWeight()); zoneSiteLoadbalancerMap.put(network.getDataCenterId(), siteLb); } diff --git a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java index ab545342cfa..6d49ec01c8c 100644 --- a/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java +++ b/server/test/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImplTest.java @@ -748,7 +748,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { phyNetworkId.set(networkVo, new Long(200)); when(gslbServiceImpl._networkDao.findById(new Long(1))).thenReturn(networkVo); - GlobalLoadBalancerLbRuleMapVO gslbLbMap = new GlobalLoadBalancerLbRuleMapVO(1, 1); + GlobalLoadBalancerLbRuleMapVO gslbLbMap = new GlobalLoadBalancerLbRuleMapVO(1, 1, 1); List listSslbLbMap = new ArrayList(); listSslbLbMap.add(gslbLbMap); when(gslbServiceImpl._gslbLbMapDao.listByGslbRuleId(new Long(1))).thenReturn(listSslbLbMap); @@ -950,7 +950,7 @@ public class GlobalLoadBalancingRulesServiceImplTest extends TestCase { when(gslbServiceImpl._gslbRuleDao.findById(new Long(1))).thenReturn(gslbRule); - GlobalLoadBalancerLbRuleMapVO gslbLmMap = new GlobalLoadBalancerLbRuleMapVO(1,1); + GlobalLoadBalancerLbRuleMapVO gslbLmMap = new GlobalLoadBalancerLbRuleMapVO(1,1,1); List gslbLbMapVos = new ArrayList(); gslbLbMapVos.add(gslbLmMap); when(gslbServiceImpl._gslbLbMapDao.listByGslbRuleId(new Long(1))).thenReturn(gslbLbMapVos); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 0c1d753486e..f5b79e9a027 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -513,6 +513,7 @@ CREATE TABLE `cloud`.`global_load_balancer_lb_rule_map` ( `id` bigint unsigned NOT NULL auto_increment, `gslb_rule_id` bigint unsigned NOT NULL, `lb_rule_id` bigint unsigned NOT NULL, + `weight` bigint unsigned NOT NULL DEFAULT 1 COMMENT 'weight of the site in gslb', `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 is when rule is set for Revoke', PRIMARY KEY (`id`), UNIQUE KEY (`gslb_rule_id`, `lb_rule_id`),