improving aws lb
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/d68a6d50 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/d68a6d50 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/d68a6d50 Branch: refs/heads/stratos-4.1.x Commit: d68a6d5033587b25ec37031a1b7884fc002a3e6a Parents: 912c923 Author: Isuru Haththotuwa <[email protected]> Authored: Wed Nov 4 19:10:08 2015 +0530 Committer: Isuru Haththotuwa <[email protected]> Committed: Tue Nov 10 13:32:43 2015 +0530 ---------------------------------------------------------------------- .../modules/aws-extension/INSTALL.md | 10 +- .../aws-extension/src/main/assembly/bin.xml | 5 + .../aws-extension/src/main/bin/aws-extension.sh | 7 +- .../aws-extension/src/main/conf/aws.properties | 2 + .../aws/extension/AWSExtensionContext.java | 28 +++ .../apache/stratos/aws/extension/AWSHelper.java | 224 +++++++++++++++--- .../stratos/aws/extension/AWSLoadBalancer.java | 227 +++++++++++++++---- .../apache/stratos/aws/extension/Constants.java | 7 + .../exception/PersistenceException.java | 39 ++++ .../FileBasedPersistenceManager.java | 161 +++++++++++++ .../persistence/PersistenceManager.java | 36 +++ .../extension/persistence/dao/LBInfoDAO.java | 52 +++++ .../extension/persistence/dto/LBInfoDTO.java | 69 ++++++ .../src/main/security/client-truststore.jks | Bin 35240 -> 36562 bytes 14 files changed, 794 insertions(+), 73 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/INSTALL.md ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/INSTALL.md b/extensions/load-balancer/modules/aws-extension/INSTALL.md index 4f8a090..aec4cfe 100644 --- a/extensions/load-balancer/modules/aws-extension/INSTALL.md +++ b/extensions/load-balancer/modules/aws-extension/INSTALL.md @@ -24,9 +24,11 @@ below steps to proceed with the installation: 1. Extract org.apache.stratos.aws.extension-<version>.zip to a desired location: <aws-extension-home>. -2. Open <aws-extension-home>/conf/aws-credentials.conf file in text editor and update AWS access key and secret key information. +2. Open <aws-extension-home>/conf/aws.properties file in text editor and update AWS access key and secret key information. If you are using HTTPS as the FE protocol for the AWS LBs, upload a certificate [1] for the LBs and update load-balancer-ssl-certificate-id with the ARN [2]. + To enable application level sticky sessions, update app-sticky-session-cookie-name with the relevant cookie name. By default + its using JSESSIONID. 3. Open <aws-extension-home>/bin/aws-extension.sh file in a text editor and update following system properties: ``` @@ -37,6 +39,12 @@ below steps to proceed with the installation: -Dthrift.receiver.ip=127.0.0.1 -Dthrift.receiver.port=7615 -Dnetwork.partition.id=network-partition-1 + + # if running in a VPC, set: + -Doperating.in.vpc=true + + # if cross-zone loadbalancing is required, set: + -Denable.cross.zone.load.balancing=true ``` 4. Open <aws-extension-home>/conf/jndi.properties file in a text editor and update message broker information: http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/assembly/bin.xml ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/assembly/bin.xml b/extensions/load-balancer/modules/aws-extension/src/main/assembly/bin.xml index ba0ad12..31cf4ad 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/assembly/bin.xml +++ b/extensions/load-balancer/modules/aws-extension/src/main/assembly/bin.xml @@ -52,6 +52,11 @@ <include>client-truststore.jks</include> </includes> </fileSet> + <fileSet> + <directory>${project.basedir}/src/main/resources</directory> + <outputDirectory>/resources</outputDirectory> + <fileMode>0600</fileMode> + </fileSet> <fileSet> <directory>${project.basedir}</directory> <outputDirectory>/</outputDirectory> http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh b/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh index 19936ae..fd4102b 100755 --- a/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh +++ b/extensions/load-balancer/modules/aws-extension/src/main/bin/aws-extension.sh @@ -27,6 +27,7 @@ class_path=`echo ${lib_path}/*.jar | tr ' ' ':'` properties="-Djndi.properties.dir=${script_path}/../conf -Dlog4j.properties.file.path=${script_path}/../conf/log4j.properties -Daws.properties.file=${script_path}/../conf/aws.properties + -Dlb.info.file=${script_path}/../resources/lbinformation.ser -Djavax.net.ssl.trustStore=${script_path}/../security/client-truststore.jks -Djavax.net.ssl.trustStorePassword=wso2carbon -Dthrift.client.config.file.path=${script_path}/../conf/thrift-client-config.xml @@ -35,7 +36,11 @@ properties="-Djndi.properties.dir=${script_path}/../conf -Dthrift.receiver.port=7615 -Dnetwork.partition.id=network-partition-1 -Dcluster.id=cluster-1 - -Dservice.name=service-1" + -Dservice.name=service-1 + -Dterminate.lbs.on.extension.stop=false + -Dterminate.lb.on.cluster.removal=true + -Doperating.in.vpc=true + -Denable.cross.zone.load.balancing=true" # Uncomment below line to enable remote debugging http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties b/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties index ebdf614..39a5d84 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties +++ b/extensions/load-balancer/modules/aws-extension/src/main/conf/aws.properties @@ -38,3 +38,5 @@ statistics-interval=60 # You can request these details for a specific certificate object by referencing the name of the certificate object: # aws iam get-server-certificate --server-certificate-name your-certificate-name load-balancer-ssl-certificate-id= +# Enable Application generated cookie stickiness by specifying the Cookie name uses +app-sticky-session-cookie-name=JSESSIONID http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java index d3da969..9b2ef4a 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSExtensionContext.java @@ -36,6 +36,10 @@ public class AWSExtensionContext { private String networkPartitionId; private String clusterId; private String serviceName; + private boolean terminateLBsOnExtensionStop; + private boolean terminateLBOnClusterRemoval; + private boolean operatingInVPC; + private boolean enableCrossZoneLoadBalancing; private AWSExtensionContext() { this.cepStatsPublisherEnabled = Boolean.getBoolean(Constants.CEP_STATS_PUBLISHER_ENABLED); @@ -44,6 +48,10 @@ public class AWSExtensionContext { this.networkPartitionId = System.getProperty(Constants.NETWORK_PARTITION_ID); this.clusterId = System.getProperty(Constants.CLUSTER_ID); this.serviceName = System.getProperty(Constants.SERVICE_NAME); + this.terminateLBsOnExtensionStop = Boolean.getBoolean(Constants.TERMINATE_LBS_ON_EXTENSION_STOP); + this.terminateLBOnClusterRemoval = Boolean.getBoolean(Constants.TERMINATE_LB_ON_CLUSTER_REMOVAL); + this.operatingInVPC = Boolean.getBoolean(Constants.OPERATIMG_IN_VPC); + this.enableCrossZoneLoadBalancing = Boolean.getBoolean(Constants.ENABLE_CROSS_ZONE_LOADBALANCING); if (log.isDebugEnabled()) { log.debug(Constants.CEP_STATS_PUBLISHER_ENABLED + " = " + cepStatsPublisherEnabled); @@ -51,6 +59,10 @@ public class AWSExtensionContext { log.debug(Constants.THRIFT_RECEIVER_PORT + " = " + thriftReceiverPort); log.debug(Constants.NETWORK_PARTITION_ID + " = " + networkPartitionId); log.debug(Constants.CLUSTER_ID + " = " + clusterId); + log.debug(Constants.TERMINATE_LBS_ON_EXTENSION_STOP + "=" + terminateLBsOnExtensionStop); + log.debug(Constants.TERMINATE_LB_ON_CLUSTER_REMOVAL + "=" + terminateLBOnClusterRemoval); + log.debug(Constants.OPERATIMG_IN_VPC + "=" + operatingInVPC); + log.debug(Constants.ENABLE_CROSS_ZONE_LOADBALANCING + "=" + enableCrossZoneLoadBalancing); } } @@ -98,4 +110,20 @@ public class AWSExtensionContext { public String getServiceName() { return serviceName; } + + public boolean terminateLBsOnExtensionStop() { + return terminateLBsOnExtensionStop; + } + + public boolean terminateLBOnClusterRemoval() { + return terminateLBOnClusterRemoval; + } + + public boolean isOperatingInVPC() { + return operatingInVPC; + } + + public boolean isCrossZoneLoadBalancingEnabled () { + return enableCrossZoneLoadBalancing; + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java index 4bdd3e5..c9500f7 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSHelper.java @@ -22,16 +22,13 @@ package org.apache.stratos.aws.extension; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; +import com.amazonaws.AmazonServiceException; +import com.amazonaws.services.ec2.model.*; +import com.amazonaws.services.elasticloadbalancing.model.Instance; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.load.balancer.common.domain.*; @@ -48,13 +45,6 @@ import com.amazonaws.services.cloudwatch.model.Dimension; import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsRequest; import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsResult; import com.amazonaws.services.ec2.AmazonEC2Client; -import com.amazonaws.services.ec2.model.AuthorizeSecurityGroupIngressRequest; -import com.amazonaws.services.ec2.model.CreateSecurityGroupRequest; -import com.amazonaws.services.ec2.model.CreateSecurityGroupResult; -import com.amazonaws.services.ec2.model.DescribeSecurityGroupsRequest; -import com.amazonaws.services.ec2.model.DescribeSecurityGroupsResult; -import com.amazonaws.services.ec2.model.IpPermission; -import com.amazonaws.services.ec2.model.SecurityGroup; import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient; import com.amazonaws.services.elasticloadbalancing.model.*; @@ -67,6 +57,7 @@ public class AWSHelper { private String allowedCidrIpForLBSecurityGroup; private int statisticsInterval; private String sslCertificateId; + private String appStickySessionCookie; private AtomicInteger lbSequence; @@ -130,7 +121,10 @@ public class AWSHelper { // Read the SSL certificate Id. This is mandatory if only we are using HTTPS as the front end protocol. // http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-elb-listenerconfig-quickref.html this.sslCertificateId = properties - .getProperty(Constants.LOAD_BALANCER_SSL_CERTIFICATE_ID); + .getProperty(Constants.LOAD_BALANCER_SSL_CERTIFICATE_ID).trim(); + + // Cookie name for application level stickiness + this.appStickySessionCookie = properties.getProperty(Constants.APP_STICKY_SESSION_COOKIE_NAME).trim(); this.allowedCidrIpForLBSecurityGroup = properties .getProperty(Constants.ALLOWED_CIDR_IP_KEY); @@ -233,7 +227,7 @@ public class AWSHelper { * @throws LoadBalancerExtensionException */ public String createLoadBalancer(String name, List<Listener> listeners, - String region) throws LoadBalancerExtensionException { + String region, String availabilityZone, boolean inVPC) throws LoadBalancerExtensionException { log.info("Creating load balancer " + name); @@ -242,18 +236,23 @@ public class AWSHelper { createLoadBalancerRequest.setListeners(listeners); + // don't need this now since we are anyway updating zone according to the member +// Set<String> availabilityZones = new HashSet<String>(); +// availabilityZones.add(getAvailabilityZoneFromRegion(region)); +// +// createLoadBalancerRequest.setAvailabilityZones(availabilityZones); Set<String> availabilityZones = new HashSet<String>(); - availabilityZones.add(getAvailabilityZoneFromRegion(region)); - + availabilityZones.add(availabilityZone); createLoadBalancerRequest.setAvailabilityZones(availabilityZones); try { - String securityGroupId = getSecurityGroupIdForRegion(region); + if (inVPC) { + String securityGroupId = getSecurityGroupIdForRegion(region); + List<String> securityGroups = new ArrayList<String>(); + securityGroups.add(securityGroupId); - List<String> securityGroups = new ArrayList<String>(); - securityGroups.add(securityGroupId); - - createLoadBalancerRequest.setSecurityGroups(securityGroups); + createLoadBalancerRequest.setSecurityGroups(securityGroups); + } elbClient.setEndpoint(String.format( Constants.ELB_ENDPOINT_URL_FORMAT, region)); @@ -264,8 +263,9 @@ public class AWSHelper { return clbResult.getDNSName(); } catch (AmazonClientException e) { - throw new LoadBalancerExtensionException( - "Could not create load balancer " + name, e); + String errorMsg = "Could not create load balancer " + name; + log.error(errorMsg, e); + throw new LoadBalancerExtensionException(errorMsg, e); } } @@ -378,7 +378,7 @@ public class AWSHelper { * of the load balancer * @return description of the load balancer */ - private LoadBalancerDescription getLoadBalancerDescription( + public LoadBalancerDescription getLoadBalancerDescription( String loadBalancerName, String region) { List<String> loadBalancers = new ArrayList<String>(); @@ -430,8 +430,9 @@ public class AWSHelper { } catch (AmazonClientException e) { log.error("Could not find instances attached load balancer " + loadBalancerName, e); - return null; } + + return null; } /** @@ -886,11 +887,12 @@ public class AWSHelper { * @return name of the load balancer * @throws LoadBalancerExtensionException */ - public String generateLoadBalancerName() + public String generateLoadBalancerName(String serviceName) throws LoadBalancerExtensionException { String name = null; - name = lbPrefix + getNextLBSequence(); + //name = lbPrefix + getNextLBSequence(); + name = lbPrefix + serviceName; if (name.length() > Constants.LOAD_BALANCER_NAME_MAX_LENGTH) throw new LoadBalancerExtensionException( @@ -942,7 +944,171 @@ public class AWSHelper { return null; } + public CreateAppCookieStickinessPolicyResult createStickySessionPolicy(String lbName, String cookieName, String policyName, String region) { + + elbClient.setEndpoint(String.format(Constants.ELB_ENDPOINT_URL_FORMAT, region)); + + CreateAppCookieStickinessPolicyRequest stickinessPolicyReq = new CreateAppCookieStickinessPolicyRequest(). + withLoadBalancerName(lbName).withCookieName(cookieName).withPolicyName(policyName); + + CreateAppCookieStickinessPolicyResult stickinessPolicyResult = null; + try { + stickinessPolicyResult = elbClient.createAppCookieStickinessPolicy(stickinessPolicyReq); + + } catch (AmazonServiceException e) { + log.error(e.getMessage(), e); + + } catch (AmazonClientException e) { + log.error(e.getMessage(), e); + } + + if (stickinessPolicyResult == null) { + log.error("Error in creating Application Stickiness policy for for cookie name: " + cookieName + ", policy: " + policyName); + } else { + log.info("Enabled Application stickiness using: " + cookieName + ", policy: " + policyName + " for LB " + lbName); + } + + return stickinessPolicyResult; + } + + public void applyPolicyToLBListenerPorts(Collection<Port> ports, String loadBalancerName, String policyName, String region) { + + for (Port port : ports) { + if ("HTTP".equalsIgnoreCase(port.getProtocol()) || "HTTPS".equalsIgnoreCase(port.getProtocol())) { + applyPolicyToListener(loadBalancerName, port.getProxy(), policyName, region); + // hack to stop too many calls to AWS API :( + try { + Thread.sleep(2000); + } catch (InterruptedException e) {} + } + } + } + + private void applyPolicyToListener (String loadBalancerName, int listenerPort, String policyName, String region) { + + SetLoadBalancerPoliciesOfListenerRequest loadBalancerPoliciesOfListenerReq = new SetLoadBalancerPoliciesOfListenerRequest(). + withLoadBalancerName(loadBalancerName).withLoadBalancerPort(listenerPort).withPolicyNames(policyName); + + elbClient.setEndpoint(String.format(Constants.ELB_ENDPOINT_URL_FORMAT, region)); + + SetLoadBalancerPoliciesOfListenerResult setLBPoliciesOfListenerRes = null; + try { + setLBPoliciesOfListenerRes = elbClient.setLoadBalancerPoliciesOfListener(loadBalancerPoliciesOfListenerReq); + + } catch (AmazonServiceException e) { + log.error(e.getMessage(), e); + + } catch (AmazonClientException e) { + log.error(e.getMessage(), e); + } + + if (setLBPoliciesOfListenerRes == null) { + log.error("Unable to apply policy " + policyName + " for Listener port: " + listenerPort + " for LB: " + loadBalancerName); + } else { + log.info("Successfully applied policy " + policyName + " for Listener port: " + listenerPort + " for LB: " + loadBalancerName); + } + } + + public List<String> getAvailabilityZonesFromRegion (final String region) { + + DescribeAvailabilityZonesRequest availabilityZonesReq = new DescribeAvailabilityZonesRequest(); + List<Filter> availabilityZoneFilters = new ArrayList<Filter>(); + availabilityZoneFilters.add(new Filter("region-name", new ArrayList<String>() {{ + add(region); + }})); + availabilityZoneFilters.add(new Filter("state", new ArrayList<String>() {{ + add("available"); + }})); + + ec2Client.setEndpoint(String.format(Constants.EC2_ENDPOINT_URL_FORMAT, region)); + DescribeAvailabilityZonesResult availabilityZonesRes = null; + + try { + availabilityZonesRes = ec2Client.describeAvailabilityZones(availabilityZonesReq); + + } catch (AmazonServiceException e) { + log.error(e.getMessage(), e); + + } catch (AmazonClientException e) { + log.error(e.getMessage(), e); + } + + List<String> availabilityZones = null; + + if (availabilityZonesRes != null) { + availabilityZones = new ArrayList<>(); + for (AvailabilityZone zone : availabilityZonesRes.getAvailabilityZones()) { + availabilityZones.add(zone.getZoneName()); + } + } else { + log.error("Unable to retrieve the active availability zones for region " + region); + } + + return availabilityZones; + } + + public void addAvailabilityZonesForLoadBalancer (String loadBalancerName, List<String> availabilityZones, String region) { + + EnableAvailabilityZonesForLoadBalancerRequest enableAvailabilityZonesReq = new EnableAvailabilityZonesForLoadBalancerRequest() + .withLoadBalancerName(loadBalancerName).withAvailabilityZones(availabilityZones); + + elbClient.setEndpoint(String.format(Constants.ELB_ENDPOINT_URL_FORMAT, region)); + + EnableAvailabilityZonesForLoadBalancerResult enableAvailabilityZonesRes = null; + + try { + enableAvailabilityZonesRes = elbClient.enableAvailabilityZonesForLoadBalancer(enableAvailabilityZonesReq); + + } catch (AmazonServiceException e) { + log.error(e.getMessage(), e); + + } catch (AmazonClientException e) { + log.error(e.getMessage(), e); + } + + if (enableAvailabilityZonesRes != null) { + log.info("Availability zones successfully added to LB " + loadBalancerName + ". Updated zone list: "); + for (String zone : enableAvailabilityZonesRes.getAvailabilityZones()) { + log.info(zone); + } + } else { + log.error("Updating availability zones failed for LB " + loadBalancerName); + } + } + + public void modifyLBAttributes (String loadBalancerName, String region, boolean enableCrossZoneLbing, boolean enableConnDraining) { + + if (!enableCrossZoneLbing && !enableConnDraining) { + log.info("No attributes specified to modify in the LB " + loadBalancerName); + return; + } + + ModifyLoadBalancerAttributesRequest modifyLBAttributesReq = new ModifyLoadBalancerAttributesRequest().withLoadBalancerName(loadBalancerName); + LoadBalancerAttributes modifiedLbAttributes = new LoadBalancerAttributes(); + if (enableCrossZoneLbing) { + modifiedLbAttributes.setCrossZoneLoadBalancing(new CrossZoneLoadBalancing().withEnabled(true)); + } + if (enableConnDraining) { + modifiedLbAttributes.setConnectionDraining(new ConnectionDraining().withEnabled(true)); + } + + modifyLBAttributesReq.setLoadBalancerAttributes(modifiedLbAttributes); + + elbClient.setEndpoint(String.format(Constants.ELB_ENDPOINT_URL_FORMAT, region)); + + ModifyLoadBalancerAttributesResult modifyLBAttributesRes = elbClient.modifyLoadBalancerAttributes(modifyLBAttributesReq); + if (modifyLBAttributesRes != null) { + log.info("Successfully enabled cross zone load balancing and connection draining for " + loadBalancerName); + } else { + log.error("Failed to enable cross zone load balancing and connection draining for " + loadBalancerName); + } + } + public String getSslCertificateId() { return sslCertificateId; } + + public String getAppStickySessionCookie() { + return appStickySessionCookie; + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java index c3a63ee..8389ec0 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/AWSLoadBalancer.java @@ -19,10 +19,16 @@ package org.apache.stratos.aws.extension; +import com.amazonaws.services.elasticloadbalancing.model.CreateAppCookieStickinessPolicyResult; import com.amazonaws.services.elasticloadbalancing.model.Instance; import com.amazonaws.services.elasticloadbalancing.model.Listener; +import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.stratos.aws.extension.exception.PersistenceException; +import org.apache.stratos.aws.extension.persistence.FileBasedPersistenceManager; +import org.apache.stratos.aws.extension.persistence.PersistenceManager; +import org.apache.stratos.aws.extension.persistence.dto.LBInfoDTO; import org.apache.stratos.load.balancer.common.domain.Cluster; import org.apache.stratos.load.balancer.common.domain.Member; import org.apache.stratos.load.balancer.common.domain.Service; @@ -30,10 +36,7 @@ import org.apache.stratos.load.balancer.common.domain.Topology; import org.apache.stratos.load.balancer.extension.api.LoadBalancer; import org.apache.stratos.load.balancer.extension.api.exception.LoadBalancerExtensionException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class AWSLoadBalancer implements LoadBalancer { @@ -47,8 +50,13 @@ public class AWSLoadBalancer implements LoadBalancer { // Object used to invoke methods related to AWS API private AWSHelper awsHelper; + // PersistenceManager: used to persist LB Information by tuples of <lb name, cluster id, region> + PersistenceManager persistenceManager; + public AWSLoadBalancer() throws LoadBalancerExtensionException { awsHelper = new AWSHelper(); + persistenceManager = new FileBasedPersistenceManager(); + initialize(); } /* @@ -100,6 +108,7 @@ public class AWSLoadBalancer implements LoadBalancer { activeClusters.add(cluster.getClusterId()); List<Instance> instancesToAddToLoadBalancer = new ArrayList<Instance>(); + List<String> availabilityZones = new ArrayList<String>(); for (Member member : clusterMembers) { // if instance id of member is not in @@ -113,6 +122,7 @@ public class AWSLoadBalancer implements LoadBalancer { || !attachedInstances.contains(instance)) { instancesToAddToLoadBalancer.add(instance); + if (log.isDebugEnabled()) { log.debug("Instance " + awsHelper @@ -122,13 +132,25 @@ public class AWSLoadBalancer implements LoadBalancer { + loadBalancerName); } + // LB Common Member has a property 'EC2_AVAILABILITY_ZONE' points to the ec2 availability zone + // for this member. Use the property value to update the LB about the relevant zone + String availabilityZone = getEC2AvaialbilityZoneOfMember(member); + if (availabilityZone != null) { + availabilityZones.add(availabilityZone); + } } } - if (instancesToAddToLoadBalancer.size() > 0) + if (instancesToAddToLoadBalancer.size() > 0) { awsHelper.registerInstancesToLoadBalancer( loadBalancerName, instancesToAddToLoadBalancer, region); + } + + // update LB with the zones + if (!availabilityZones.isEmpty()) { + awsHelper.addAvailabilityZonesForLoadBalancer(loadBalancerName, availabilityZones, region); + } } } else { @@ -136,26 +158,38 @@ public class AWSLoadBalancer implements LoadBalancer { Collection<Member> clusterMembers = cluster.getMembers(); if (clusterMembers.size() > 0) { + Member aMember = clusterMembers.iterator().next(); + // a unique load balancer name with user-defined // prefix and a sequence number. String loadBalancerName = awsHelper - .generateLoadBalancerName(); + .generateLoadBalancerName(cluster.getServiceName()); - String region = awsHelper.getAWSRegion(clusterMembers - .iterator().next().getInstanceId()); + String region = awsHelper.getAWSRegion(aMember.getInstanceId()); // list of AWS listeners obtained using port // mappings of one of the members of the cluster. List<Listener> listenersForThisCluster = awsHelper - .getRequiredListeners(clusterMembers.iterator() - .next()); + .getRequiredListeners(aMember); + + // Get the zone from the first member and use in LB creation. Zone will be updated for each member below + String initialAvailabilityZone = getEC2AvaialbilityZoneOfMember(aMember); + if (initialAvailabilityZone == null) { + // could not get the availability zone from the Member property 'EC2_AVAILABILITY_ZONE' + // use the default (<region>a) + initialAvailabilityZone = awsHelper.getAvailabilityZoneFromRegion(region); + } - // DNS name of load balancer which was created. + // Returns DNS name of load balancer which was created. // This is used in the domain mapping of this // cluster. String loadBalancerDNSName = awsHelper .createLoadBalancer(loadBalancerName, - listenersForThisCluster, region); + listenersForThisCluster, region, initialAvailabilityZone, AWSExtensionContext.getInstance().isOperatingInVPC()); + + // enable connection draining (default) and cross zone load balancing (if specified in aws-extension.sh) + awsHelper.modifyLBAttributes(loadBalancerName, region, AWSExtensionContext.getInstance().isCrossZoneLoadBalancingEnabled(), + true); // Add the inbound rule the security group of the load // balancer @@ -183,6 +217,7 @@ public class AWSLoadBalancer implements LoadBalancer { // Register instances in the cluster to load balancer List<Instance> instances = new ArrayList<Instance>(); + List<String> availabilityZones = new ArrayList<String>(); for (Member member : clusterMembers) { String instanceId = member.getInstanceId(); @@ -200,11 +235,43 @@ public class AWSLoadBalancer implements LoadBalancer { .getAWSInstanceName(instanceId)); instances.add(instance); + // LB Common Member has a property 'EC2_AVAILABILITY_ZONE' which points to the ec2 availability + // zone for this member. Use the property value to update the LB about the relevant zone + String availabilityZone = getEC2AvaialbilityZoneOfMember(member); + if (availabilityZone != null) { + availabilityZones.add(availabilityZone); + } } awsHelper.registerInstancesToLoadBalancer( loadBalancerName, instances, region); + // update LB with the zones + if (!availabilityZones.isEmpty()) { + awsHelper.addAvailabilityZonesForLoadBalancer(loadBalancerName, availabilityZones, region); + } + + // add stickiness policy + if (awsHelper.getAppStickySessionCookie() != null && !awsHelper.getAppStickySessionCookie().isEmpty()) { + CreateAppCookieStickinessPolicyResult result = awsHelper.createStickySessionPolicy(loadBalancerName, awsHelper.getAppStickySessionCookie(), + Constants.STICKINESS_POLICY, region); + + if (result != null) { + // Take a single port mapping from a member, and apply the policy for + // the LB Listener port (Proxy port of the port mapping) + awsHelper.applyPolicyToLBListenerPorts(aMember.getPorts(), loadBalancerName, Constants.STICKINESS_POLICY, region); + } + } + + // persist LB info + try { + persistenceManager.persist(new LBInfoDTO(loadBalancerName, cluster.getClusterId(), region)); + + } catch (PersistenceException e) { + log.error("Unable to persist LB Information for " + loadBalancerName + ", cluster id " + + cluster.getClusterId()); + } + LoadBalancerInfo loadBalancerInfo = new LoadBalancerInfo( loadBalancerName, region); @@ -212,39 +279,49 @@ public class AWSLoadBalancer implements LoadBalancer { loadBalancerInfo); activeClusters.add(cluster.getClusterId()); } - } - - // sleep to stop AWS Rate Exceeding: Caused by: com.amazonaws.AmazonServiceException: Rate exceeded - // (Service: AmazonElasticLoadBalancing; Status Code: 400; Error Code: Throttling; Request ID: xxx-xxx) - try { - Thread.sleep(3000); - } catch (InterruptedException ignored) {} + pause(3000); + } } } - // Find out clusters which were present earlier but are not now. - List<String> clustersToRemoveFromMap = new ArrayList<String>(); + // if 'terminate.lb.on.cluster.removal' = true in aws-extension.sh + if (AWSExtensionContext.getInstance().terminateLBOnClusterRemoval()) { - for (String clusterId : clusterIdToLoadBalancerMap.keySet()) { - if (!activeClusters.contains(clusterId)) { - clustersToRemoveFromMap.add(clusterId); + // Find out clusters which were present earlier but are not now. + List<String> clustersToRemoveFromMap = new ArrayList<String>(); + // TODO: improve using an iterator and removing the unwanted cluster id in this loop + for (String clusterId : clusterIdToLoadBalancerMap.keySet()) { + if (!activeClusters.contains(clusterId)) { + clustersToRemoveFromMap.add(clusterId); - if (log.isDebugEnabled()) { - log.debug("Load balancer for cluster " + clusterId - + " needs to be removed."); - } + if (log.isDebugEnabled()) { + log.debug("Load balancer for cluster " + clusterId + + " needs to be removed."); + } + } } - } - // Delete load balancers associated with these clusters. - for (String clusterId : clustersToRemoveFromMap) { - // Remove load balancer for this cluster. - awsHelper.deleteLoadBalancer( - clusterIdToLoadBalancerMap.get(clusterId).getName(), - clusterIdToLoadBalancerMap.get(clusterId).getRegion()); - clusterIdToLoadBalancerMap.remove(clusterId); + + // Delete load balancers associated with these clusters. + for (String clusterId : clustersToRemoveFromMap) { + // Remove load balancer for this cluster. + final String loadBalancerName = clusterIdToLoadBalancerMap.get(clusterId).getName(); + final String region = clusterIdToLoadBalancerMap.get(clusterId).getRegion(); + awsHelper.deleteLoadBalancer( + loadBalancerName, + region); + //remove and persist + try { + persistenceManager.remove(new LBInfoDTO(loadBalancerName, clusterId, region)); + + } catch (PersistenceException e) { + log.error("Unable to persist LB Information for " + loadBalancerName + ", cluster id " + + clusterId); + } + clusterIdToLoadBalancerMap.remove(clusterId); + } } activeClusters.clear(); @@ -252,6 +329,14 @@ public class AWSLoadBalancer implements LoadBalancer { return true; } + private String getEC2AvaialbilityZoneOfMember(Member member) { + if (member.getProperties() != null) { + return member.getProperties().getProperty(Constants.EC2_AVAILABILITY_ZONE_PROPERTY); + } + + return null; + } + /* * start method is called after extension if configured first time. Does * nothing but logs the message. @@ -261,6 +346,41 @@ public class AWSLoadBalancer implements LoadBalancer { log.info("AWS load balancer extension started."); } + private void initialize() { + // load persisted LB information + Set<LBInfoDTO> lbInfo = null; + try { + lbInfo = persistenceManager.retrieve(); + + } catch (PersistenceException e) { + log.error("Unable to retrieve persisted LB Information", e); + } + + if (lbInfo != null) { + for (LBInfoDTO lbInfoDTO : lbInfo) { + LoadBalancerDescription lbDesc = awsHelper.getLoadBalancerDescription(lbInfoDTO.getName(), + lbInfoDTO.getRegion()); + if (lbDesc != null) { + clusterIdToLoadBalancerMap.put(lbInfoDTO.getClusterId(), new LoadBalancerInfo(lbInfoDTO.getName(), + lbInfoDTO.getRegion())); + } else { + // make debug + if (log.isInfoEnabled()) { + log.info("Unable to locate LB " + lbInfoDTO.getName()); + } + // remove the persisted entry + try { + persistenceManager.remove(new LBInfoDTO(lbInfoDTO.getName(), lbInfoDTO.getClusterId(), lbInfoDTO.getRegion())); + + } catch (PersistenceException e) { + log.error("Unable to remove persisted LB Information", e); + } + } + + } + } + } + /* * reload method is called every time after extension if configured. Does * nothing but logs the message. @@ -274,15 +394,38 @@ public class AWSLoadBalancer implements LoadBalancer { * stop method deletes load balancers for all clusters in the topology. */ public void stop() throws LoadBalancerExtensionException { - // Remove all load balancers - for (LoadBalancerInfo loadBalancerInfo : clusterIdToLoadBalancerMap - .values()) { - // Remove load balancer - awsHelper.deleteLoadBalancer(loadBalancerInfo.getName(), - loadBalancerInfo.getRegion()); + // Remove all load balancers if 'terminate.lbs.on.extension.stop' = true in aws-extension.sh + if (AWSExtensionContext.getInstance().terminateLBsOnExtensionStop()) { + for (Map.Entry<String, LoadBalancerInfo> lbInfoEntry : clusterIdToLoadBalancerMap + .entrySet()) { + // Remove load balancer + awsHelper.deleteLoadBalancer(lbInfoEntry.getValue().getName(), + lbInfoEntry.getValue().getRegion()); + + // remove the persisted entry + try { + persistenceManager.remove(new LBInfoDTO(lbInfoEntry.getValue().getName(), lbInfoEntry.getKey(), + lbInfoEntry.getValue().getRegion())); + + } catch (PersistenceException e) { + log.error("Unable to remove persisted LB Information", e); + } + } + } else { + if (log.isInfoEnabled()) { + log.info("Not terminating LBs since terminate.lbs.on.extension.stop=false"); + } } } + private static void pause (long duration) { + // sleep to stop AWS Rate Exceeding: Caused by: com.amazonaws.AmazonServiceException: Rate exceeded + // (Service: AmazonElasticLoadBalancing; Status Code: 400; Error Code: Throttling; Request ID: xxx-xxx) + try { + Thread.sleep(duration); + } catch (InterruptedException ignored) {} + } + public static ConcurrentHashMap<String, LoadBalancerInfo> getClusterIdToLoadBalancerMap() { return clusterIdToLoadBalancerMap; } http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java index 626f1ce..dbcfb9a 100644 --- a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/Constants.java @@ -54,4 +54,11 @@ public class Constants { public static final String STATISTICS_INTERVAL = "statistics-interval"; public static final int STATISTICS_INTERVAL_MULTIPLE_OF = 60; public static final String LOAD_BALANCER_SSL_CERTIFICATE_ID = "load-balancer-ssl-certificate-id"; + public static final String APP_STICKY_SESSION_COOKIE_NAME = "app-sticky-session-cookie-name"; + public static final String TERMINATE_LBS_ON_EXTENSION_STOP = "terminate.lbs.on.extension.stop"; + public static final String TERMINATE_LB_ON_CLUSTER_REMOVAL = "terminate.lb.on.cluster.removal"; + public static final String STICKINESS_POLICY = "stickiness-policy"; + public static final String OPERATIMG_IN_VPC = "operating.in.vpc"; + public static final String ENABLE_CROSS_ZONE_LOADBALANCING = "enable.cross.zone.load.balancing"; + public static final String EC2_AVAILABILITY_ZONE_PROPERTY = "EC2_AVAILABILITY_ZONE"; } http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/exception/PersistenceException.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/exception/PersistenceException.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/exception/PersistenceException.java new file mode 100644 index 0000000..eb3fa52 --- /dev/null +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/exception/PersistenceException.java @@ -0,0 +1,39 @@ +/* + * 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.stratos.aws.extension.exception; + +public class PersistenceException extends Exception { + + private final String message; + + public PersistenceException (String message, Throwable cause) { + super(message, cause); + this.message = message; + } + + public PersistenceException (String message) { + super(message); + this.message = message; + } + + public String getMessage() { + return message; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/FileBasedPersistenceManager.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/FileBasedPersistenceManager.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/FileBasedPersistenceManager.java new file mode 100644 index 0000000..57b5427 --- /dev/null +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/FileBasedPersistenceManager.java @@ -0,0 +1,161 @@ +/* + * 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.stratos.aws.extension.persistence; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.aws.extension.exception.PersistenceException; +import org.apache.stratos.aws.extension.persistence.dao.LBInfoDAO; +import org.apache.stratos.aws.extension.persistence.dto.LBInfoDTO; + +import java.io.*; +import java.util.Set; + +public class FileBasedPersistenceManager implements PersistenceManager { + + private static final Log log = LogFactory.getLog(FileBasedPersistenceManager.class); + private String lbInfoFilePath = null; + + public FileBasedPersistenceManager () { + lbInfoFilePath = System.getProperty("lb.info.file"); + if (lbInfoFilePath == null || lbInfoFilePath.isEmpty()) { + throw new RuntimeException("required system property lb.info.file not found"); + } + } + + @Override + public synchronized void persist (LBInfoDTO lbInfoDTO) throws PersistenceException { + + LBInfoDAO retrievedLbInfoDAO = retrieveLBInfo(); + if (retrievedLbInfoDAO == null) { + retrievedLbInfoDAO = new LBInfoDAO(); + } + + retrievedLbInfoDAO.add(lbInfoDTO); + persistLBInfo(retrievedLbInfoDAO); + } + + @Override + public synchronized Set<LBInfoDTO> retrieve () throws PersistenceException { + return retrieveLBInfo() != null && retrieveLBInfo().get() != null ? retrieveLBInfo().get() : null; + } + + @Override + public synchronized void remove(LBInfoDTO lbInfoDTO) throws PersistenceException { + + LBInfoDAO retrievedLbInfoDAO = retrieveLBInfo(); + if (retrievedLbInfoDAO != null) { + retrievedLbInfoDAO.remove(lbInfoDTO); + persistLBInfo(retrievedLbInfoDAO); + } else { + log.info("No persisted LB Information found, hence unable to remove information of LB: " + lbInfoDTO.getName()); + } + } + + @Override + public synchronized void clear () throws PersistenceException { + + LBInfoDAO retrievedLbInfoDAO = retrieveLBInfo(); + if (retrievedLbInfoDAO == null) { + retrievedLbInfoDAO = new LBInfoDAO(); + } + + retrievedLbInfoDAO.clear(); + persistLBInfo(retrievedLbInfoDAO); + } + + private void persistLBInfo (LBInfoDAO lbInfoDAO) throws PersistenceException { + + FileOutputStream fileOutStream = null; + ObjectOutputStream ObjOutStream = null; + try { + fileOutStream = new FileOutputStream(lbInfoFilePath); + ObjOutStream = new ObjectOutputStream(fileOutStream); + ObjOutStream.writeObject(lbInfoDAO); + + } catch (IOException e) { + log.error(e.getMessage(), e); + throw new PersistenceException(e.getMessage(), e); + + } finally { + try { + if (ObjOutStream != null) { + ObjOutStream.close(); + } + if (fileOutStream != null) { + fileOutStream.close(); + } + + } catch (IOException e) { + log.error(e.getMessage(), e); + if (fileOutStream != null) { + try { + fileOutStream.close(); + } catch (IOException e1) {} + } + throw new PersistenceException(e.getMessage(), e); + } + + } + } + + private LBInfoDAO retrieveLBInfo () throws PersistenceException { + + FileInputStream fileInStream = null; + ObjectInputStream objInStream = null; + + try { + fileInStream = new FileInputStream(lbInfoFilePath); + objInStream = new ObjectInputStream(fileInStream); + return (LBInfoDAO) objInStream.readObject(); + + } catch (FileNotFoundException e) { + log.warn("File lbinformation.ser not found, any previously persisted LB information will not be reflected"); + return null; + + } catch (IOException e) { + log.error(e.getMessage(), e); + throw new PersistenceException(e.getMessage(), e); + + } catch (ClassNotFoundException e) { + log.error(e.getMessage(), e); + throw new PersistenceException(e.getMessage(), e); + + } finally { + try { + if (objInStream != null) { + objInStream.close(); + } + if (fileInStream != null) { + fileInStream.close(); + } + + } catch (IOException e) { + log.error(e.getMessage(), e); + if (fileInStream != null) { + try { + fileInStream.close(); + } catch (IOException e1) {} + } + throw new PersistenceException(e.getMessage(), e); + } + } + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/PersistenceManager.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/PersistenceManager.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/PersistenceManager.java new file mode 100644 index 0000000..ab7853a --- /dev/null +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/PersistenceManager.java @@ -0,0 +1,36 @@ +/* + * 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.stratos.aws.extension.persistence; + +import org.apache.stratos.aws.extension.exception.PersistenceException; +import org.apache.stratos.aws.extension.persistence.dto.LBInfoDTO; + +import java.util.Set; + +public interface PersistenceManager { + + public void persist (LBInfoDTO lbInfoDTO) throws PersistenceException; + + public Set<LBInfoDTO> retrieve () throws PersistenceException; + + public void remove (LBInfoDTO lbInfoDTO) throws PersistenceException; + + public void clear () throws PersistenceException; +} http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dao/LBInfoDAO.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dao/LBInfoDAO.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dao/LBInfoDAO.java new file mode 100644 index 0000000..29af4cf --- /dev/null +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dao/LBInfoDAO.java @@ -0,0 +1,52 @@ +/* + * 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.stratos.aws.extension.persistence.dao; + +import org.apache.stratos.aws.extension.persistence.dto.LBInfoDTO; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +public class LBInfoDAO implements Serializable { + + private static final long serialVersionUID = 6429853257198804560L; + private final Set<LBInfoDTO> lbInformation; + + public LBInfoDAO() { + lbInformation = new HashSet<>(); + } + + public void add (LBInfoDTO lbInfo) { + lbInformation.add(lbInfo); + } + + public void remove (LBInfoDTO lbInfo) { + lbInformation.remove(lbInfo); + } + + public void clear () { + lbInformation.clear(); + } + + public Set<LBInfoDTO> get () { + return lbInformation; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dto/LBInfoDTO.java ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dto/LBInfoDTO.java b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dto/LBInfoDTO.java new file mode 100644 index 0000000..215eb69 --- /dev/null +++ b/extensions/load-balancer/modules/aws-extension/src/main/java/org/apache/stratos/aws/extension/persistence/dto/LBInfoDTO.java @@ -0,0 +1,69 @@ +/* + * 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.stratos.aws.extension.persistence.dto; + +import java.io.Serializable; + +public class LBInfoDTO implements Serializable { + + private static final long serialVersionUID = -3788551425235723608L; + private String name; + private String clusterId; + private String region; + + public LBInfoDTO(String name, String clusterId, String region) { + this.name = name; + this.clusterId = clusterId; + this.region = region; + } + + public String getName() { + return name; + } + + public String getClusterId () { + return clusterId; + } + + public String getRegion() { + return region; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + LBInfoDTO lbInfoDTO = (LBInfoDTO) o; + + if (!name.equals(lbInfoDTO.name)) return false; + if (!clusterId.equals(lbInfoDTO.clusterId)) return false; + return region.equals(lbInfoDTO.region); + + } + + @Override + public int hashCode() { + int result = name.hashCode(); + result = 31 * result + clusterId.hashCode(); + result = 31 * result + region.hashCode(); + return result; + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/d68a6d50/extensions/load-balancer/modules/aws-extension/src/main/security/client-truststore.jks ---------------------------------------------------------------------- diff --git a/extensions/load-balancer/modules/aws-extension/src/main/security/client-truststore.jks b/extensions/load-balancer/modules/aws-extension/src/main/security/client-truststore.jks index be441f3..4da2690 100644 Binary files a/extensions/load-balancer/modules/aws-extension/src/main/security/client-truststore.jks and b/extensions/load-balancer/modules/aws-extension/src/main/security/client-truststore.jks differ
