diff --git a/api/src/com/cloud/region/ha/GlobalLoadBalancer.java b/api/src/com/cloud/region/ha/GlobalLoadBalancer.java index dcbd749612c..3d9f25efe98 100644 --- a/api/src/com/cloud/region/ha/GlobalLoadBalancer.java +++ b/api/src/com/cloud/region/ha/GlobalLoadBalancer.java @@ -16,13 +16,52 @@ // under the License. package com.cloud.region.ha; -import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; /** * Definition for a GlobalLoadBalancer */ -public interface GlobalLoadBalancer extends ControlledEntity, Identity, InternalIdentity { +public interface GlobalLoadBalancer extends Identity, InternalIdentity { + enum Algorithm { + + RoundRobin, + LeastConn, + Proximity; + + public static boolean isValidAlgorithm(String algorithm) { + if (RoundRobin.name().equalsIgnoreCase(algorithm) || + LeastConn.name().equalsIgnoreCase(algorithm) || + Proximity.name().equalsIgnoreCase(algorithm)) { + return true; + } + return false; + } + } + enum Persistence { + + sourceip; + + public static boolean isValidPersistence(String persistence) { + if (sourceip.name().equalsIgnoreCase(persistence)) { + return true; + } + return false; + } + } + + public String getName(); + + public String getDescription(); + + public String getGslbDomain(); + + public String getAlgorithm(); + + public String getPersistence(); + + public int getRegion(); + + public long getAccountId(); } diff --git a/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java b/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java index 69845610f9c..2a4115bc089 100644 --- a/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java +++ b/api/src/com/cloud/region/ha/GlobalLoadBalancingRulesService.java @@ -17,6 +17,29 @@ package com.cloud.region.ha; +import org.apache.cloudstack.api.command.user.region.ha.gslb.*; + +import java.security.spec.InvalidParameterSpecException; +import java.util.List; + public interface GlobalLoadBalancingRulesService { + /* + * methods for managing life cycle of global load balancing rules + */ + GlobalLoadBalancer createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd createGslbCmd) throws InvalidParameterSpecException; + + boolean deleteGlobalLoadBalancerRule(DeleteGlobalLoadBalancerRuleCmd deleteGslbCmd); + + GlobalLoadBalancer updateGlobalLoadBalancerRule(UpdateGlobalLoadBalancerRuleCmd updateGslbCmd); + + List listGlobalLoadBalancerRule(ListGlobalLoadBalancerRuleCmd listGslbCmd); + + /* + * methods for managing sites participating in global load balancing + */ + boolean assignToGlobalLoadBalancerRule(AssignToGlobalLoadBalancerRuleCmd assignToGslbCmd); + + boolean removeFromGlobalLoadBalancerRule(RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd); + } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 2df1472e83d..720a131cf1d 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -77,6 +77,9 @@ public class ApiConstants { public static final String IP6_GATEWAY = "ip6gateway"; public static final String GROUP = "group"; public static final String GROUP_ID = "groupid"; + public static final String GSLB_LB_METHOD = "gslblbmethod"; + public static final String GSLB_SERVICE_DOMAIN_NAME = "gslbdomainname"; + public static final String GSLB_STICKY_SESSION_METHOD = "gslbstickysessionmethodname"; public static final String GUEST_CIDR_ADDRESS = "guestcidraddress"; public static final String HA_ENABLE = "haenable"; public static final String HOST_ID = "hostid"; diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index b95f182c32f..58f7504dea5 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -16,85 +16,6 @@ // under the License. package org.apache.cloudstack.api; -import java.text.DecimalFormat; -import java.util.EnumSet; -import java.util.List; - -import org.apache.cloudstack.api.ApiConstants.HostDetails; -import org.apache.cloudstack.api.ApiConstants.VMDetails; -import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; -import org.apache.cloudstack.api.response.AccountResponse; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.AutoScalePolicyResponse; -import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; -import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; -import org.apache.cloudstack.api.response.CapacityResponse; -import org.apache.cloudstack.api.response.ClusterResponse; -import org.apache.cloudstack.api.response.ConditionResponse; -import org.apache.cloudstack.api.response.ConfigurationResponse; -import org.apache.cloudstack.api.response.CounterResponse; -import org.apache.cloudstack.api.response.CreateCmdResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.ExtractResponse; -import org.apache.cloudstack.api.response.FirewallResponse; -import org.apache.cloudstack.api.response.FirewallRuleResponse; -import org.apache.cloudstack.api.response.GuestOSResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; -import org.apache.cloudstack.api.response.IPAddressResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.IpForwardingRuleResponse; -import org.apache.cloudstack.api.response.LBStickinessResponse; -import org.apache.cloudstack.api.response.LDAPConfigResponse; -import org.apache.cloudstack.api.response.LoadBalancerResponse; -import org.apache.cloudstack.api.response.NetworkACLResponse; -import org.apache.cloudstack.api.response.NetworkOfferingResponse; -import org.apache.cloudstack.api.response.NetworkResponse; -import org.apache.cloudstack.api.response.PhysicalNetworkResponse; -import org.apache.cloudstack.api.response.PodResponse; -import org.apache.cloudstack.api.response.PrivateGatewayResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ProviderResponse; -import org.apache.cloudstack.api.response.RegionResponse; -import org.apache.cloudstack.api.response.RemoteAccessVpnResponse; -import org.apache.cloudstack.api.response.ResourceCountResponse; -import org.apache.cloudstack.api.response.ResourceLimitResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.S3Response; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.ServiceResponse; -import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse; -import org.apache.cloudstack.api.response.SnapshotPolicyResponse; -import org.apache.cloudstack.api.response.SnapshotResponse; -import org.apache.cloudstack.api.response.SnapshotScheduleResponse; -import org.apache.cloudstack.api.response.StaticRouteResponse; -import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.SwiftResponse; -import org.apache.cloudstack.api.response.SystemVmInstanceResponse; -import org.apache.cloudstack.api.response.SystemVmResponse; -import org.apache.cloudstack.api.response.TemplatePermissionsResponse; -import org.apache.cloudstack.api.response.TemplateResponse; -import org.apache.cloudstack.api.response.TrafficTypeResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VirtualRouterProviderResponse; -import org.apache.cloudstack.api.response.VlanIpRangeResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.VpcOfferingResponse; -import org.apache.cloudstack.api.response.VpcResponse; -import org.apache.cloudstack.api.response.VpnUsersResponse; -import org.apache.cloudstack.api.response.ZoneResponse; -import org.apache.cloudstack.region.Region; - import com.cloud.async.AsyncJob; import com.cloud.capacity.Capacity; import com.cloud.configuration.Configuration; @@ -108,29 +29,11 @@ import com.cloud.domain.Domain; import com.cloud.event.Event; import com.cloud.host.Host; import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Service; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteCustomerGateway; -import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VpnUser; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScaleVmGroup; -import com.cloud.network.as.AutoScaleVmProfile; -import com.cloud.network.as.Condition; -import com.cloud.network.as.Counter; +import com.cloud.network.as.*; import com.cloud.network.router.VirtualRouter; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.StaticNatRule; -import com.cloud.network.rules.StickinessPolicy; +import com.cloud.network.rules.*; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityRule; import com.cloud.network.vpc.PrivateGateway; @@ -144,13 +47,9 @@ import com.cloud.org.Cluster; import com.cloud.projects.Project; import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; +import com.cloud.region.ha.GlobalLoadBalancer; import com.cloud.server.ResourceTag; -import com.cloud.storage.GuestOS; -import com.cloud.storage.S3; -import com.cloud.storage.Snapshot; -import com.cloud.storage.StoragePool; -import com.cloud.storage.Swift; -import com.cloud.storage.Volume; +import com.cloud.storage.*; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.storage.snapshot.SnapshotSchedule; import com.cloud.template.VirtualMachineTemplate; @@ -160,6 +59,15 @@ import com.cloud.user.UserAccount; import com.cloud.uservm.UserVm; import com.cloud.vm.InstanceGroup; import com.cloud.vm.VirtualMachine; +import org.apache.cloudstack.api.ApiConstants.HostDetails; +import org.apache.cloudstack.api.ApiConstants.VMDetails; +import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; +import org.apache.cloudstack.api.response.*; +import org.apache.cloudstack.region.Region; + +import java.text.DecimalFormat; +import java.util.EnumSet; +import java.util.List; public interface ResponseGenerator { UserResponse createUserResponse(UserAccount user); @@ -198,6 +106,8 @@ public interface ResponseGenerator { IPAddressResponse createIPAddressResponse(IpAddress ipAddress); + GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancer globalLoadBalancer); + LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer); LBStickinessResponse createLBStickinessPolicyResponse(List stickinessPolicies, LoadBalancer lb); 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 7e2cc5be20e..4fc90ad0965 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 @@ -21,6 +21,7 @@ import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.LoadBalancer; import com.cloud.region.ha.GlobalLoadBalancer; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.StringUtils; @@ -30,6 +31,7 @@ import org.apache.cloudstack.api.response.LoadBalancerResponse; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; +import javax.inject.Inject; import java.util.List; @APICommand(name = "assignToGlobalLoadBalancerRule", description="Assign load balancer rule or list of load " + @@ -69,6 +71,9 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + @Inject + public GlobalLoadBalancingRulesService _gslbService; + @Override public String getCommandName() { return s_name; @@ -98,7 +103,7 @@ public class AssignToGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { public void execute(){ UserContext.current().setEventDetails("Global Load balancer rule Id: "+ getGlobalLoadBalancerId()+ " VmIds: " + StringUtils.join(getLoadBalancerRulesId(), ",")); - boolean result = _lbService.assignToLoadBalancer(getGlobalLoadBalancerId(), loadBalancerRulesIds); + boolean result = _gslbService.assignToGlobalLoadBalancerRule(this); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java index f010f812eca..b764c25c239 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/CreateGlobalLoadBalancerRuleCmd.java @@ -19,20 +19,19 @@ package org.apache.cloudstack.api.command.user.region.ha.gslb; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.user.Account; +import com.cloud.region.ha.GlobalLoadBalancer; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.user.UserContext; -import org.apache.cloudstack.api.APICommand; -import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.BaseAsyncCreateCmd; -import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.*; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse; import org.apache.cloudstack.api.response.RegionResponse; import org.apache.log4j.Logger; +import javax.inject.Inject; + @APICommand(name = "createGlobalLoadBalancerRule", description="Creates a global load balancer rule", responseObject=GlobalLoadBalancerResponse.class) public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd { @@ -45,17 +44,14 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ALGORITHM, type=CommandType.STRING, required=true, description="load balancer algorithm (source, roundrobin, leastconn)") - private String algorithm; + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="name of the load balancer rule") + private String globalLoadBalancerRuleName; @Parameter(name=ApiConstants.DESCRIPTION, type=CommandType.STRING, description="the description of the load balancer rule", length=4096) private String description; - @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="name of the load balancer rule") - private String globalLoadBalancerRuleName; - - @Parameter(name=ApiConstants.REGION_ID, type= CommandType.UUID, entityType = RegionResponse.class, required=true, description="region where the global load balancer is going to be created.") - private Long regionId; + @Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, entityType = RegionResponse.class, required=true, description="region where the global load balancer is going to be created.") + private Integer regionId; @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="the account associated with the global load balancer. Must be used with the domainId parameter.") private String accountName; @@ -63,27 +59,51 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd { @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType = DomainResponse.class, description="the domain ID associated with the load balancer") private Long domainId; + @Parameter(name=ApiConstants.GSLB_LB_METHOD, type=CommandType.STRING, required=false, description="load balancer algorithm (roundrobin, leastconn, proximity) " + + "that is used to distributed traffic across the zones participating in global server load balancing, if not specified defaults to 'round robin'") + private String algorithm; + + @Parameter(name=ApiConstants.GSLB_STICKY_SESSION_METHOD, type=CommandType.STRING, required=false, description="session sticky method (sourceip) if not specified defaults to sourceip") + private String stickyMethod; + + @Parameter(name=ApiConstants.GSLB_SERVICE_DOMAIN_NAME, type = CommandType.STRING, required = true, description = "domain name for the GSLB service.") + private String serviceDomainName; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - public String getAlgorithm() { - return algorithm; + public String getName() { + return globalLoadBalancerRuleName; } public String getDescription() { return description; } - public String getGlobalLoadBalancerRuleName() { - return globalLoadBalancerRuleName; + public String getAlgorithm() { + return algorithm; } - - public String getName() { - return globalLoadBalancerRuleName; + public String getGslbMethod() { + return algorithm; } + public String getStickyMethod() { + return stickyMethod; + } + + public String getServiceDomainName() { + return serviceDomainName; + } + + public Integer getRegionId() { + return regionId; + } + + @Inject + private GlobalLoadBalancingRulesService _gslbService; + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -97,19 +117,28 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd { public void execute() throws ResourceAllocationException, ResourceUnavailableException { UserContext callerContext = UserContext.current(); - - try { - UserContext.current().setEventDetails("Rule Id: " + getEntityId()); - } catch (Exception ex) { - - }finally { - + GlobalLoadBalancer rule = _entityMgr.findById(GlobalLoadBalancer.class, getEntityId()); + GlobalLoadBalancerResponse response = null; + if (rule != null) { + response = _responseGenerator.createGlobalLoadBalancerResponse(rule); + setResponseObject(response); } + response.setResponseName(getCommandName()); } @Override public void create() { + try { + GlobalLoadBalancer gslbRule = _gslbService.createGlobalLoadBalancerRule(this); + this.setEntityId(gslbRule.getId()); + this.setEntityUuid(gslbRule.getUuid()); + UserContext.current().setEventDetails("Rule Id: " + getEntityId()); + } catch (Exception ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage()); + }finally { + } } @Override @@ -130,24 +159,14 @@ public class CreateGlobalLoadBalancerRuleCmd extends BaseAsyncCreateCmd { @Override public long getEntityOwnerId() { - return getAccountId(); + Long accountId = finalyzeAccountId(accountName, domainId, null, true); + if (accountId == null) { + return UserContext.current().getCaller().getId(); + } + return accountId; } public String getAccountName() { return accountName; } - - public long getAccountId() { - Account account = null; - if ((domainId != null) && (accountName != null)) { - account = _responseGenerator.findAccountByNameDomain(accountName, domainId); - if (account != null) { - return account.getId(); - } else { - throw new InvalidParameterValueException("Unable to find account " + account + " in domain id=" + domainId); - } - } else { - throw new InvalidParameterValueException("Can't define IP owner. Either specify account/domainId or publicIpId"); - } - } } diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java index 690e5d09b49..0d185df629a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/DeleteGlobalLoadBalancerRuleCmd.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.api.command.user.region.ha.gslb; import com.cloud.async.AsyncJob; import com.cloud.event.EventTypes; import com.cloud.region.ha.GlobalLoadBalancer; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.user.Account; import com.cloud.user.UserContext; import org.apache.cloudstack.api.*; @@ -27,6 +28,8 @@ import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; +import javax.inject.Inject; + @APICommand(name = "deleteGlobalLoadBalancerRule", description="Deletes a global load balancer rule.", responseObject=SuccessResponse.class) public class DeleteGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { @@ -59,6 +62,9 @@ public class DeleteGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { return s_name; } + @Inject + public GlobalLoadBalancingRulesService _gslbService; + @Override public long getEntityOwnerId() { GlobalLoadBalancer lb = _entityMgr.findById(GlobalLoadBalancer.class, getGlobalLoadBalancerId()); @@ -81,6 +87,7 @@ public class DeleteGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { @Override public void execute(){ + _gslbService.deleteGlobalLoadBalancerRule(this); UserContext.current().setEventDetails("Deleting global Load balancer Id: " + getGlobalLoadBalancerId()); } diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java index e759a821914..2ff605c9be7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/ListGlobalLoadBalancerRuleCmd.java @@ -25,7 +25,7 @@ import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse; import org.apache.cloudstack.api.response.RegionResponse; import org.apache.log4j.Logger; -@APICommand(name = "listLoadBalancerRules", description = "Lists load balancer rules.", responseObject = GlobalLoadBalancerResponse.class) +@APICommand(name = "listGlobalLoadBalancerRules", description = "Lists load balancer rules.", responseObject = GlobalLoadBalancerResponse.class) public class ListGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(ListGlobalLoadBalancerRuleCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java index 9f114dc5545..31bae9e479d 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/RemoveFromGlobalLoadBalancerRuleCmd.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.user.region.ha.gslb; import com.cloud.event.EventTypes; import com.cloud.region.ha.GlobalLoadBalancer; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import com.cloud.user.Account; import com.cloud.utils.StringUtils; import org.apache.cloudstack.api.APICommand; @@ -30,9 +31,11 @@ import org.apache.cloudstack.api.response.LoadBalancerResponse; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; +import javax.inject.Inject; import java.util.List; -@APICommand(name = "removeFromGlobalLoadBalancerRule", description="Removes a load balancer rule association with global load balancer rule", responseObject=SuccessResponse.class) +@APICommand(name = "removeFromGlobalLoadBalancerRule", description="Removes a load balancer rule association with" + + " global load balancer rule", responseObject=SuccessResponse.class) public class RemoveFromGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveFromGlobalLoadBalancerRuleCmd.class.getName()); @@ -47,7 +50,8 @@ public class RemoveFromGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { private Long id; @Parameter(name=ApiConstants.LOAD_BALANCER_RULE_LIST, type=CommandType.LIST, collectionType=CommandType.UUID, - entityType = LoadBalancerResponse.class, required=true, description="the list load balancer rules that " + "will be assigned to gloabal load balacner rule") + entityType = LoadBalancerResponse.class, required=true, description="the list load balancer rules that " + + "will be assigned to gloabal load balacner rule") private List loadBalancerRulesIds; ///////////////////////////////////////////////////// @@ -66,6 +70,9 @@ public class RemoveFromGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + @Inject + public GlobalLoadBalancingRulesService _gslbService; + @Override public String getCommandName() { return s_name; @@ -87,12 +94,13 @@ public class RemoveFromGlobalLoadBalancerRuleCmd extends BaseAsyncCmd { @Override public String getEventDescription() { - return "removing load balancer rules:" + StringUtils.join(getLoadBalancerRulesId(), ",") + " from global load balancer: " + getGlobalLoadBalancerId(); + return "removing load balancer rules:" + StringUtils.join(getLoadBalancerRulesId(), ",") + + " from global load balancer: " + getGlobalLoadBalancerId(); } @Override public void execute(){ - + boolean response = _gslbService.removeFromGlobalLoadBalancerRule(this); } @Override diff --git a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java index 85ced6dad7a..a5368f32730 100644 --- a/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/region/ha/gslb/UpdateGlobalLoadBalancerRuleCmd.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.user.region.ha.gslb; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; @@ -26,7 +27,9 @@ import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse; import org.apache.cloudstack.api.response.LoadBalancerResponse; import org.apache.log4j.Logger; -@APICommand(name = "updateGlobalLoadBalancerRules", description = "update global load balancer rules.", responseObject = LoadBalancerResponse.class) +import javax.inject.Inject; + +@APICommand(name = "updateGlobalLoadBalancerRule", description = "update global load balancer rules.", responseObject = LoadBalancerResponse.class) public class UpdateGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd { public static final Logger s_logger = Logger.getLogger(GlobalLoadBalancerResponse.class.getName()); @@ -53,6 +56,9 @@ public class UpdateGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// + @Inject + public GlobalLoadBalancingRulesService _gslbService; + @Override public String getCommandName() { return s_name; @@ -60,7 +66,7 @@ public class UpdateGlobalLoadBalancerRuleCmd extends BaseListTaggedResourcesCmd @Override public void execute() { - + _gslbService.updateGlobalLoadBalancerRule(this); } } diff --git a/api/src/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java b/api/src/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java index cb16391d8b8..b168ae81ab9 100644 --- a/api/src/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java +++ b/api/src/org/apache/cloudstack/api/response/GlobalLoadBalancerResponse.java @@ -16,32 +16,107 @@ // under the License. package org.apache.cloudstack.api.response; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; public class GlobalLoadBalancerResponse extends BaseResponse implements ControlledEntityResponse { - @Override + @SerializedName(ApiConstants.ID) + @Param(description = "global load balancer rule ID") + private String id; + + @SerializedName(ApiConstants.NAME) + @Param(description = "name of the global load balancer rule") + private String name; + + @SerializedName(ApiConstants.DESCRIPTION) + @Param(description = "the description of the global load balancer rule") + private String description; + + @SerializedName(ApiConstants.GSLB_SERVICE_DOMAIN_NAME) + @Param(description = "DNS domain name given for the global load balancer") + private String gslbDomainName; + + @SerializedName(ApiConstants.GSLB_LB_METHOD) + @Param(description = "Load balancing method used for the global load balancer") + private String algorithm; + + @SerializedName(ApiConstants.GSLB_STICKY_SESSION_METHOD) + @Param(description = "session persistence method used for the global load balancer") + private String stickyMethod; + + @SerializedName(ApiConstants.REGION_ID) + @Param(description = "Region Id in which global load balancer is created") + private Integer regionId; + + @SerializedName(ApiConstants.ACCOUNT) + @Param(description = "the account of the load balancer rule") + private String accountName; + + @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the load balancer") + private String projectId; + + @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the load balancer") + private String projectName; + + @SerializedName(ApiConstants.DOMAIN_ID) + @Param(description = "the domain ID of the load balancer rule") + private String domainId; + + @SerializedName(ApiConstants.DOMAIN) + @Param(description = "the domain of the load balancer rule") + private String domainName; + + public void setRegionIdId(Integer regionId) { + this.regionId = regionId; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public void setStickyMethod(String stickyMethod) { + this.stickyMethod = stickyMethod; + } + + public void setServiceDomainName(String domainName) { + this.gslbDomainName = domainName; + } + public void setAccountName(String accountName) { - //To change body of implemented methods use File | Settings | File Templates. + this.accountName = accountName; } @Override public void setProjectId(String projectId) { - //To change body of implemented methods use File | Settings | File Templates. + this.projectId = projectId; } @Override public void setProjectName(String projectName) { - //To change body of implemented methods use File | Settings | File Templates. + this.projectName = projectName; } @Override public void setDomainId(String domainId) { - //To change body of implemented methods use File | Settings | File Templates. + this.domainId = domainId; } - @Override public void setDomainName(String domainName) { - //To change body of implemented methods use File | Settings | File Templates. + this.domainName = domainName; } } diff --git a/api/src/org/apache/cloudstack/region/Region.java b/api/src/org/apache/cloudstack/region/Region.java index 7f0aeeab2ef..87b028b3d58 100644 --- a/api/src/org/apache/cloudstack/region/Region.java +++ b/api/src/org/apache/cloudstack/region/Region.java @@ -16,6 +16,9 @@ // under the License. package org.apache.cloudstack.region; +import java.util.ArrayList; +import java.util.List; + /** * */ @@ -32,4 +35,50 @@ public interface Region { public String getApiKey(); public String getSecretKey(); + + public boolean checkIfServiceEnabled(Service service); + + /** + * A region level service, is a service that constitute services across one or more zones in the region or a service + * made available to all the zones in the region. + */ + public static class Service { + + private String name; + private static List regionServices = new ArrayList(); + + public static final Service Gslb = new Service("Gslb"); + + public Service(String name ) { + this.name = name; + regionServices.add(this); + } + + public String getName() { + return name; + } + + } + + /** + * A provider provides the region level service in a zone. + */ + public static class Provider { + + private static List supportedProviders = new ArrayList(); + private String name; + private Service service; + + public static final Provider Netscaler = new Provider("Netscaler", Service.Gslb); + + public Provider(String name, Service service) { + this.name = name; + this.service = service; + supportedProviders.add(this); + } + + public String getName() { + return name; + } + } } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index d70649bf318..fd9e7335d07 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -537,3 +537,12 @@ addRegion=1 updateRegion=1 removeRegion=1 listRegions=15 + + +#### GSLB (Global Server Load Balancing) commands +createGlobalLoadBalancerRule=15 +deleteGlobalLoadBalancerRule=15 +updateGlobalLoadBalancerRule=15 +listGlobalLoadBalancerRules=15 +assignToGlobalLoadBalancerRule=15 +removeFromGlobalLoadBalancerRule=15 diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 411de946f56..8fe0ee07c50 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -19,82 +19,6 @@ package com.cloud.api; import com.cloud.api.query.ViewResponseHelper; import com.cloud.api.query.vo.*; import com.cloud.api.response.ApiResponseSerializer; -import org.apache.cloudstack.api.response.AsyncJobResponse; -import org.apache.cloudstack.api.response.AutoScalePolicyResponse; -import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; -import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; -import org.apache.cloudstack.api.response.CapabilityResponse; -import org.apache.cloudstack.api.response.CapacityResponse; -import org.apache.cloudstack.api.response.ClusterResponse; -import org.apache.cloudstack.api.response.ConditionResponse; -import org.apache.cloudstack.api.response.ConfigurationResponse; -import org.apache.cloudstack.api.response.ControlledEntityResponse; -import org.apache.cloudstack.api.response.CounterResponse; -import org.apache.cloudstack.api.response.CreateCmdResponse; -import org.apache.cloudstack.api.response.DiskOfferingResponse; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.DomainRouterResponse; -import org.apache.cloudstack.api.response.EventResponse; -import org.apache.cloudstack.api.response.ExtractResponse; -import org.apache.cloudstack.api.response.FirewallResponse; -import org.apache.cloudstack.api.response.FirewallRuleResponse; -import org.apache.cloudstack.api.response.GuestOSResponse; -import org.apache.cloudstack.api.response.HostResponse; -import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse; -import org.apache.cloudstack.api.response.ControlledViewEntityResponse; -import org.apache.cloudstack.api.response.IPAddressResponse; -import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.IpForwardingRuleResponse; -import org.apache.cloudstack.api.response.LBStickinessPolicyResponse; -import org.apache.cloudstack.api.response.LBStickinessResponse; -import org.apache.cloudstack.api.response.LDAPConfigResponse; -import org.apache.cloudstack.api.response.LoadBalancerResponse; -import org.apache.cloudstack.api.response.NetworkACLResponse; -import org.apache.cloudstack.api.response.NetworkOfferingResponse; -import org.apache.cloudstack.api.response.NetworkResponse; -import org.apache.cloudstack.api.response.PhysicalNetworkResponse; -import org.apache.cloudstack.api.response.PodResponse; -import org.apache.cloudstack.api.response.PrivateGatewayResponse; -import org.apache.cloudstack.api.response.ProjectAccountResponse; -import org.apache.cloudstack.api.response.ProjectInvitationResponse; -import org.apache.cloudstack.api.response.ProjectResponse; -import org.apache.cloudstack.api.response.ProviderResponse; -import org.apache.cloudstack.api.response.RemoteAccessVpnResponse; -import org.apache.cloudstack.api.response.ResourceCountResponse; -import org.apache.cloudstack.api.response.ResourceLimitResponse; -import org.apache.cloudstack.api.response.ResourceTagResponse; -import org.apache.cloudstack.api.response.SecurityGroupResponse; -import org.apache.cloudstack.api.response.SecurityGroupRuleResponse; -import org.apache.cloudstack.api.response.ServiceOfferingResponse; -import org.apache.cloudstack.api.response.ServiceResponse; -import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse; -import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse; -import org.apache.cloudstack.api.response.SnapshotPolicyResponse; -import org.apache.cloudstack.api.response.SnapshotResponse; -import org.apache.cloudstack.api.response.SnapshotScheduleResponse; -import org.apache.cloudstack.api.response.StaticRouteResponse; -import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse; -import org.apache.cloudstack.api.response.StoragePoolResponse; -import org.apache.cloudstack.api.response.SwiftResponse; -import org.apache.cloudstack.api.response.SystemVmInstanceResponse; -import org.apache.cloudstack.api.response.SystemVmResponse; -import org.apache.cloudstack.api.response.TemplatePermissionsResponse; -import org.apache.cloudstack.api.response.TemplateResponse; -import org.apache.cloudstack.api.response.TrafficTypeResponse; -import org.apache.cloudstack.api.response.UserResponse; -import org.apache.cloudstack.api.response.UserVmResponse; -import org.apache.cloudstack.api.response.VirtualRouterProviderResponse; -import org.apache.cloudstack.api.response.VlanIpRangeResponse; -import org.apache.cloudstack.api.response.VolumeResponse; -import org.apache.cloudstack.api.response.VpcOfferingResponse; -import org.apache.cloudstack.api.response.VpcResponse; -import org.apache.cloudstack.api.response.VpnUsersResponse; -import org.apache.cloudstack.api.response.ZoneResponse; - -import org.apache.cloudstack.api.response.S3Response; -import org.springframework.stereotype.Component; - import com.cloud.async.AsyncJob; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; @@ -110,29 +34,12 @@ import com.cloud.event.Event; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.hypervisor.HypervisorCapabilities; -import com.cloud.network.IpAddress; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkProfile; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.PhysicalNetworkTrafficType; -import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.Site2SiteCustomerGateway; -import com.cloud.network.Site2SiteVpnConnection; -import com.cloud.network.Site2SiteVpnGateway; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VpnUser; -import com.cloud.network.as.AutoScalePolicy; -import com.cloud.network.as.AutoScaleVmGroup; -import com.cloud.network.as.AutoScaleVmProfile; -import com.cloud.network.as.AutoScaleVmProfileVO; -import com.cloud.network.as.Condition; -import com.cloud.network.as.ConditionVO; -import com.cloud.network.as.Counter; +import com.cloud.network.as.*; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkVO; @@ -152,6 +59,7 @@ import com.cloud.org.Cluster; import com.cloud.projects.Project; import com.cloud.projects.ProjectAccount; import com.cloud.projects.ProjectInvitation; +import com.cloud.region.ha.GlobalLoadBalancer; import com.cloud.server.Criteria; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; @@ -186,6 +94,7 @@ import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; import org.apache.cloudstack.api.response.*; import org.apache.cloudstack.region.Region; import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import java.text.DecimalFormat; import java.util.*; @@ -624,6 +533,19 @@ public class ApiResponseHelper implements ResponseGenerator { return lbResponse; } + @Override + public GlobalLoadBalancerResponse createGlobalLoadBalancerResponse(GlobalLoadBalancer globalLoadBalancer) { + GlobalLoadBalancerResponse response = new GlobalLoadBalancerResponse(); + response.setAlgorithm(globalLoadBalancer.getAlgorithm()); + response.setStickyMethod(globalLoadBalancer.getPersistence()); + response.setServiceDomainName(globalLoadBalancer.getGslbDomain()); + response.setName(globalLoadBalancer.getName()); + response.setDescription(globalLoadBalancer.getDescription()); + response.setRegionIdId(globalLoadBalancer.getRegion()); + response.setId(globalLoadBalancer.getUuid()); + return response; + } + @Override public PodResponse createPodResponse(Pod pod, Boolean showCapacities) { String[] ipRange = new String[2]; diff --git a/server/src/org/apache/cloudstack/region/RegionVO.java b/server/src/org/apache/cloudstack/region/RegionVO.java index 0c36db2caff..f62f571eeba 100644 --- a/server/src/org/apache/cloudstack/region/RegionVO.java +++ b/server/src/org/apache/cloudstack/region/RegionVO.java @@ -41,7 +41,18 @@ public class RegionVO implements Region{ @Column(name="secret_key") private String secretKey; - + + public boolean getGslbEnabled() { + return gslbEnabled; + } + + public void setGslbEnabled(boolean gslbEnabled) { + this.gslbEnabled = gslbEnabled; + } + + @Column(name="gslb_service_enabled") + private boolean gslbEnabled; + public RegionVO() { } @@ -51,6 +62,7 @@ public class RegionVO implements Region{ this.endPoint = endPoint; this.apiKey = apiKey; this.secretKey = secretKey; + this.gslbEnabled = true; } public int getId() { @@ -85,7 +97,12 @@ public class RegionVO implements Region{ return secretKey; } - public void setSecretKey(String secretKey) { + @Override + public boolean checkIfServiceEnabled(Service service) { + return gslbEnabled; + } + + public void setSecretKey(String secretKey) { this.secretKey = secretKey; } diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDao.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDao.java new file mode 100644 index 00000000000..c7f1d58efea --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDao.java @@ -0,0 +1,28 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import com.cloud.utils.db.GenericDao; + +import java.util.List; + +public interface GlobalLoadBalancerDao extends GenericDao { + + List listByRegionId(long regionId); + List listByDomainName(String domainName); +} diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java new file mode 100644 index 00000000000..63d60c06b54 --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerDaoImpl.java @@ -0,0 +1,51 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import java.util.List; + +@Component +@Local(value={GlobalLoadBalancerDao.class}) +public class GlobalLoadBalancerDaoImpl extends GenericDaoBase implements GlobalLoadBalancerDao { + + private final SearchBuilder listByDomainSearch; + + public GlobalLoadBalancerDaoImpl() { + listByDomainSearch = createSearchBuilder(); + listByDomainSearch.and("gslbDomain", listByDomainSearch.entity().getGslbDomain(), SearchCriteria.Op.EQ); + listByDomainSearch.done(); + } + + @Override + public List listByRegionId(long regionId) { + return null; + } + + @Override + public List listByDomainName(String domainName) { + SearchCriteria sc = listByDomainSearch.create(); + sc.setParameters("gslbDomain", domainName); + return listBy(sc); + } +} diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java new file mode 100644 index 00000000000..6ffdc499d11 --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDao.java @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import com.cloud.utils.db.GenericDao; + +public interface GlobalLoadBalancerLbRuleMapDao extends GenericDao { + +} diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java new file mode 100644 index 00000000000..625198571e2 --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapDaoImpl.java @@ -0,0 +1,34 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import com.cloud.utils.db.DB; +import com.cloud.utils.db.GenericDaoBase; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; + +@Component +@Local(value={GlobalLoadBalancerLbRuleMapDao.class}) +@DB(txn = false) +public class GlobalLoadBalancerLbRuleMapDaoImpl extends GenericDaoBase implements GlobalLoadBalancerLbRuleMapDao { + + public GlobalLoadBalancerLbRuleMapDaoImpl() { + + } +} diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java new file mode 100644 index 00000000000..84ce0ccf23e --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerLbRuleMapVO.java @@ -0,0 +1,71 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import org.apache.cloudstack.api.InternalIdentity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name=("global_load_balancer_lb_rule_map")) +public class GlobalLoadBalancerLbRuleMapVO implements InternalIdentity { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="lb_rule_id") + private long loadBalancerId; + + @Column(name="gslb_rule_id") + private long gslbLoadBalancerId; + + public GlobalLoadBalancerLbRuleMapVO() { + + } + + public GlobalLoadBalancerLbRuleMapVO(long loadBalancerId, long gslbLoadBalancerId) { + this.loadBalancerId = loadBalancerId; + this.gslbLoadBalancerId = gslbLoadBalancerId; + } + + public long getId() { + return id; + } + + public long getLoadBalancerId() { + return loadBalancerId; + } + + public long getGslbLoadBalancerId() { + return gslbLoadBalancerId; + } + + public void setLoadBalancerId(long loadBalancerId) { + this.loadBalancerId = loadBalancerId; + } + + public void setGslbLoadBalancerId(long gslbLoadBalancerId) { + this.gslbLoadBalancerId = gslbLoadBalancerId; + } +} diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerVO.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerVO.java new file mode 100644 index 00000000000..372ef7d6780 --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancerVO.java @@ -0,0 +1,146 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import com.cloud.region.ha.GlobalLoadBalancer; + +import javax.persistence.*; +import java.util.UUID; + +@Entity +@Table(name=("global_load_balancing_rules")) +public class GlobalLoadBalancerVO implements GlobalLoadBalancer { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="name") + private String name; + + @Column(name="description", length=4096) + private String description; + + @Column(name="algorithm") + private String algorithm; + + @Column(name="persistence") + private String persistence; + + @Column(name="gslb_domain_name") + private String gslbDomain; + + @Column(name="region_id") + private int region; + + @Column(name="account_id") + long accountId; + + @Column(name="uuid") + String uuid; + + public GlobalLoadBalancerVO() { + this.uuid = UUID.randomUUID().toString(); + } + + public GlobalLoadBalancerVO(String name, String description, String gslbDomain, String algorithm, + String persistence, int regionId, long accountId) { + this.name =name; + this.description = description; + this.region = regionId; + this.algorithm = algorithm; + this.gslbDomain = gslbDomain; + this.persistence = persistence; + this.accountId = accountId; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getAlgorithm() { + return algorithm; + } + + @Override + public String getPersistence() { + return persistence; + } + + @Override + public int getRegion() { + return region; + } + + @Override + public long getAccountId() { + return accountId; + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public void setPersistence(String persistence) { + this.persistence = persistence; + } + + @Override + public String getGslbDomain() { + return gslbDomain; + } + + public void setGslbDomain(String gslbDomain) { + this.gslbDomain = gslbDomain; + } + + public void setRegion(int region) { + this.region =region; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return this.uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java new file mode 100644 index 00000000000..c6a2dc24c0e --- /dev/null +++ b/server/src/org/apache/cloudstack/region/gslb/GlobalLoadBalancingRulesServiceImpl.java @@ -0,0 +1,135 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.cloudstack.region.gslb; + +import com.cloud.agent.api.routing.GlobalLoadBalancerConfigCommand; +import com.cloud.event.ActionEvent; +import com.cloud.event.EventTypes; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.region.ha.GlobalLoadBalancer; +import com.cloud.region.ha.GlobalLoadBalancingRulesService; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.Transaction; +import com.cloud.utils.net.NetUtils; +import org.apache.cloudstack.api.command.user.region.ha.gslb.*; +import org.apache.cloudstack.region.Region; +import org.apache.cloudstack.region.dao.RegionDao; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import java.security.spec.InvalidParameterSpecException; +import java.util.List; + +@Component +@Local(value = {GlobalLoadBalancingRulesService.class}) +public class GlobalLoadBalancingRulesServiceImpl implements GlobalLoadBalancingRulesService { + + @Inject + AccountManager _accountMgr; + @Inject + GlobalLoadBalancerDao _globalLoadBalancerDao; + @Inject + RegionDao _regionDao; + + @Override + @DB + @ActionEvent(eventType = EventTypes.EVENT_GLOBAL_LOAD_BALANCER_CREATE, eventDescription = "creating global load balancer") + public GlobalLoadBalancer createGlobalLoadBalancerRule(CreateGlobalLoadBalancerRuleCmd newGslb) + throws InvalidParameterSpecException { + + Integer regionId = newGslb.getRegionId(); + String algorithm = newGslb.getAlgorithm(); + String stickyMethod = newGslb.getStickyMethod(); + String name = newGslb.getName(); + String description = newGslb.getDescription(); + String domainName = newGslb.getServiceDomainName(); + + Account gslbOwner = _accountMgr.getAccount(newGslb.getEntityOwnerId()); + + if (!GlobalLoadBalancer.Algorithm.isValidAlgorithm(algorithm)) { + throw new InvalidParameterSpecException("Invalid Algorithm: " + algorithm); + } + + if (!GlobalLoadBalancer.Persistence.isValidPersistence(stickyMethod)) { + throw new InvalidParameterSpecException("Invalid persistence: " + stickyMethod); + } + + List gslbRules = _globalLoadBalancerDao.listByDomainName(domainName); + if (gslbRules != null && !gslbRules.isEmpty()) { + throw new InvalidParameterSpecException("There exist a GSLB rule with same domain name : " + domainName); + } + + if (!NetUtils.verifyDomainName(domainName)){ + throw new InvalidParameterSpecException("Invalid domain name : " + domainName); + } + + Region region = _regionDao.findById(regionId); + if (region == null) { + throw new InvalidParameterSpecException("Invalid region ID: " + region.getName()); + } + + if (!region.checkIfServiceEnabled(Region.Service.Gslb)) { + throw new InvalidParameterValueException("GSLB service is not enabled in region : " + region.getName()); + } + + // persist in the DB + Transaction txn = Transaction.currentTxn(); + txn.start(); + GlobalLoadBalancerVO newGslbRule = new GlobalLoadBalancerVO(name, description, domainName, algorithm, + stickyMethod, regionId, gslbOwner.getId()); + _globalLoadBalancerDao.persist(newGslbRule); + txn.commit(); + return newGslbRule; + } + + @Override + public boolean deleteGlobalLoadBalancerRule(DeleteGlobalLoadBalancerRuleCmd deleteGslbCmd) { + return false; + } + + @Override + public GlobalLoadBalancer updateGlobalLoadBalancerRule(UpdateGlobalLoadBalancerRuleCmd updateGslbCmd) { + return null; + } + + @Override + public List listGlobalLoadBalancerRule(ListGlobalLoadBalancerRuleCmd listGslbCmd) { + return null; + } + + @Override + public boolean assignToGlobalLoadBalancerRule(AssignToGlobalLoadBalancerRuleCmd assignToGslbCmd) { + return false; + } + + @Override + public boolean removeFromGlobalLoadBalancerRule(RemoveFromGlobalLoadBalancerRuleCmd removeFromGslbCmd) { + return false; + } + + private void deployGlobalLoadBalancerRule(GlobalLoadBalancerConfigCommand cmd) { + + } + + private void configureZoneGslbProvider(long zoneId, GlobalLoadBalancerConfigCommand cmd) { + + } +} diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index f89c8851e8e..5ac83e12697 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -196,6 +196,8 @@ DROP TABLE IF EXISTS `cloud`.`vm_network_map`; DROP TABLE IF EXISTS `cloud`.`netapp_volume`; DROP TABLE IF EXISTS `cloud`.`netapp_pool`; DROP TABLE IF EXISTS `cloud`.`netapp_lun`; +DROP TABLE IF EXISTS `cloud`.`global_load_balancing_rules`; +DROP TABLE IF EXISTS `cloud`.`global_load_balancer_lb_rule_map`; CREATE TABLE `cloud`.`version` ( `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id', @@ -2311,6 +2313,7 @@ CREATE TABLE `cloud`.`region` ( `end_point` varchar(255) NOT NULL, `api_key` varchar(255), `secret_key` varchar(255), + `gslb_service_enabled` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT 'Is GSLB service provided in the zone', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -2651,5 +2654,30 @@ CREATE TABLE `cloud`.`user_ipv6_address` ( CONSTRAINT `fk_user_ipv6_address__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`global_load_balancing_rules` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `account_id` bigint unsigned NOT NULL COMMENT 'account id', + `region_id` int unsigned NOT NULL, + `name` varchar(255) NOT NULL, + `description` varchar(4096) NULL COMMENT 'description', + `algorithm` varchar(255) NOT NULL COMMENT 'load balancing algorithm used to distribbute traffic across zones', + `persistence` varchar(255) NOT NULL COMMENT 'session persistence used across the zone', + `gslb_domain_name` varchar(255) NOT NULL COMMENT 'DNS name for the GSLB service that is used to provide a FQDN for the GSLB service', + PRIMARY KEY (`id`), + CONSTRAINT `fk_global_load_balancing_rules_account_id` FOREIGN KEY (`account_id`) REFERENCES `account`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_global_load_balancing_rules_region_id` FOREIGN KEY(`region_id`) REFERENCES `region`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +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, + PRIMARY KEY (`id`), + UNIQUE KEY (`gslb_rule_id`, `lb_rule_id`), + CONSTRAINT `fk_gslb_rule_id` FOREIGN KEY(`gslb_rule_id`) REFERENCES `global_load_balancing_rules`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_lb_rule_id` FOREIGN KEY(`lb_rule_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + SET foreign_key_checks = 1;