diff --git a/labs/elb/src/main/java/org/jclouds/elb/ELB.java b/labs/elb/src/main/java/org/jclouds/elb/ELB.java new file mode 100644 index 0000000000..68e2bba407 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/ELB.java @@ -0,0 +1,43 @@ +package org.jclouds.elb; + +import org.jclouds.collect.PaginatedSet; +import org.jclouds.collect.PaginatedSets; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.features.LoadBalancerClient; +import org.jclouds.elb.options.ListLoadBalancersOptions; + +import com.google.common.base.Function; + +/** + * Utilities for using ELB. + * + * @author Adrian Cole + */ +public class ELB { + + /** + * List loadBalancers based on the criteria in the {@link ListLoadBalancersOptions} passed in. + * + * @param loadBalancerClient + * the {@link LoadBalancerClient} to use for the request + * @param options + * the {@link ListLoadBalancersOptions} describing the ListLoadBalancers request + * + * @return iterable of loadBalancers fitting the criteria + */ + public static Iterable list(final LoadBalancerClient loadBalancerClient, final ListLoadBalancersOptions options) { + return PaginatedSets.lazyContinue(loadBalancerClient.list(options), new Function>() { + + @Override + public PaginatedSet apply(String input) { + return loadBalancerClient.list(options.clone().marker(input)); + } + + @Override + public String toString() { + return "listLoadBalancers(" + options + ")"; + } + }); + } + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/ELBAsyncClient.java b/labs/elb/src/main/java/org/jclouds/elb/ELBAsyncClient.java index e8bd45146e..11f816d8fb 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/ELBAsyncClient.java +++ b/labs/elb/src/main/java/org/jclouds/elb/ELBAsyncClient.java @@ -31,12 +31,15 @@ import org.jclouds.aws.filters.FormSigner; import org.jclouds.elb.binders.BindAvailabilityZonesToIndexedFormParams; import org.jclouds.elb.binders.BindInstanceIdsToIndexedFormParams; import org.jclouds.elb.binders.BindLoadBalancerNamesToIndexedFormParams; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; +import org.jclouds.elb.features.LoadBalancerAsyncClient; import org.jclouds.elb.xml.CreateLoadBalancerResponseHandler; import org.jclouds.elb.xml.DescribeLoadBalancersResponseHandler; import org.jclouds.elb.xml.RegisterInstancesWithLoadBalancerResponseHandler; +import org.jclouds.location.Region; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.FormParams; @@ -47,6 +50,7 @@ import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import com.google.common.annotations.Beta; import com.google.common.util.concurrent.ListenableFuture; +import com.google.inject.Provides; /** * Provides access to EC2 Elastic Load Balancer via REST API. @@ -60,7 +64,25 @@ import com.google.common.util.concurrent.ListenableFuture; @RequestFilters(FormSigner.class) @VirtualHost public interface ELBAsyncClient { - public static final String VERSION = "2011-11-15"; + /** + * + * @return the Region codes configured + */ + @Provides + @Region + Set getConfiguredRegions(); + + /** + * Provides asynchronous access to LoadBalancer features. + */ + @Delegate + LoadBalancerAsyncClient getLoadBalancerClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + + + + + /// old stuff + public static final String VERSION = "2012-06-01"; // TODO: there are a lot of missing methods @@ -122,7 +144,7 @@ public interface ELBAsyncClient { @XMLResponseParser(DescribeLoadBalancersResponseHandler.class) @FormParams(keys = ACTION, values = "DescribeLoadBalancers") @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) - ListenableFuture> describeLoadBalancersInRegion( + ListenableFuture> describeLoadBalancersInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @BinderParam(BindLoadBalancerNamesToIndexedFormParams.class) String... loadbalancerNames); diff --git a/labs/elb/src/main/java/org/jclouds/elb/ELBClient.java b/labs/elb/src/main/java/org/jclouds/elb/ELBClient.java index 1135033794..b5d4a6d37c 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/ELBClient.java +++ b/labs/elb/src/main/java/org/jclouds/elb/ELBClient.java @@ -24,9 +24,15 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; import org.jclouds.concurrent.Timeout; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; +import org.jclouds.elb.features.LoadBalancerClient; +import org.jclouds.location.Region; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.annotations.Delegate; +import org.jclouds.rest.annotations.EndpointParam; import com.google.common.annotations.Beta; +import com.google.inject.Provides; /** * Provides access to EC2 Elastic Load Balancer via their REST API. @@ -38,7 +44,22 @@ import com.google.common.annotations.Beta; // see ELBAsyncClient @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface ELBClient { + /** + * + * @return the Region codes configured + */ + @Provides + @Region + Set getConfiguredRegions(); + + /** + * Provides synchronous access to LoadBalancer features. + */ + @Delegate + LoadBalancerClient getLoadBalancerClientForRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region); + + /// old stuff /** * Creates a load balancer * @@ -105,6 +126,6 @@ public interface ELBClient { * names associated with the LoadBalancers at creation time. * @return */ - Set describeLoadBalancersInRegion(@Nullable String region, String... loadbalancerNames); + Set describeLoadBalancersInRegion(@Nullable String region, String... loadbalancerNames); } diff --git a/labs/elb/src/main/java/org/jclouds/elb/config/ELBRestClientModule.java b/labs/elb/src/main/java/org/jclouds/elb/config/ELBRestClientModule.java index cf67ae6f7e..6513221d6d 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/config/ELBRestClientModule.java +++ b/labs/elb/src/main/java/org/jclouds/elb/config/ELBRestClientModule.java @@ -18,11 +18,18 @@ */ package org.jclouds.elb.config; +import java.util.Map; + import org.jclouds.aws.config.FormSigningRestClientModule; import org.jclouds.elb.ELBAsyncClient; import org.jclouds.elb.ELBClient; +import org.jclouds.elb.features.LoadBalancerAsyncClient; +import org.jclouds.elb.features.LoadBalancerClient; import org.jclouds.rest.ConfiguresRestClient; +import com.google.common.collect.ImmutableMap; +import com.google.common.reflect.TypeToken; + /** * Configures the ELB connection. * @@ -30,5 +37,10 @@ import org.jclouds.rest.ConfiguresRestClient; */ @ConfiguresRestClient public class ELBRestClientModule extends FormSigningRestClientModule { + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// + .put(LoadBalancerClient.class, LoadBalancerAsyncClient.class).build(); + public ELBRestClientModule() { + super(TypeToken.of(ELBClient.class), TypeToken.of(ELBAsyncClient.class), DELEGATE_MAP); + } } diff --git a/labs/elb/src/main/java/org/jclouds/elb/domain/CrappyLoadBalancer.java b/labs/elb/src/main/java/org/jclouds/elb/domain/CrappyLoadBalancer.java new file mode 100644 index 0000000000..93c5b25b2b --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/domain/CrappyLoadBalancer.java @@ -0,0 +1,447 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.domain; + +import java.util.HashSet; +import java.util.Set; + +import com.google.common.annotations.Beta; + +/** + * + * + * @author Lili Nader + */ +@Beta +// Missing fields, this class is too big, please cut out inner classes into top-level +@Deprecated +public class CrappyLoadBalancer implements Comparable { + + // Missing: createdTime, healthcheck + private String region; + private String name; + private Set instanceIds; + private Set availabilityZones; + private String dnsName; + // TODO: this could be cleaned up to be a policy collection of subclasses of Policy. note that + // docs suggest there could be many + private AppCookieStickinessPolicy appCookieStickinessPolicy; + private LBCookieStickinessPolicy lBCookieStickinessPolicy; + private Set loadBalancerListeners; + + public CrappyLoadBalancer() { + super(); + this.instanceIds = new HashSet(); + this.availabilityZones = new HashSet(); + this.loadBalancerListeners = new HashSet(); + } + + public CrappyLoadBalancer(String region, String name, Set instanceIds, Set availabilityZones, + String dnsName) { + this.region = region; + this.name = name; + this.instanceIds = instanceIds; + this.availabilityZones = availabilityZones; + this.dnsName = dnsName; + this.loadBalancerListeners = new HashSet(); + } + + public void setRegion(String region) { + this.region = region; + } + + public void setName(String name) { + this.name = name; + } + + public void setInstanceIds(Set instanceIds) { + this.instanceIds = instanceIds; + } + + public void setAvailabilityZones(Set availabilityZones) { + this.availabilityZones = availabilityZones; + } + + public void setDnsName(String dnsName) { + this.dnsName = dnsName; + } + + public void setAppCookieStickinessPolicy(AppCookieStickinessPolicy appCookieStickinessPolicy) { + this.appCookieStickinessPolicy = appCookieStickinessPolicy; + } + + public void setlBCookieStickinessPolicy(LBCookieStickinessPolicy lBCookieStickinessPolicy) { + this.lBCookieStickinessPolicy = lBCookieStickinessPolicy; + } + + public void setLoadBalancerListeners(Set loadBalancerListeners) { + this.loadBalancerListeners = loadBalancerListeners; + } + + public String getName() { + return name; + } + + public Set getInstanceIds() { + return instanceIds; + } + + public Set getAvailabilityZones() { + return availabilityZones; + } + + public String getDnsName() { + return dnsName; + } + + public AppCookieStickinessPolicy getAppCookieStickinessPolicy() { + return appCookieStickinessPolicy; + } + + public LBCookieStickinessPolicy getlBCookieStickinessPolicy() { + return lBCookieStickinessPolicy; + } + + public Set getLoadBalancerListeners() { + return loadBalancerListeners; + } + + public String getRegion() { + return region; + } + + @Override + public int compareTo(CrappyLoadBalancer that) { + return name.compareTo(that.name); + } + + @Override + public String toString() { + return "[region=" + region + ", name=" + name + ", instanceIds=" + instanceIds + ", availabilityZones=" + + availabilityZones + ", dnsName=" + dnsName + ", appCookieStickinessPolicy=" + + appCookieStickinessPolicy + ", lBCookieStickinessPolicy=" + lBCookieStickinessPolicy + + ", loadBalancerListeners=" + loadBalancerListeners + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((appCookieStickinessPolicy == null) ? 0 : appCookieStickinessPolicy.hashCode()); + result = prime * result + ((availabilityZones == null) ? 0 : availabilityZones.hashCode()); + result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode()); + result = prime * result + ((instanceIds == null) ? 0 : instanceIds.hashCode()); + result = prime * result + ((lBCookieStickinessPolicy == null) ? 0 : lBCookieStickinessPolicy.hashCode()); + result = prime * result + ((loadBalancerListeners == null) ? 0 : loadBalancerListeners.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((region == null) ? 0 : region.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CrappyLoadBalancer other = (CrappyLoadBalancer) obj; + if (appCookieStickinessPolicy == null) { + if (other.appCookieStickinessPolicy != null) + return false; + } else if (!appCookieStickinessPolicy.equals(other.appCookieStickinessPolicy)) + return false; + if (availabilityZones == null) { + if (other.availabilityZones != null) + return false; + } else if (!availabilityZones.equals(other.availabilityZones)) + return false; + if (dnsName == null) { + if (other.dnsName != null) + return false; + } else if (!dnsName.equals(other.dnsName)) + return false; + if (instanceIds == null) { + if (other.instanceIds != null) + return false; + } else if (!instanceIds.equals(other.instanceIds)) + return false; + if (lBCookieStickinessPolicy == null) { + if (other.lBCookieStickinessPolicy != null) + return false; + } else if (!lBCookieStickinessPolicy.equals(other.lBCookieStickinessPolicy)) + return false; + if (loadBalancerListeners == null) { + if (other.loadBalancerListeners != null) + return false; + } else if (!loadBalancerListeners.equals(other.loadBalancerListeners)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (region == null) { + if (other.region != null) + return false; + } else if (!region.equals(other.region)) + return false; + return true; + } + + public static class AppCookieStickinessPolicy { + private String policyName; + private String cookieName; + + public AppCookieStickinessPolicy() { + super(); + } + + public AppCookieStickinessPolicy(String policyName, String cookieName) { + super(); + this.policyName = policyName; + this.cookieName = cookieName; + } + + public String getPolicyName() { + return policyName; + } + + public String getCookieName() { + return cookieName; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public void setCookieName(String cookieName) { + this.cookieName = cookieName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((cookieName == null) ? 0 : cookieName.hashCode()); + result = prime * result + ((policyName == null) ? 0 : policyName.hashCode()); + return result; + } + + @Override + public String toString() { + return "[policyName=" + policyName + ", cookieName=" + cookieName + "]"; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AppCookieStickinessPolicy other = (AppCookieStickinessPolicy) obj; + if (cookieName == null) { + if (other.cookieName != null) + return false; + } else if (!cookieName.equals(other.cookieName)) + return false; + if (policyName == null) { + if (other.policyName != null) + return false; + } else if (!policyName.equals(other.policyName)) + return false; + return true; + } + + } + + public static class LBCookieStickinessPolicy { + private String policyName; + private Integer cookieExpirationPeriod; + + public LBCookieStickinessPolicy() { + super(); + } + + public LBCookieStickinessPolicy(String policyName, Integer cookieExpirationPeriod) { + super(); + this.policyName = policyName; + this.cookieExpirationPeriod = cookieExpirationPeriod; + } + + public String getPolicyName() { + return policyName; + } + + public Integer getCookieExpirationPeriod() { + return cookieExpirationPeriod; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public void setCookieExpirationPeriod(Integer cookieExpirationPeriod) { + this.cookieExpirationPeriod = cookieExpirationPeriod; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((cookieExpirationPeriod == null) ? 0 : cookieExpirationPeriod.hashCode()); + result = prime * result + ((policyName == null) ? 0 : policyName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LBCookieStickinessPolicy other = (LBCookieStickinessPolicy) obj; + if (cookieExpirationPeriod == null) { + if (other.cookieExpirationPeriod != null) + return false; + } else if (!cookieExpirationPeriod.equals(other.cookieExpirationPeriod)) + return false; + if (policyName == null) { + if (other.policyName != null) + return false; + } else if (!policyName.equals(other.policyName)) + return false; + return true; + } + + @Override + public String toString() { + return "[policyName=" + policyName + ", cookieExpirationPeriod=" + cookieExpirationPeriod + "]"; + } + + } + + public static class LoadBalancerListener { + // TODO: missing SSLCertificateId + private Set policyNames; + private Integer instancePort; + private Integer loadBalancerPort; + private String protocol; + + public LoadBalancerListener(Set policyNames, Integer instancePort, Integer loadBalancerPort, + String protocol) { + super(); + this.policyNames = policyNames; + this.instancePort = instancePort; + this.loadBalancerPort = loadBalancerPort; + this.protocol = protocol; + } + + public LoadBalancerListener() { + super(); + } + + public Set getPolicyNames() { + return policyNames; + } + + public Integer getInstancePort() { + return instancePort; + } + + public Integer getLoadBalancerPort() { + return loadBalancerPort; + } + + public String getProtocol() { + return protocol; + } + + public void setPolicyNames(Set policyNames) { + this.policyNames = policyNames; + } + + public void setInstancePort(Integer instancePort) { + this.instancePort = instancePort; + } + + public void setLoadBalancerPort(Integer loadBalancerPort) { + this.loadBalancerPort = loadBalancerPort; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((instancePort == null) ? 0 : instancePort.hashCode()); + result = prime * result + ((loadBalancerPort == null) ? 0 : loadBalancerPort.hashCode()); + result = prime * result + ((policyNames == null) ? 0 : policyNames.hashCode()); + result = prime * result + ((protocol == null) ? 0 : protocol.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LoadBalancerListener other = (LoadBalancerListener) obj; + if (instancePort == null) { + if (other.instancePort != null) + return false; + } else if (!instancePort.equals(other.instancePort)) + return false; + if (loadBalancerPort == null) { + if (other.loadBalancerPort != null) + return false; + } else if (!loadBalancerPort.equals(other.loadBalancerPort)) + return false; + if (policyNames == null) { + if (other.policyNames != null) + return false; + } else if (!policyNames.equals(other.policyNames)) + return false; + if (protocol == null) { + if (other.protocol != null) + return false; + } else if (!protocol.equals(other.protocol)) + return false; + return true; + } + + @Override + public String toString() { + return "[policyNames=" + policyNames + ", instancePort=" + instancePort + ", loadBalancerPort=" + + loadBalancerPort + ", protocol=" + protocol + "]"; + } + + } +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/domain/Listener.java b/labs/elb/src/main/java/org/jclouds/elb/domain/Listener.java new file mode 100644 index 0000000000..87a6ecc2fc --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/domain/Listener.java @@ -0,0 +1,214 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.domain; + +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import com.google.common.base.Objects.ToStringHelper; + +/** + * Listener is a process that listens for client connection requests. It is configured with a + * protocol and a port number for front-end (Load Balancer) and back-end (Back-end instance) + * connections. + * + * + * By default, your load balancer is set to use the HTTP protocol with port 80 for the front-end + * connection and the back-end connection. The default settings can be changed using the AWS + * Management Console, the Query API, the command line interface (CLI), or the SDKs. + * + * @see doc + * + * @author Adrian Cole + */ +public class Listener { + + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromListener(this); + } + + public static abstract class Builder> { + protected abstract T self(); + + protected int instancePort; + protected Protocol instanceProtocol; + protected int port; + protected Protocol protocol; + protected Optional SSLCertificateId = Optional.absent(); + + /** + * @see Listener#getInstancePort() + */ + public T instancePort(int instancePort) { + this.instancePort = instancePort; + return self(); + } + + /** + * @see Listener#getInstanceProtocol() + */ + public T instanceProtocol(Protocol instanceProtocol) { + this.instanceProtocol = instanceProtocol; + return self(); + } + + /** + * @see Listener#getPort() + */ + public T port(int port) { + this.port = port; + return self(); + } + + /** + * @see Listener#getProtocol() + */ + public T protocol(Protocol protocol) { + this.protocol = protocol; + if (instanceProtocol == null) + instanceProtocol = protocol; + return self(); + } + + /** + * @see Listener#getSSLCertificateId() + */ + public T SSLCertificateId(String SSLCertificateId) { + this.SSLCertificateId = Optional.fromNullable(SSLCertificateId); + return self(); + } + + public Listener build() { + return new Listener(instancePort, instanceProtocol, port, protocol, SSLCertificateId); + } + + public T fromListener(Listener in) { + return this.instancePort(in.getInstancePort()).instanceProtocol(in.getInstanceProtocol()).port(in.getPort()) + .protocol(in.getProtocol()).SSLCertificateId(in.getSSLCertificateId().orNull()); + } + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + protected final int instancePort; + protected final Protocol instanceProtocol; + protected final int port; + protected final Protocol protocol; + protected final Optional SSLCertificateId; + + protected Listener(int instancePort, Protocol instanceProtocol, int port, Protocol protocol, + Optional SSLCertificateId) { + this.instancePort = instancePort; + this.instanceProtocol = instanceProtocol; + this.port = port; + this.protocol = protocol; + this.SSLCertificateId = SSLCertificateId; + } + + /** + * The name associated with the LoadBalancer. The name must be unique within your set of + * LoadBalancers. + */ + public int getInstancePort() { + return instancePort; + } + + /** + * pecifies the protocol to use for routing traffic to back-end instances - HTTP, HTTPS, TCP, or + * SSL. This property cannot be modified for the life of the LoadBalancer. + */ + public Protocol getInstanceProtocol() { + return instanceProtocol; + } + + /** + * Specifies the external LoadBalancer port number. This property cannot be modified for the life + * of the LoadBalancer. + */ + public int getPort() { + return port; + } + + /** + * Specifies the LoadBalancer transport protocol to use for routing - HTTP, HTTPS, TCP or SSL. + * This property cannot be modified for the life of the LoadBalancer. + */ + public Protocol getProtocol() { + return protocol; + } + + /** + * The ARN string of the server certificate. To get the ARN of the server certificate, call the + * AWS Identity and Access Management UploadServerCertificate API. + */ + public Optional getSSLCertificateId() { + return SSLCertificateId; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return Objects.hashCode(instancePort, instanceProtocol, port, protocol, SSLCertificateId); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Listener other = (Listener) obj; + return Objects.equal(this.instancePort, other.instancePort) + && Objects.equal(this.instanceProtocol, other.instanceProtocol) && Objects.equal(this.port, other.port) + && Objects.equal(this.protocol, other.protocol) + && Objects.equal(this.SSLCertificateId, other.SSLCertificateId); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return string().toString(); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues().add("instancePort", instancePort).add("instanceProtocol", + instanceProtocol).add("port", port).add("protocol", protocol).add("SSLCertificateId", + SSLCertificateId.orNull()); + } + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/domain/ListenerWithPolicies.java b/labs/elb/src/main/java/org/jclouds/elb/domain/ListenerWithPolicies.java new file mode 100644 index 0000000000..77b2d512bb --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/domain/ListenerWithPolicies.java @@ -0,0 +1,118 @@ +/* + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.domain; + +import static com.google.common.base.Objects.equal; + +import java.util.Set; + +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import com.google.common.base.Objects.ToStringHelper; +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +public class ListenerWithPolicies extends Listener { + + public static Builder builder() { + return new ConcreteBuilder(); + } + + @Override + public Builder toBuilder() { + return builder().fromListenerWithPolicies(this); + } + + public static abstract class Builder> extends Listener.Builder { + + private ImmutableSet.Builder policyNames = ImmutableSet. builder(); + + /** + * @see ListenerWithPolicies#getPolicyNames() + */ + public T policyNames(Iterable policyName) { + this.policyNames.addAll(policyName); + return self(); + } + + /** + * @see ListenerWithPolicies#getPolicyNames() + */ + public T policyName(String policyName) { + this.policyNames.add(policyName); + return self(); + } + + @Override + public ListenerWithPolicies build() { + return new ListenerWithPolicies(instancePort, instanceProtocol, port, protocol, SSLCertificateId, policyNames + .build()); + } + + public T fromListenerWithPolicies(ListenerWithPolicies in) { + return fromListener(in).policyNames(in.getPolicyNames()); + } + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + private final Set policyNames; + + protected ListenerWithPolicies(int instancePort, Protocol instanceProtocol, int port, Protocol protocol, + Optional SSLCertificateId, Iterable policiesNames) { + super(instancePort, instanceProtocol, port, protocol, SSLCertificateId); + this.policyNames = ImmutableSet.copyOf(policiesNames); + } + + /** + * A list of policies enabled for this listener. An empty list indicates that no policies are + * enabled. + */ + public Set getPolicyNames() { + return policyNames; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + ListenerWithPolicies that = ListenerWithPolicies.class.cast(o); + return super.equals(that) && equal(this.policyNames, that.policyNames); + } + + @Override + public int hashCode() { + return Objects.hashCode(super.hashCode(), policyNames); + } + + @Override + public ToStringHelper string() { + return super.string().add("policyNames", policyNames); + } +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/domain/LoadBalancer.java b/labs/elb/src/main/java/org/jclouds/elb/domain/LoadBalancer.java index 61e00e8bb3..4455dd0c36 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/domain/LoadBalancer.java +++ b/labs/elb/src/main/java/org/jclouds/elb/domain/LoadBalancer.java @@ -18,141 +18,265 @@ */ package org.jclouds.elb.domain; -import java.util.HashSet; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Date; import java.util.Set; -import com.google.common.annotations.Beta; +import com.google.common.base.CaseFormat; +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; /** + * A load balancer is represented by a DNS name and a set of ports. The load balancer is the + * destination to which all requests intended for your application should be directed. Each load + * balancer can distribute requests to multiple EC2 instances. Load Balancers can span multiple + * Availability Zones within an EC2 region, but they cannot span multiple regions. * + *

note

* - * @author Lili Nader + * Elastic Load Balancing automatically generates a DNS name for each load balancer. You can map any + * other domain name (such as www.example.com) to the automatically generated DNS name using CNAME. + * Or you can use an Amazon Route 53 alias for the load balancer's DNS name. Amazon Route 53 + * provides secure and reliable routing to the infrastructure that uses AWS products, such as Amazon + * EC2, Amazon Simple Storage Service (Amazon S3), or Elastic Load Balancing. For more information + * on using Amazon Route 53 for your load balancer, see Using Domain Names with Elastic Load + * Balancing. For information about CNAME records, see the CNAME Record Wikipedia article. + * + * @see doc + * + * @author Adrian Cole */ -@Beta -// Missing fields, this class is too big, please cut out inner classes into top-level -public class LoadBalancer implements Comparable { +public class LoadBalancer { + /** + * Specifies the type of LoadBalancer. This option is only available for LoadBalancers attached + * to an Amazon VPC. + */ + public static enum Scheme { - // Missing: createdTime, healthcheck - private String region; - private String name; - private Set instanceIds; - private Set availabilityZones; - private String dnsName; - // TODO: this could be cleaned up to be a policy collection of subclasses of Policy. note that - // docs suggest there could be many - private AppCookieStickinessPolicy appCookieStickinessPolicy; - private LBCookieStickinessPolicy lBCookieStickinessPolicy; - private Set loadBalancerListeners; + /** + * the LoadBalancer has a publicly resolvable DNS name that resolves to public IP addresses + */ + INTERNET_FACING, + /** + * the LoadBalancer has a publicly resolvable DNS name that resolves to private IP addresses. + */ + INTERNAL, + /** + * The scheme was returned unrecognized. + */ + UNRECOGNIZED; - public LoadBalancer() { - super(); - this.instanceIds = new HashSet(); - this.availabilityZones = new HashSet(); - this.loadBalancerListeners = new HashSet(); + public String value() { + return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name())); + } + + @Override + public String toString() { + return value(); + } + + public static Scheme fromValue(String scheme) { + try { + return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(scheme, "scheme"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } } - public LoadBalancer(String region, String name, Set instanceIds, Set availabilityZones, - String dnsName) { - this.region = region; + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromLoadBalancer(this); + } + + public static abstract class Builder> { + protected abstract T self(); + + private String name; + private Date createdTime; + private String dnsName; + private ImmutableSet.Builder instanceIds = ImmutableSet. builder(); + private ImmutableSet.Builder listeners = ImmutableSet. builder(); + private Optional scheme = Optional.absent(); + private Optional VPCId = Optional.absent(); + + /** + * @see LoadBalancer#getName() + */ + public T name(String name) { + this.name = name; + return self(); + } + + /** + * @see LoadBalancer#getCreatedTime() + */ + public T createdTime(Date createdTime) { + this.createdTime = createdTime; + return self(); + } + + /** + * @see LoadBalancer#getDnsName() + */ + public T dnsName(String dnsName) { + this.dnsName = dnsName; + return self(); + } + + /** + * @see LoadBalancer#getInstanceIds() + */ + public T instanceIds(Iterable instanceId) { + this.instanceIds.addAll(instanceId); + return self(); + } + + /** + * @see LoadBalancer#getInstanceIds() + */ + public T instanceId(String instanceId) { + this.instanceIds.add(instanceId); + return self(); + } + + /** + * @see LoadBalancer#getListeners() + */ + public T listeners(Iterable listener) { + this.listeners.addAll(listener); + return self(); + } + + /** + * @see LoadBalancer#getListeners() + */ + public T listener(ListenerWithPolicies listener) { + this.listeners.add(listener); + return self(); + } + + /** + * @see LoadBalancer#getScheme() + */ + public T scheme(Scheme scheme) { + this.scheme = Optional.fromNullable(scheme); + return self(); + } + + /** + * @see LoadBalancer#getVPCId() + */ + public T VPCId(String VPCId) { + this.VPCId = Optional.fromNullable(VPCId); + return self(); + } + + public LoadBalancer build() { + return new LoadBalancer(name, createdTime, dnsName, instanceIds.build(), listeners.build(), scheme, VPCId); + } + + public T fromLoadBalancer(LoadBalancer in) { + return this.name(in.getName()).createdTime(in.getCreatedTime()).dnsName(in.getDnsName()).instanceIds( + in.getInstanceIds()).scheme(in.getScheme().orNull()).VPCId(in.getVPCId().orNull()); + } + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + + private final String name; + private final Date createdTime; + private final String dnsName; + private final Set instanceIds; + private final Set listeners; + private final Optional scheme; + private final Optional VPCId; + + protected LoadBalancer(String name, Date createdTime, String dnsName, Iterable instanceIds, + Iterable listeners, Optional scheme, Optional VPCId) { this.name = name; - this.instanceIds = instanceIds; - this.availabilityZones = availabilityZones; + this.createdTime = createdTime; this.dnsName = dnsName; - this.loadBalancerListeners = new HashSet(); - } - - public void setRegion(String region) { - this.region = region; - } - - public void setName(String name) { - this.name = name; - } - - public void setInstanceIds(Set instanceIds) { - this.instanceIds = instanceIds; - } - - public void setAvailabilityZones(Set availabilityZones) { - this.availabilityZones = availabilityZones; - } - - public void setDnsName(String dnsName) { - this.dnsName = dnsName; - } - - public void setAppCookieStickinessPolicy(AppCookieStickinessPolicy appCookieStickinessPolicy) { - this.appCookieStickinessPolicy = appCookieStickinessPolicy; - } - - public void setlBCookieStickinessPolicy(LBCookieStickinessPolicy lBCookieStickinessPolicy) { - this.lBCookieStickinessPolicy = lBCookieStickinessPolicy; - } - - public void setLoadBalancerListeners(Set loadBalancerListeners) { - this.loadBalancerListeners = loadBalancerListeners; + this.instanceIds = ImmutableSet.copyOf(instanceIds); + this.listeners = ImmutableSet.copyOf(listeners); + this.scheme = scheme; + this.VPCId = VPCId; } + /** + * The name associated with the LoadBalancer. The name must be unique within your set of + * LoadBalancers. + */ public String getName() { return name; } - public Set getInstanceIds() { - return instanceIds; - } - - public Set getAvailabilityZones() { - return availabilityZones; + /** + * Provides the date and time the LoadBalancer was created. + */ + public Date getCreatedTime() { + return createdTime; } + /** + * Specifies the external DNS name associated with the LoadBalancer. + */ public String getDnsName() { return dnsName; } - public AppCookieStickinessPolicy getAppCookieStickinessPolicy() { - return appCookieStickinessPolicy; + /** + * Provides a list of EC2 instance IDs for the LoadBalancer. + */ + public Set getInstanceIds() { + return instanceIds; } - public LBCookieStickinessPolicy getlBCookieStickinessPolicy() { - return lBCookieStickinessPolicy; + /** + * Provides a list of listeners for the LoadBalancer. + */ + public Set getListeners() { + return listeners; } - public Set getLoadBalancerListeners() { - return loadBalancerListeners; + /** + * Type of the loadbalancer; This option is only available for LoadBalancers attached to an + * Amazon VPC. + */ + public Optional getScheme() { + return scheme; } - public String getRegion() { - return region; - } - - @Override - public int compareTo(LoadBalancer that) { - return name.compareTo(that.name); - } - - @Override - public String toString() { - return "[region=" + region + ", name=" + name + ", instanceIds=" + instanceIds + ", availabilityZones=" - + availabilityZones + ", dnsName=" + dnsName + ", appCookieStickinessPolicy=" - + appCookieStickinessPolicy + ", lBCookieStickinessPolicy=" + lBCookieStickinessPolicy - + ", loadBalancerListeners=" + loadBalancerListeners + "]"; + /** + * Provides the ID of the VPC attached to the LoadBalancer. + */ + public Optional getVPCId() { + return VPCId; } + /** + * {@inheritDoc} + */ @Override public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((appCookieStickinessPolicy == null) ? 0 : appCookieStickinessPolicy.hashCode()); - result = prime * result + ((availabilityZones == null) ? 0 : availabilityZones.hashCode()); - result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode()); - result = prime * result + ((instanceIds == null) ? 0 : instanceIds.hashCode()); - result = prime * result + ((lBCookieStickinessPolicy == null) ? 0 : lBCookieStickinessPolicy.hashCode()); - result = prime * result + ((loadBalancerListeners == null) ? 0 : loadBalancerListeners.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((region == null) ? 0 : region.hashCode()); - return result; + return Objects.hashCode(name, createdTime); } + /** + * {@inheritDoc} + */ @Override public boolean equals(Object obj) { if (this == obj) @@ -162,285 +286,17 @@ public class LoadBalancer implements Comparable { if (getClass() != obj.getClass()) return false; LoadBalancer other = (LoadBalancer) obj; - if (appCookieStickinessPolicy == null) { - if (other.appCookieStickinessPolicy != null) - return false; - } else if (!appCookieStickinessPolicy.equals(other.appCookieStickinessPolicy)) - return false; - if (availabilityZones == null) { - if (other.availabilityZones != null) - return false; - } else if (!availabilityZones.equals(other.availabilityZones)) - return false; - if (dnsName == null) { - if (other.dnsName != null) - return false; - } else if (!dnsName.equals(other.dnsName)) - return false; - if (instanceIds == null) { - if (other.instanceIds != null) - return false; - } else if (!instanceIds.equals(other.instanceIds)) - return false; - if (lBCookieStickinessPolicy == null) { - if (other.lBCookieStickinessPolicy != null) - return false; - } else if (!lBCookieStickinessPolicy.equals(other.lBCookieStickinessPolicy)) - return false; - if (loadBalancerListeners == null) { - if (other.loadBalancerListeners != null) - return false; - } else if (!loadBalancerListeners.equals(other.loadBalancerListeners)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (region == null) { - if (other.region != null) - return false; - } else if (!region.equals(other.region)) - return false; - return true; + return Objects.equal(this.name, other.name) && Objects.equal(this.createdTime, other.createdTime); } - public static class AppCookieStickinessPolicy { - private String policyName; - private String cookieName; - - public AppCookieStickinessPolicy() { - super(); - } - - public AppCookieStickinessPolicy(String policyName, String cookieName) { - super(); - this.policyName = policyName; - this.cookieName = cookieName; - } - - public String getPolicyName() { - return policyName; - } - - public String getCookieName() { - return cookieName; - } - - public void setPolicyName(String policyName) { - this.policyName = policyName; - } - - public void setCookieName(String cookieName) { - this.cookieName = cookieName; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cookieName == null) ? 0 : cookieName.hashCode()); - result = prime * result + ((policyName == null) ? 0 : policyName.hashCode()); - return result; - } - - @Override - public String toString() { - return "[policyName=" + policyName + ", cookieName=" + cookieName + "]"; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AppCookieStickinessPolicy other = (AppCookieStickinessPolicy) obj; - if (cookieName == null) { - if (other.cookieName != null) - return false; - } else if (!cookieName.equals(other.cookieName)) - return false; - if (policyName == null) { - if (other.policyName != null) - return false; - } else if (!policyName.equals(other.policyName)) - return false; - return true; - } - + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Objects.toStringHelper(this).omitNullValues().add("name", name).add("createdTime", createdTime).add( + "dnsName", dnsName).add("instanceIds", instanceIds).add("listeners", listeners).add("scheme", + scheme.orNull()).add("VPCId", VPCId.orNull()).toString(); } - public static class LBCookieStickinessPolicy { - private String policyName; - private Integer cookieExpirationPeriod; - - public LBCookieStickinessPolicy() { - super(); - } - - public LBCookieStickinessPolicy(String policyName, Integer cookieExpirationPeriod) { - super(); - this.policyName = policyName; - this.cookieExpirationPeriod = cookieExpirationPeriod; - } - - public String getPolicyName() { - return policyName; - } - - public Integer getCookieExpirationPeriod() { - return cookieExpirationPeriod; - } - - public void setPolicyName(String policyName) { - this.policyName = policyName; - } - - public void setCookieExpirationPeriod(Integer cookieExpirationPeriod) { - this.cookieExpirationPeriod = cookieExpirationPeriod; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cookieExpirationPeriod == null) ? 0 : cookieExpirationPeriod.hashCode()); - result = prime * result + ((policyName == null) ? 0 : policyName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LBCookieStickinessPolicy other = (LBCookieStickinessPolicy) obj; - if (cookieExpirationPeriod == null) { - if (other.cookieExpirationPeriod != null) - return false; - } else if (!cookieExpirationPeriod.equals(other.cookieExpirationPeriod)) - return false; - if (policyName == null) { - if (other.policyName != null) - return false; - } else if (!policyName.equals(other.policyName)) - return false; - return true; - } - - @Override - public String toString() { - return "[policyName=" + policyName + ", cookieExpirationPeriod=" + cookieExpirationPeriod + "]"; - } - - } - - public static class LoadBalancerListener { - // TODO: missing SSLCertificateId - private Set policyNames; - private Integer instancePort; - private Integer loadBalancerPort; - private String protocol; - - public LoadBalancerListener(Set policyNames, Integer instancePort, Integer loadBalancerPort, - String protocol) { - super(); - this.policyNames = policyNames; - this.instancePort = instancePort; - this.loadBalancerPort = loadBalancerPort; - this.protocol = protocol; - } - - public LoadBalancerListener() { - super(); - } - - public Set getPolicyNames() { - return policyNames; - } - - public Integer getInstancePort() { - return instancePort; - } - - public Integer getLoadBalancerPort() { - return loadBalancerPort; - } - - public String getProtocol() { - return protocol; - } - - public void setPolicyNames(Set policyNames) { - this.policyNames = policyNames; - } - - public void setInstancePort(Integer instancePort) { - this.instancePort = instancePort; - } - - public void setLoadBalancerPort(Integer loadBalancerPort) { - this.loadBalancerPort = loadBalancerPort; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((instancePort == null) ? 0 : instancePort.hashCode()); - result = prime * result + ((loadBalancerPort == null) ? 0 : loadBalancerPort.hashCode()); - result = prime * result + ((policyNames == null) ? 0 : policyNames.hashCode()); - result = prime * result + ((protocol == null) ? 0 : protocol.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LoadBalancerListener other = (LoadBalancerListener) obj; - if (instancePort == null) { - if (other.instancePort != null) - return false; - } else if (!instancePort.equals(other.instancePort)) - return false; - if (loadBalancerPort == null) { - if (other.loadBalancerPort != null) - return false; - } else if (!loadBalancerPort.equals(other.loadBalancerPort)) - return false; - if (policyNames == null) { - if (other.policyNames != null) - return false; - } else if (!policyNames.equals(other.policyNames)) - return false; - if (protocol == null) { - if (other.protocol != null) - return false; - } else if (!protocol.equals(other.protocol)) - return false; - return true; - } - - @Override - public String toString() { - return "[policyNames=" + policyNames + ", instancePort=" + instancePort + ", loadBalancerPort=" - + loadBalancerPort + ", protocol=" + protocol + "]"; - } - - } } diff --git a/labs/elb/src/main/java/org/jclouds/elb/domain/Protocol.java b/labs/elb/src/main/java/org/jclouds/elb/domain/Protocol.java new file mode 100644 index 0000000000..508386c6c1 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/domain/Protocol.java @@ -0,0 +1,48 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.domain; + +/** + * Specifies transport protocol to use for routing or the protocol to use for routing traffic to + * back-end instances. + * + *

Note

If the front-end protocol is HTTP or HTTPS, InstanceProtocol has to be at the same + * protocol layer, i.e., HTTP or HTTPS. Likewise, if the front-end protocol is TCP or SSL, + * InstanceProtocol has to be TCP or SSL. + * + *

Note

If there is another listener with the same InstancePort whose InstanceProtocol is + * secure, i.e., HTTPS or SSL, the listener's InstanceProtocol has to be secure, i.e., HTTPS or SSL. + * If there is another listener with the same InstancePort whose InstanceProtocol is HTTP or TCP, + * the listener's InstanceProtocol must be either HTTP or TCP. + * + * @author Adrian Cole + * @see + * docs + */ +public enum Protocol { + + HTTP, HTTPS, TCP, SSL, + /** + * The protocol was returned unrecognized. + */ + UNRECOGNIZED; + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/features/LoadBalancerAsyncClient.java b/labs/elb/src/main/java/org/jclouds/elb/features/LoadBalancerAsyncClient.java new file mode 100644 index 0000000000..7c6ffc2586 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/features/LoadBalancerAsyncClient.java @@ -0,0 +1,80 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.features; + +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.collect.PaginatedSet; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.options.ListLoadBalancersOptions; +import org.jclouds.elb.xml.DescribeLoadBalancersResultHandler; +import org.jclouds.elb.xml.LoadBalancerHandler; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides access to Amazon ELB via the Query API + *

+ * + * @see doc + * @see LoadBalancerClient + * @author Adrian Cole + */ +@RequestFilters(FormSigner.class) +@VirtualHost +public interface LoadBalancerAsyncClient { + + /** + * @see LoadBalancerClient#get() + */ + @POST + @Path("/") + @XMLResponseParser(LoadBalancerHandler.class) + @FormParams(keys = "Action", values = "DescribeLoadBalancers") + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture get(@FormParam("LoadBalancerNames.member.1") String name); + + /** + * @see LoadBalancerClient#list() + */ + @POST + @Path("/") + @XMLResponseParser(DescribeLoadBalancersResultHandler.class) + @FormParams(keys = "Action", values = "DescribeLoadBalancers") + ListenableFuture> list(); + + /** + * @see LoadBalancerClient#list(ListLoadBalancersOptions) + */ + @POST + @Path("/") + @XMLResponseParser(DescribeLoadBalancersResultHandler.class) + @FormParams(keys = "Action", values = "DescribeLoadBalancers") + ListenableFuture> list(ListLoadBalancersOptions options); + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/features/LoadBalancerClient.java b/labs/elb/src/main/java/org/jclouds/elb/features/LoadBalancerClient.java new file mode 100644 index 0000000000..a55642b5dd --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/features/LoadBalancerClient.java @@ -0,0 +1,70 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.features; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.collect.PaginatedSet; +import org.jclouds.concurrent.Timeout; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.options.ListLoadBalancersOptions; +import org.jclouds.javax.annotation.Nullable; + +/** + * Provides access to Amazon ELB via the Query API + *

+ * + * @see + * @author Adrian Cole + */ +@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +public interface LoadBalancerClient { + + /** + * Retrieves information about the specified loadBalancer. + * + * @param name + * Name of the loadBalancer to get information about. + * @return null if not found + */ + @Nullable + LoadBalancer get(String name); + + /** + * Returns detailed configuration information for the specified LoadBalancers. If there are none, the action returns an + * empty list. + * + *
+ * You can paginate the results using the {@link ListLoadBalancersOptions parameter} + * + * @param options + * the options describing the loadBalancers query + * + * @return the response object + */ + PaginatedSet list(ListLoadBalancersOptions options); + + /** + * Lists the loadBalancers all load balancers + * + * @return the response object + */ + PaginatedSet list(); + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/config/ELBLoadBalancerServiceDependenciesModule.java b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/config/ELBLoadBalancerServiceDependenciesModule.java index 77abdd1517..3cc7efe1a4 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/config/ELBLoadBalancerServiceDependenciesModule.java +++ b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/config/ELBLoadBalancerServiceDependenciesModule.java @@ -18,7 +18,7 @@ */ package org.jclouds.elb.loadbalancer.config; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.elb.loadbalancer.functions.LoadBalancerToLoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; @@ -34,7 +34,7 @@ public class ELBLoadBalancerServiceDependenciesModule extends AbstractModule { @Override protected void configure() { - bind(new TypeLiteral>() { + bind(new TypeLiteral>() { }).to(LoadBalancerToLoadBalancerMetadata.class); } diff --git a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java index dcd09d0a21..33c9fd2729 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java +++ b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/functions/LoadBalancerToLoadBalancerMetadata.java @@ -27,7 +27,7 @@ import javax.inject.Singleton; import org.jclouds.collect.Memoized; import org.jclouds.domain.Location; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.domain.LoadBalancerType; import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl; @@ -45,7 +45,7 @@ import com.google.common.collect.Iterables; * @author Adrian Cole */ @Singleton -public class LoadBalancerToLoadBalancerMetadata implements Function { +public class LoadBalancerToLoadBalancerMetadata implements Function { @Resource protected static Logger logger = Logger.NULL; @@ -60,7 +60,7 @@ public class LoadBalancerToLoadBalancerMetadata implements Function converter; + private final Function converter; @Inject - protected ELBGetLoadBalancerMetadataStrategy(ELBClient client, Function converter) { + protected ELBGetLoadBalancerMetadataStrategy(ELBClient client, Function converter) { this.client = checkNotNull(client, "client"); this.converter = checkNotNull(converter, "converter"); } diff --git a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java index b23916edcd..7f82ffbe0a 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java +++ b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBListLoadBalancersStrategy.java @@ -35,7 +35,7 @@ import javax.inject.Singleton; import org.jclouds.Constants; import org.jclouds.elb.ELBAsyncClient; import org.jclouds.elb.ELBClient; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.reference.LoadBalancerConstants; import org.jclouds.loadbalancer.strategy.ListLoadBalancersStrategy; @@ -58,13 +58,13 @@ public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy { private final ELBClient client; private final ELBAsyncClient aclient; - private final Function converter; + private final Function converter; private final ExecutorService executor; private final Supplier> regions; @Inject protected ELBListLoadBalancersStrategy(ELBClient client, ELBAsyncClient aclient, - Function converter, + Function converter, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Region Supplier> regions) { this.client = checkNotNull(client, "client"); this.aclient = checkNotNull(aclient, "aclient"); @@ -75,13 +75,13 @@ public class ELBListLoadBalancersStrategy implements ListLoadBalancersStrategy { @Override public Iterable listLoadBalancers() { - Iterable loadBalancers; + Iterable loadBalancers; Set regions = this.regions.get(); if (regions.size() > 0) - loadBalancers = concat(transformParallel(regions, new Function>>() { + loadBalancers = concat(transformParallel(regions, new Function>>() { @Override - public ListenableFuture> apply(String from) { + public ListenableFuture> apply(String from) { return aclient.describeLoadBalancersInRegion(from); } diff --git a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBLoadBalanceNodesStrategy.java b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBLoadBalanceNodesStrategy.java index 96f3a696d4..dc635afb31 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBLoadBalanceNodesStrategy.java +++ b/labs/elb/src/main/java/org/jclouds/elb/loadbalancer/strategy/ELBLoadBalanceNodesStrategy.java @@ -33,7 +33,7 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.domain.Location; import org.jclouds.elb.ELBClient; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.loadbalancer.domain.LoadBalancerMetadata; import org.jclouds.loadbalancer.reference.LoadBalancerConstants; import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy; @@ -53,10 +53,10 @@ public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy { @Named(LoadBalancerConstants.LOADBALANCER_LOGGER) protected Logger logger = Logger.NULL; protected final ELBClient client; - protected final Function converter; + protected final Function converter; @Inject - protected ELBLoadBalanceNodesStrategy(ELBClient client, Function converter) { + protected ELBLoadBalanceNodesStrategy(ELBClient client, Function converter) { this.client = checkNotNull(client, "client"); this.converter = checkNotNull(converter, "converter"); } diff --git a/labs/elb/src/main/java/org/jclouds/elb/options/ListLoadBalancersOptions.java b/labs/elb/src/main/java/org/jclouds/elb/options/ListLoadBalancersOptions.java new file mode 100644 index 0000000000..acf4aeb340 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/options/ListLoadBalancersOptions.java @@ -0,0 +1,159 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.options; + +import java.util.Set; + +import org.jclouds.http.options.BaseHttpRequestOptions; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.base.Objects; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; + +/** + * Options used to list available loadBalancers. + * + * @see
docs + * + * @author Adrian Cole + */ +public class ListLoadBalancersOptions extends BaseHttpRequestOptions implements Cloneable { + + private String marker; + private Set names = Sets.newLinkedHashSet(); + + /** + * @see ListLoadBalancersOptions#getMarker() + */ + public ListLoadBalancersOptions marker(String marker) { + this.marker = marker; + return this; + } + + /** + * @see ListLoadBalancersOptions#getNames() + */ + public ListLoadBalancersOptions names(Set names) { + this.names = names; + return this; + } + + /** + * @see ListLoadBalancersOptions#getNames() + */ + public ListLoadBalancersOptions name(String name) { + this.names.add(name); + return this; + } + + /** + * list of names associated with the LoadBalancers at creation time. + */ + public Set getNames() { + return names; + } + + /** + * Use this parameter only when paginating results, and only in a subsequent request after you've + * received a response where the results are truncated. Set it to the value of the Marker element + * in the response you just received. + */ + @Nullable + public String getMarker() { + return marker; + } + + public static class Builder { + + /** + * @see ListLoadBalancersOptions#getMarker() + */ + public static ListLoadBalancersOptions marker(String marker) { + return new ListLoadBalancersOptions().marker(marker); + } + + /** + * @see ListLoadBalancersOptions#getNames() + */ + public static ListLoadBalancersOptions name(String name) { + return new ListLoadBalancersOptions().name(name); + } + + /** + * @see ListLoadBalancersOptions#getNames() + */ + public static ListLoadBalancersOptions names(Set names) { + return new ListLoadBalancersOptions().names(names); + } + } + + @Override + public Multimap buildFormParameters() { + Multimap params = super.buildFormParameters(); + if (marker != null) + params.put("Marker", marker); + if (names.size() > 0) { + int nameIndex = 1; + for (String name : names) { + params.put("LoadBalancerNames.member." + nameIndex, name); + nameIndex++; + } + } + return params; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + return Objects.hashCode(marker, names); + } + + @Override + public ListLoadBalancersOptions clone() { + return new ListLoadBalancersOptions().marker(marker).names(names); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ListLoadBalancersOptions other = ListLoadBalancersOptions.class.cast(obj); + return Objects.equal(this.marker, other.marker) && Objects.equal(this.names, other.names); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Objects.toStringHelper(this).omitNullValues().add("marker", marker).add("names", names).toString(); + } +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResponseHandler.java b/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResponseHandler.java index e22b9c6965..19923e139a 100644 --- a/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResponseHandler.java +++ b/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResponseHandler.java @@ -25,10 +25,10 @@ import javax.inject.Inject; import org.jclouds.aws.util.AWSUtils; import org.jclouds.date.DateService; -import org.jclouds.elb.domain.LoadBalancer; -import org.jclouds.elb.domain.LoadBalancer.AppCookieStickinessPolicy; -import org.jclouds.elb.domain.LoadBalancer.LBCookieStickinessPolicy; -import org.jclouds.elb.domain.LoadBalancer.LoadBalancerListener; +import org.jclouds.elb.domain.CrappyLoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer.AppCookieStickinessPolicy; +import org.jclouds.elb.domain.CrappyLoadBalancer.LBCookieStickinessPolicy; +import org.jclouds.elb.domain.CrappyLoadBalancer.LoadBalancerListener; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.logging.Logger; @@ -41,7 +41,7 @@ import com.google.common.collect.Sets; * @author Lili Nadar */ public class DescribeLoadBalancersResponseHandler extends - ParseSax.HandlerForGeneratedRequestWithResult> { + ParseSax.HandlerForGeneratedRequestWithResult> { private final DateService dateService; private final LoadBalancerListenerHandler listenerHandler; @@ -54,7 +54,7 @@ public class DescribeLoadBalancersResponseHandler extends @Resource protected Logger logger = Logger.NULL; - private Set contents = Sets.newLinkedHashSet(); + private Set contents = Sets.newLinkedHashSet(); private StringBuilder currentText = new StringBuilder(); private boolean inListenerDescriptions = false; @@ -65,7 +65,7 @@ public class DescribeLoadBalancersResponseHandler extends // TODO unused? private boolean inLoadBalancerDescriptions = false; - private LoadBalancer elb; + private CrappyLoadBalancer elb; // TODO unused? private AppCookieStickinessPolicy appCookieStickinessPolicy; // TODO unused? @@ -89,7 +89,7 @@ public class DescribeLoadBalancersResponseHandler extends if (qName.equals("member")) { if (!(inListenerDescriptions || inAppCookieStickinessPolicies || inInstances || inLBCookieStickinessPolicies || inAvailabilityZones)) { - elb = new LoadBalancer(); + elb = new CrappyLoadBalancer(); } } } @@ -141,7 +141,7 @@ public class DescribeLoadBalancersResponseHandler extends } @Override - public Set getResult() { + public Set getResult() { return contents; } diff --git a/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResultHandler.java b/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResultHandler.java new file mode 100644 index 0000000000..923c3e2da5 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/xml/DescribeLoadBalancersResultHandler.java @@ -0,0 +1,122 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.xml; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +import java.util.Set; + +import org.jclouds.collect.PaginatedSet; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import com.google.common.collect.Sets; +import com.google.inject.Inject; + +/** + * @see docs + * + * @author Adrian Cole + */ +public class DescribeLoadBalancersResultHandler extends + ParseSax.HandlerForGeneratedRequestWithResult> { + + private final LoadBalancerHandler loadBalancerHandler; + + private StringBuilder currentText = new StringBuilder(); + private Set loadBalancers = Sets.newLinkedHashSet(); + private boolean inLoadBalancers; + private String marker; + + protected int memberDepth; + + @Inject + public DescribeLoadBalancersResultHandler(LoadBalancerHandler loadBalancerHandler) { + this.loadBalancerHandler = loadBalancerHandler; + } + + /** + * {@inheritDoc} + */ + @Override + public PaginatedSet getResult() { + return PaginatedSet.copyOfWithMarker(loadBalancers, marker); + } + + /** + * {@inheritDoc} + */ + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (equalsOrSuffix(qName, "member")) { + memberDepth++; + } else if (equalsOrSuffix(qName, "LoadBalancerDescriptions")) { + inLoadBalancers = true; + } + if (inLoadBalancers) { + loadBalancerHandler.startElement(url, name, qName, attributes); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "member")) { + endMember( uri, name, qName); + memberDepth--; + } else if (equalsOrSuffix(qName, "LoadBalancerDescriptions")) { + inLoadBalancers = false; + } else if (equalsOrSuffix(qName, "Marker")) { + marker = currentOrNull(currentText); + } else if (inLoadBalancers) { + loadBalancerHandler.endElement(uri, name, qName); + } + + currentText = new StringBuilder(); + } + + protected void endMember(String uri, String name, String qName) throws SAXException { + if (inLoadBalancers) { + if (memberDepth == 1) + loadBalancers.add(loadBalancerHandler.getResult()); + else + loadBalancerHandler.endElement(uri, name, qName); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void characters(char ch[], int start, int length) { + if (inLoadBalancers) { + loadBalancerHandler.characters(ch, start, length); + } else { + currentText.append(ch, start, length); + } + } + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/xml/ListenerWithPoliciesHandler.java b/labs/elb/src/main/java/org/jclouds/elb/xml/ListenerWithPoliciesHandler.java new file mode 100644 index 0000000000..6877a8f167 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/xml/ListenerWithPoliciesHandler.java @@ -0,0 +1,82 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.xml; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +import org.jclouds.elb.domain.ListenerWithPolicies; +import org.jclouds.elb.domain.Protocol; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.SAXException; + +/** + * @see xml + * + * @author Adrian Cole + */ +public class ListenerWithPoliciesHandler extends ParseSax.HandlerForGeneratedRequestWithResult { + + private StringBuilder currentText = new StringBuilder(); + private ListenerWithPolicies.Builder builder = ListenerWithPolicies.builder(); + + /** + * {@inheritDoc} + */ + @Override + public ListenerWithPolicies getResult() { + try { + return builder.build(); + } finally { + builder = ListenerWithPolicies.builder(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "PolicyName")) { + builder.policyName(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "InstancePort")) { + builder.instancePort(Integer.parseInt(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "InstanceProtocol")) { + builder.instanceProtocol(Protocol.valueOf(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "LoadBalancerPort")) { + builder.port(Integer.parseInt(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "Protocol")) { + builder.protocol(Protocol.valueOf(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "SSLCertificateId")) { + builder.SSLCertificateId(currentOrNull(currentText)); + } + currentText = new StringBuilder(); + } + + /** + * {@inheritDoc} + */ + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + +} diff --git a/labs/elb/src/main/java/org/jclouds/elb/xml/LoadBalancerHandler.java b/labs/elb/src/main/java/org/jclouds/elb/xml/LoadBalancerHandler.java new file mode 100644 index 0000000000..c703edd823 --- /dev/null +++ b/labs/elb/src/main/java/org/jclouds/elb/xml/LoadBalancerHandler.java @@ -0,0 +1,129 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.xml; + +import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; + +import javax.inject.Inject; + +import org.jclouds.date.DateService; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.LoadBalancer.Scheme; +import org.jclouds.http.functions.ParseSax; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +/** + * @see + * + * @author Adrian Cole + */ +public class LoadBalancerHandler extends ParseSax.HandlerForGeneratedRequestWithResult { + private final DateService dateService; + private final ListenerWithPoliciesHandler listenerHandler; + + @Inject + protected LoadBalancerHandler(DateService dateService, ListenerWithPoliciesHandler listenerHandler) { + this.dateService = dateService; + this.listenerHandler = listenerHandler; + } + + private StringBuilder currentText = new StringBuilder(); + private LoadBalancer.Builder builder = LoadBalancer.builder(); + + private boolean inListeners; + + protected int memberDepth; + + /** + * {@inheritDoc} + */ + @Override + public LoadBalancer getResult() { + try { + return builder.build(); + } finally { + builder = LoadBalancer.builder(); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (equalsOrSuffix(qName, "member")) { + memberDepth++; + } else if (equalsOrSuffix(qName, "ListenerDescriptions")) { + inListeners = true; + } + if (inListeners) { + listenerHandler.startElement(url, name, qName, attributes); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (equalsOrSuffix(qName, "member")) { + endMember(uri, name, qName); + memberDepth--; + } else if (equalsOrSuffix(qName, "ListenerDescriptions")) { + inListeners = false; + } else if (equalsOrSuffix(qName, "LoadBalancerName")) { + builder.name(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "CreatedTime")) { + builder.createdTime(dateService.iso8601DateParse(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "DNSName")) { + builder.dnsName(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "InstanceId")) { + builder.instanceId(currentOrNull(currentText)); + } else if (equalsOrSuffix(qName, "Scheme")) { + builder.scheme(Scheme.fromValue(currentOrNull(currentText))); + } else if (equalsOrSuffix(qName, "VPCId")) { + builder.VPCId(currentOrNull(currentText)); + } else if (inListeners) { + listenerHandler.endElement(uri, name, qName); + } + currentText = new StringBuilder(); + } + + protected void endMember(String uri, String name, String qName) throws SAXException { + if (inListeners) { + builder.listener(listenerHandler.getResult()); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void characters(char ch[], int start, int length) { + if (inListeners) { + listenerHandler.characters(ch, start, length); + } else { + currentText.append(ch, start, length); + } + } + +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java b/labs/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java index effd8e5171..a0e187b79d 100644 --- a/labs/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java +++ b/labs/elb/src/test/java/org/jclouds/elb/ELBClientLiveTest.java @@ -24,7 +24,7 @@ import static org.testng.Assert.assertNotNull; import java.util.Set; import org.jclouds.apis.BaseContextLiveTest; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.rest.RestContext; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -73,7 +73,7 @@ public class ELBClientLiveTest ex } protected void describeLoadBalancerInRegion(String region) { - Set allResults = client.describeLoadBalancersInRegion(region); + Set allResults = client.describeLoadBalancersInRegion(region); assertNotNull(allResults); assert (allResults.size() >= 1) : region; } diff --git a/labs/elb/src/test/java/org/jclouds/elb/ELBTest.java b/labs/elb/src/test/java/org/jclouds/elb/ELBTest.java new file mode 100644 index 0000000000..103dc11315 --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/ELBTest.java @@ -0,0 +1,62 @@ +package org.jclouds.elb; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; + +import org.easymock.EasyMock; +import org.jclouds.collect.PaginatedSet; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.features.LoadBalancerClient; +import org.jclouds.elb.options.ListLoadBalancersOptions; +import org.testng.Assert; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * Tests behavior of {@code ELB}. + * + * @author Adrian Cole + */ +@Test(testName = "ELBTest") +public class ELBTest { + + + @Test + public void testSinglePageResult() throws Exception { + LoadBalancerClient loadBalancerClient = createMock(LoadBalancerClient.class); + ListLoadBalancersOptions options = new ListLoadBalancersOptions(); + PaginatedSet response = PaginatedSet.copyOf(ImmutableSet.of(createMock(LoadBalancer.class))); + + expect(loadBalancerClient.list(options)) + .andReturn(response) + .once(); + + EasyMock.replay(loadBalancerClient); + + Assert.assertEquals(1, Iterables.size(ELB.list(loadBalancerClient, options))); + } + + + @Test + public void testMultiPageResult() throws Exception { + LoadBalancerClient loadBalancerClient = createMock(LoadBalancerClient.class); + ListLoadBalancersOptions options = new ListLoadBalancersOptions(); + PaginatedSet response1 = PaginatedSet.copyOfWithMarker(ImmutableSet.of(createMock(LoadBalancer.class)), "NEXTTOKEN"); + PaginatedSet response2 = PaginatedSet.copyOf(ImmutableSet.of(createMock(LoadBalancer.class))); + + expect(loadBalancerClient.list(anyObject(ListLoadBalancersOptions.class))) + .andReturn(response1) + .once(); + expect(loadBalancerClient.list(anyObject(ListLoadBalancersOptions.class))) + .andReturn(response2) + .once(); + + EasyMock.replay(loadBalancerClient); + + Assert.assertEquals(2, Iterables.size(ELB.list(loadBalancerClient, options))); + } + +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/features/LoadBalancerClientExpectTest.java b/labs/elb/src/test/java/org/jclouds/elb/features/LoadBalancerClientExpectTest.java new file mode 100644 index 0000000000..8638a51f7f --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/features/LoadBalancerClientExpectTest.java @@ -0,0 +1,160 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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 + * + * Unles 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 expres or implied. See the License for the + * specific language governing permisions and limitations + * under the License. + */ +package org.jclouds.elb.features; + +import static org.jclouds.elb.options.ListLoadBalancersOptions.Builder.marker; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.net.URI; +import java.util.TimeZone; + +import org.jclouds.elb.ELBClient; +import org.jclouds.elb.internal.BaseELBClientExpectTest; +import org.jclouds.elb.parse.DescribeLoadBalancersResponseTest; +import org.jclouds.elb.parse.GetLoadBalancerResponseTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.rest.ResourceNotFoundException; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "LoadBalancerClientExpectTest") +public class LoadBalancerClientExpectTest extends BaseELBClientExpectTest { + + public LoadBalancerClientExpectTest() { + TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); + } + + HttpRequest get = HttpRequest.builder() + .method("POST") + .endpoint(URI.create("https://elasticloadbalancing.us-east-1.amazonaws.com/")) + .headers(ImmutableMultimap. builder() + .put("Host", "elasticloadbalancing.us-east-1.amazonaws.com") + .build()) + .payload( + payloadFromStringWithContentType( + "Action=DescribeLoadBalancers" + + "&LoadBalancerNames.member.1=name" + + "&Signature=EYzZgYDMGi9uFZU%2BVh%2FmmsJ9KmHxm5vEAF%2BhGF12BP4%3D" + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Timestamp=2009-11-08T15%3A54%3A08.897Z" + + "&Version=2012-06-01" + + "&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded")) + .build(); + + + public void testGetWhenResponseIs2xx() throws Exception { + + HttpResponse getResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/describe_loadbalancers.xml", "text/xml")).build(); + + ELBClient clientWhenExist = requestSendsResponse( + get, getResponse); + + assertEquals(clientWhenExist.getLoadBalancerClientForRegion(null).get("name").toString(), new GetLoadBalancerResponseTest().expected().toString()); + } + + public void testGetWhenResponseIs404() throws Exception { + + HttpResponse getResponse = HttpResponse.builder().statusCode(404).build(); + + ELBClient clientWhenDontExist = requestSendsResponse( + get, getResponse); + + assertNull(clientWhenDontExist.getLoadBalancerClientForRegion(null).get("name")); + } + + HttpRequest list = HttpRequest.builder() + .method("POST") + .endpoint(URI.create("https://elasticloadbalancing.us-east-1.amazonaws.com/")) + .headers(ImmutableMultimap. builder() + .put("Host", "elasticloadbalancing.us-east-1.amazonaws.com") + .build()) + .payload( + payloadFromStringWithContentType( + "Action=DescribeLoadBalancers" + + "&Signature=3pErfVJXXe4EndOr3nPMu2%2F5eO8aCvwcOaI%2BL64VMqg%3D" + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Timestamp=2009-11-08T15%3A54%3A08.897Z" + + "&Version=2012-06-01" + + "&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded")) + .build(); + + public void testListWhenResponseIs2xx() throws Exception { + + HttpResponse listResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/describe_loadbalancers.xml", "text/xml")).build(); + + ELBClient clientWhenExist = requestSendsResponse( + list, listResponse); + + assertEquals(clientWhenExist.getLoadBalancerClientForRegion(null).list().toString(), new DescribeLoadBalancersResponseTest().expected().toString()); + } + + // TODO: this should really be an empty set + @Test(expectedExceptions = ResourceNotFoundException.class) + public void testListWhenResponseIs404() throws Exception { + + HttpResponse listResponse = HttpResponse.builder().statusCode(404).build(); + + ELBClient clientWhenDontExist = requestSendsResponse( + list, listResponse); + + clientWhenDontExist.getLoadBalancerClientForRegion(null).list(); + } + + public void testListWithOptionsWhenResponseIs2xx() throws Exception { + HttpRequest listWithOptions = + HttpRequest.builder() + .method("POST") + .endpoint(URI.create("https://elasticloadbalancing.us-east-1.amazonaws.com/")) + .headers(ImmutableMultimap.builder() + .put("Host", "elasticloadbalancing.us-east-1.amazonaws.com") + .build()) + .payload(payloadFromStringWithContentType( + "Action=DescribeLoadBalancers" + + "&Marker=MARKER" + + "&Signature=%2FJttkIXuYljhZLJOPYyn%2BYIkDhD9skmePH3LYEnqmes%3D" + + "&SignatureMethod=HmacSHA256" + + "&SignatureVersion=2" + + "&Timestamp=2009-11-08T15%3A54%3A08.897Z" + + "&Version=2012-06-01" + + "&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded")) + .build(); + + HttpResponse listWithOptionsResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/describe_loadbalancers.xml", "text/xml")).build(); + + ELBClient clientWhenWithOptionsExist = requestSendsResponse(listWithOptions, + listWithOptionsResponse); + + assertEquals(clientWhenWithOptionsExist.getLoadBalancerClientForRegion(null).list(marker("MARKER")).toString(), + new DescribeLoadBalancersResponseTest().expected().toString()); + } +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/features/LoadBalancerClientLiveTest.java b/labs/elb/src/test/java/org/jclouds/elb/features/LoadBalancerClientLiveTest.java new file mode 100644 index 0000000000..6c8feae889 --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/features/LoadBalancerClientLiveTest.java @@ -0,0 +1,82 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.features; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.collect.PaginatedSet; +import org.jclouds.elb.domain.ListenerWithPolicies; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.internal.BaseELBClientLiveTest; +import org.jclouds.elb.options.ListLoadBalancersOptions; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "live", testName = "LoadBalancerClientLiveTest") +public class LoadBalancerClientLiveTest extends BaseELBClientLiveTest { + + private void checkLoadBalancer(LoadBalancer loadBalancer) { + checkNotNull(loadBalancer.getName(), "While Name can be null for a LoadBalancer, its Optional wrapper cannot."); + checkNotNull(loadBalancer.getCreatedTime(), "CreatedTime cannot be null for a LoadBalancer."); + checkNotNull(loadBalancer.getDnsName(), "DnsName cannot be null for a LoadBalancer."); + checkNotNull(loadBalancer.getScheme(), + "While Scheme can be null for a LoadBalancer, its Optional wrapper cannot."); + checkNotNull(loadBalancer.getVPCId(), "While VPCId can be null for a LoadBalancer, its Optional wrapper cannot."); + } + + private void checkListener(ListenerWithPolicies listener) { + checkNotNull(listener.getPolicyNames(), "While PolicyNames can be empty, it cannot be null."); + assert listener.getInstancePort() > 0 : "InstancePort must be positive"; + checkNotNull(listener.getInstanceProtocol(), "InstanceProtocol cannot be null"); + assert listener.getPort() > 0 : "Port must be positive"; + checkNotNull(listener.getProtocol(), "Protocol cannot be null"); + checkNotNull(listener.getSSLCertificateId(), + "While SSLCertificateId can be null for a ListenerWithPolicies, its Optional wrapper cannot."); + } + + @Test + protected void testDescribeLoadBalancers() { + PaginatedSet response = client().list(); + + for (LoadBalancer loadBalancer : response) { + checkLoadBalancer(loadBalancer); + for (ListenerWithPolicies listener : loadBalancer.getListeners()) { + checkListener(listener); + } + } + + if (response.size() > 0) { + LoadBalancer loadBalancer = response.iterator().next(); + Assert.assertEquals(client().get(loadBalancer.getName()), loadBalancer); + } + + // Test with a Marker, even if it's null + response = client().list(ListLoadBalancersOptions.Builder.marker(response.getNextMarker())); + for (LoadBalancer loadBalancer : response) { + checkLoadBalancer(loadBalancer); + } + } + + protected LoadBalancerClient client() { + return context.getApi().getLoadBalancerClientForRegion(null); + } +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBAsyncClientExpectTest.java b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBAsyncClientExpectTest.java new file mode 100644 index 0000000000..df56165a5d --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBAsyncClientExpectTest.java @@ -0,0 +1,38 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.internal; + +import java.util.Properties; + +import org.jclouds.elb.ELBAsyncClient; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; + +import com.google.common.base.Function; +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +public class BaseELBAsyncClientExpectTest extends BaseELBExpectTest { + public ELBAsyncClient createClient(Function fn, Module module, Properties props) { + return createInjector(fn, module, props).getInstance(ELBAsyncClient.class); + } +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBClientExpectTest.java b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBClientExpectTest.java new file mode 100644 index 0000000000..c713868c70 --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBClientExpectTest.java @@ -0,0 +1,30 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.internal; + +import org.jclouds.elb.ELBClient; + + +/** + * + * @author Adrian Cole + */ +public class BaseELBClientExpectTest extends BaseELBExpectTest { + +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBClientLiveTest.java b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBClientLiveTest.java new file mode 100644 index 0000000000..95c757d8b2 --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBClientLiveTest.java @@ -0,0 +1,46 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.internal; + +import org.jclouds.apis.BaseContextLiveTest; +import org.jclouds.elb.ELBApiMetadata; +import org.jclouds.elb.ELBAsyncClient; +import org.jclouds.elb.ELBClient; +import org.jclouds.rest.RestContext; +import org.testng.annotations.Test; + +import com.google.common.reflect.TypeToken; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live") +public class BaseELBClientLiveTest extends BaseContextLiveTest> { + + public BaseELBClientLiveTest() { + provider = "elb"; + } + + @Override + protected TypeToken> contextType() { + return ELBApiMetadata.CONTEXT_TOKEN; + } + +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBExpectTest.java b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBExpectTest.java new file mode 100644 index 0000000000..9da28ef956 --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/internal/BaseELBExpectTest.java @@ -0,0 +1,78 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.internal; + +import static com.google.common.collect.Maps.transformValues; + +import java.net.URI; +import java.util.Map; + +import org.jclouds.aws.domain.Region; +import org.jclouds.date.DateService; +import org.jclouds.elb.config.ELBRestClientModule; +import org.jclouds.location.config.LocationModule; +import org.jclouds.location.suppliers.RegionIdToURISupplier; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.internal.BaseRestClientExpectTest; +import org.jclouds.util.Suppliers2; + +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableMap; +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +public class BaseELBExpectTest extends BaseRestClientExpectTest { + + public BaseELBExpectTest() { + provider = "elb"; + } + + @ConfiguresRestClient + private static final class TestELBRestClientModule extends ELBRestClientModule { + + @Override + protected void installLocations() { + install(new LocationModule()); + bind(RegionIdToURISupplier.class).toInstance(new RegionIdToURISupplier() { + + @Override + public Map> get() { + return transformValues(ImmutableMap. of(Region.EU_WEST_1, URI + .create("https://elasticloadbalancing.eu-west-1.amazonaws.com"), Region.US_EAST_1, URI + .create("https://elasticloadbalancing.us-east-1.amazonaws.com"), Region.US_WEST_1, URI + .create("https://elasticloadbalancing.us-west-1.amazonaws.com")), Suppliers2. ofInstanceFunction()); + } + + }); + } + + @Override + protected String provideTimeStamp(final DateService dateService) { + return "2009-11-08T15:54:08.897Z"; + } + } + + @Override + protected Module createModule() { + return new TestELBRestClientModule(); + } +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/loadbalancer/ELBLoadBalancerServiceLiveTest.java b/labs/elb/src/test/java/org/jclouds/elb/loadbalancer/ELBLoadBalancerServiceLiveTest.java index 89334a26a1..9d23ff6852 100644 --- a/labs/elb/src/test/java/org/jclouds/elb/loadbalancer/ELBLoadBalancerServiceLiveTest.java +++ b/labs/elb/src/test/java/org/jclouds/elb/loadbalancer/ELBLoadBalancerServiceLiveTest.java @@ -27,7 +27,7 @@ import java.util.Set; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.elb.ELBAsyncClient; import org.jclouds.elb.ELBClient; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.loadbalancer.BaseLoadBalancerServiceLiveTest; import org.jclouds.rest.RestContext; import org.jclouds.sshj.config.SshjSshClientModule; @@ -61,9 +61,9 @@ public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveT for (NodeMetadata node : nodes) { instanceIds.add(node.getProviderId()); } - Set elbs = elbClient.describeLoadBalancersInRegion(null); + Set elbs = elbClient.describeLoadBalancersInRegion(null); assertNotNull(elbs); - for (LoadBalancer elb : elbs) { + for (CrappyLoadBalancer elb : elbs) { if (elb.getName().equals(group)) assertEquals(elb.getInstanceIds(), instanceIds); } diff --git a/labs/elb/src/test/java/org/jclouds/elb/options/ListLoadBalancersOptionsTest.java b/labs/elb/src/test/java/org/jclouds/elb/options/ListLoadBalancersOptionsTest.java new file mode 100644 index 0000000000..490d53790e --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/options/ListLoadBalancersOptionsTest.java @@ -0,0 +1,57 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.options; + +import static org.jclouds.elb.options.ListLoadBalancersOptions.Builder.marker; +import static org.jclouds.elb.options.ListLoadBalancersOptions.Builder.name; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code ListLoadBalancersOptions} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ListLoadBalancersOptionsTest") +public class ListLoadBalancersOptionsTest { + + public void testMarker() { + ListLoadBalancersOptions options = new ListLoadBalancersOptions().marker("FFFFF"); + assertEquals(ImmutableSet.of("FFFFF"), options.buildFormParameters().get("Marker")); + } + + public void testMarkerStatic() { + ListLoadBalancersOptions options = marker("FFFFF"); + assertEquals(ImmutableSet.of("FFFFF"), options.buildFormParameters().get("Marker")); + } + + public void testName() { + ListLoadBalancersOptions options = new ListLoadBalancersOptions().name("my-load-balancer"); + assertEquals(ImmutableSet.of("my-load-balancer"), options.buildFormParameters().get("LoadBalancerNames.member.1")); + } + + public void testNameStatic() { + ListLoadBalancersOptions options = name("my-load-balancer"); + assertEquals(ImmutableSet.of("my-load-balancer"), options.buildFormParameters().get("LoadBalancerNames.member.1")); + } + +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/parse/DescribeLoadBalancersResponseTest.java b/labs/elb/src/test/java/org/jclouds/elb/parse/DescribeLoadBalancersResponseTest.java new file mode 100644 index 0000000000..0e511a08c0 --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/parse/DescribeLoadBalancersResponseTest.java @@ -0,0 +1,67 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.collect.PaginatedSet; +import org.jclouds.date.internal.SimpleDateFormatDateService; +import org.jclouds.elb.domain.ListenerWithPolicies; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.Protocol; +import org.jclouds.elb.xml.DescribeLoadBalancersResultHandler; +import org.jclouds.http.functions.BaseHandlerTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "DescribeLoadBalancersResponseTest") +public class DescribeLoadBalancersResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/describe_loadbalancers.xml"); + + PaginatedSet expected = expected(); + + DescribeLoadBalancersResultHandler handler = injector.getInstance(DescribeLoadBalancersResultHandler.class); + PaginatedSet result = factory.create(handler).parse(is); + + assertEquals(result.toString(), expected.toString()); + + } + + public PaginatedSet expected() { + return PaginatedSet.copyOf(ImmutableSet.of( + LoadBalancer.builder() + .name("my-load-balancer") + .createdTime(new SimpleDateFormatDateService().iso8601DateParse("2010-03-03T20:54:45.110Z")) + .dnsName("my-load-balancer-1400212309.us-east-1.elb.amazonaws.com") + .instanceIds(ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632")) + .listener(ListenerWithPolicies.builder().protocol(Protocol.HTTP).port(80).instancePort(80).build()) + .listener(ListenerWithPolicies.builder().protocol(Protocol.TCP).port(443).instancePort(443).build()) + .build())); + } + +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/parse/GetLoadBalancerResponseTest.java b/labs/elb/src/test/java/org/jclouds/elb/parse/GetLoadBalancerResponseTest.java new file mode 100644 index 0000000000..6556e122cd --- /dev/null +++ b/labs/elb/src/test/java/org/jclouds/elb/parse/GetLoadBalancerResponseTest.java @@ -0,0 +1,67 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.jclouds.elb.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.date.internal.SimpleDateFormatDateService; +import org.jclouds.elb.domain.ListenerWithPolicies; +import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.Protocol; +import org.jclouds.elb.xml.LoadBalancerHandler; +import org.jclouds.http.functions.BaseHandlerTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "GetLoadBalancerResponseTest") +public class GetLoadBalancerResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/describe_loadbalancers.xml"); + + LoadBalancer expected = expected(); + + LoadBalancerHandler handler = injector.getInstance(LoadBalancerHandler.class); + LoadBalancer result = factory.create(handler).parse(is); + + assertEquals(result, expected); + assertEquals(result.getCreatedTime(), expected.getCreatedTime()); + assertEquals(result.getDnsName(), expected.getDnsName()); + assertEquals(result.getScheme(), expected.getScheme()); + assertEquals(result.getVPCId(), expected.getVPCId()); + } + + public LoadBalancer expected() { + return LoadBalancer.builder() + .name("my-load-balancer") + .createdTime(new SimpleDateFormatDateService().iso8601DateParse("2010-03-03T20:54:45.110Z")) + .dnsName("my-load-balancer-1400212309.us-east-1.elb.amazonaws.com") + .instanceIds(ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632")) + .listener(ListenerWithPolicies.builder().protocol(Protocol.HTTP).port(80).instancePort(80).build()) + .listener(ListenerWithPolicies.builder().protocol(Protocol.TCP).port(443).instancePort(443).build()) + .build(); + } +} diff --git a/labs/elb/src/test/java/org/jclouds/elb/xml/DescribeLoadBalancerResponseHandlerTest.java b/labs/elb/src/test/java/org/jclouds/elb/xml/DescribeLoadBalancerResponseHandlerTest.java index 6577a925bf..fb78e05efe 100644 --- a/labs/elb/src/test/java/org/jclouds/elb/xml/DescribeLoadBalancerResponseHandlerTest.java +++ b/labs/elb/src/test/java/org/jclouds/elb/xml/DescribeLoadBalancerResponseHandlerTest.java @@ -26,7 +26,7 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.Set; -import org.jclouds.elb.domain.LoadBalancer; +import org.jclouds.elb.domain.CrappyLoadBalancer; import org.jclouds.http.functions.BaseHandlerTest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; @@ -48,21 +48,21 @@ public class DescribeLoadBalancerResponseHandlerTest extends BaseHandlerTest { public void testParse() { InputStream is = getClass().getResourceAsStream("/describe_loadbalancers.xml"); - Set contents = Sets.newHashSet(); - LoadBalancer dummy = new LoadBalancer(null, "my-load-balancer", ImmutableSet.of("i-5b33e630", + Set contents = Sets.newHashSet(); + CrappyLoadBalancer dummy = new CrappyLoadBalancer(null, "my-load-balancer", ImmutableSet.of("i-5b33e630", "i-8f26d7e4", "i-5933e632"), ImmutableSet.of("us-east-1a"), "my-load-balancer-1400212309.us-east-1.elb.amazonaws.com"); contents.add(dummy); - Set result = parseLoadBalancers(is); + Set result = parseLoadBalancers(is); assertEquals(result, contents); } - private Set parseLoadBalancers(InputStream is) { + private Set parseLoadBalancers(InputStream is) { DescribeLoadBalancersResponseHandler handler = injector.getInstance(DescribeLoadBalancersResponseHandler.class); addDefaultRegionToHandler(handler); - Set result = factory.create(handler).parse(is); + Set result = factory.create(handler).parse(is); return result; }