From 6bc848c2327bd37e81c4bedc5778988aae5fb348 Mon Sep 17 00:00:00 2001 From: Everett Toews Date: Thu, 3 Jan 2013 17:11:38 -0600 Subject: [PATCH] More attributes and domain objects for Rackspace Cloud Load Balancers. --- .../cloudloadbalancers/domain/AccessRule.java | 153 +++++ .../domain/ConnectionThrottle.java | 150 +++++ .../domain/HealthMonitor.java | 240 +++++++ .../domain/LoadBalancer.java | 590 ++++++++++-------- .../domain/LoadBalancerAttributes.java | 108 +++- .../domain/LoadBalancerRequest.java | 145 +++-- .../cloudloadbalancers/domain/Metadata.java | 111 ++++ .../cloudloadbalancers/domain/Node.java | 199 +++--- .../domain/NodeAttributes.java | 64 +- .../domain/NodeRequest.java | 121 ++-- .../domain/SSLTermination.java | 152 +++++ .../domain/SourceAddresses.java | 127 ++++ .../cloudloadbalancers/domain/VirtualIP.java | 161 +++-- .../domain/internal/BaseLoadBalancer.java | 467 +++++++++++--- .../domain/internal/BaseNode.java | 250 +++++--- .../functions/ConvertLB.java | 24 +- .../cloudloadbalancers/functions/LB.java | 13 +- .../features/LoadBalancerApiExpectTest.java | 4 +- .../features/LoadBalancerApiLiveTest.java | 2 +- .../features/NodeApiExpectTest.java | 6 + .../features/NodeApiLiveTest.java | 4 +- .../functions/ParseLoadBalancerTest.java | 38 +- .../functions/ParseLoadBalancersTest.java | 5 +- .../test/resources/loadbalancer-create.json | 26 +- .../src/test/resources/loadbalancer-get.json | 114 +++- .../test/resources/loadbalancer-update.json | 9 +- .../src/test/resources/node-get.json | 30 +- .../src/test/resources/node-update.json | 2 +- .../src/test/resources/nodes-add.json | 2 +- 29 files changed, 2435 insertions(+), 882 deletions(-) create mode 100644 apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/AccessRule.java create mode 100644 apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/ConnectionThrottle.java create mode 100644 apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/HealthMonitor.java create mode 100644 apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Metadata.java create mode 100644 apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SSLTermination.java create mode 100644 apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SourceAddresses.java diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/AccessRule.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/AccessRule.java new file mode 100644 index 0000000000..7b53b457d6 --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/AccessRule.java @@ -0,0 +1,153 @@ +/** + * 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.rackspace.cloudloadbalancers.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * The access list management feature allows fine-grained network access controls to be applied to the load balancer's + * virtual IP address. A single IP address, multiple IP addresses, or entire network subnets can be added as an access + * rule. Items that are configured with the ALLOW type will always take precedence over items with the DENY type. To + * reject traffic from all items except for those with the ALLOW type, add an access rules with an address of + * "0.0.0.0/0" and a DENY type. + * + * @author Everett Toews + */ +public class AccessRule { + + private final int id; + private final Type type; + private final String address; + + protected AccessRule(int id, Type type, String address) { + this.id = id; + this.type = checkNotNull(type, "type"); + this.address = checkNotNull(address, "address"); + } + + public int getId() { + return this.id; + } + + public Type getType() { + return this.type; + } + + public String getAddress() { + return this.address; + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + AccessRule that = AccessRule.class.cast(obj); + + return Objects.equal(this.id, that.id); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this) + .add("id", id).add("type", type).add("address", address); + } + + @Override + public String toString() { + return string().toString(); + } + + public static enum Type { + /** + * Specifies items that will always take precedence over items with the DENY type. + */ + ALLOW, + + /** + * Specifies items to which traffic can be denied. + */ + DENY, + + UNRECOGNIZED; + + public static Type fromValue(String type) { + try { + return valueOf(checkNotNull(type, "type")); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + } + + public static class Builder { + private int id; + private Type type; + private String address; + + /** + * @see AccessRule#getId() + */ + public Builder id(int id) { + this.id = id; + return this; + } + + /** + * @see Type + */ + public Builder type(Type type) { + this.type = type; + return this; + } + + /** + * IP address for item to add to access list. + */ + public Builder address(String address) { + this.address = address; + return this; + } + + public AccessRule build() { + return new AccessRule(id, type, address); + } + + public Builder from(AccessRule in) { + return this + .id(in.getId()) + .type(in.getType()) + .address(in.getAddress()); + } + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().from(this); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/ConnectionThrottle.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/ConnectionThrottle.java new file mode 100644 index 0000000000..d44fe20903 --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/ConnectionThrottle.java @@ -0,0 +1,150 @@ +/** + * 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.rackspace.cloudloadbalancers.domain; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * The connection throttling feature imposes limits on the number of connections per IP address to help mitigate + * malicious or abusive traffic to your applications. The attributes in the table that follows can be configured + * based on the traffic patterns for your sites. + * + * @author Everett Toews + */ +public class ConnectionThrottle { + + private final int maxConnections; + private final int minConnections; + private final int maxConnectionRate; + private final int rateInterval; + + protected ConnectionThrottle(int maxConnections, int minConnections, int maxConnectionRate, int rateInterval) { + this.maxConnections = maxConnections; + this.minConnections = minConnections; + this.maxConnectionRate = maxConnectionRate; + this.rateInterval = rateInterval; + } + + public int getMaxConnections() { + return this.maxConnections; + } + + public int getMinConnections() { + return this.minConnections; + } + + public int getMaxConnectionRate() { + return this.maxConnectionRate; + } + + public int getRateInterval() { + return this.rateInterval; + } + + @Override + public int hashCode() { + return Objects.hashCode(maxConnections, minConnections, maxConnectionRate, rateInterval); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + ConnectionThrottle that = ConnectionThrottle.class.cast(obj); + + return Objects.equal(this.maxConnections, that.maxConnections) + && Objects.equal(this.minConnections, that.minConnections) + && Objects.equal(this.maxConnectionRate, that.maxConnectionRate) + && Objects.equal(this.rateInterval, that.rateInterval); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).add("maxConnections", maxConnections).add("minConnections", minConnections) + .add("maxConnectionRate", maxConnectionRate).add("rateInterval", rateInterval); + } + + @Override + public String toString() { + return string().toString(); + } + + public static class Builder { + private int maxConnections; + private int minConnections; + private int maxConnectionRate; + private int rateInterval; + + /** + * Maximum number of connections to allow for a single IP address. Setting a value of 0 will allow unlimited + * simultaneous connections; otherwise set a value between 1 and 100000. + */ + public Builder maxConnections(int maxConnections) { + this.maxConnections = maxConnections; + return this; + } + + /** + * Allow at least this number of connections per IP address before applying throttling restrictions. Setting + * a value of 0 allows unlimited simultaneous connections; otherwise, set a value between 1 and 1000. + */ + public Builder minConnections(int minConnections) { + this.minConnections = minConnections; + return this; + } + + /** + * Maximum number of connections allowed from a single IP address in the defined rateInterval. Setting a value + * of 0 allows an unlimited connection rate; otherwise, set a value between 1 and 100000. + */ + public Builder maxConnectionRate(int maxConnectionRate) { + this.maxConnectionRate = maxConnectionRate; + return this; + } + + /** + * Frequency (in seconds) at which the maxConnectionRate is assessed. For example, a maxConnectionRate of 30 + * with a rateInterval of 60 would allow a maximum of 30 connections per minute for a single IP address. This + * value must be between 1 and 3600. + */ + public Builder rateInterval(int rateInterval) { + this.rateInterval = rateInterval; + return this; + } + + public ConnectionThrottle build() { + return new ConnectionThrottle(maxConnections, minConnections, maxConnectionRate, rateInterval); + } + + public Builder from(ConnectionThrottle in) { + return this.maxConnections(in.getMaxConnections()).minConnections(in.getMinConnections()) + .maxConnectionRate(in.getMaxConnectionRate()).rateInterval(in.getRateInterval()); + } + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().from(this); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/HealthMonitor.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/HealthMonitor.java new file mode 100644 index 0000000000..cd1e159dc4 --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/HealthMonitor.java @@ -0,0 +1,240 @@ +/** + * 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.rackspace.cloudloadbalancers.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * The load balancing service includes a health monitoring operation which periodically checks your back-end nodes to + * ensure they are responding correctly. If a node is not responding, it is removed from rotation until the health + * monitor determines that the node is functional. In addition to being performed periodically, the health check also + * is performed against every node that is added to ensure that the node is operating properly before allowing it to + * service traffic. Only one health monitor is allowed to be enabled on a load balancer at a time. + * + * As part of your strategy for monitoring connections, you should consider defining secondary nodes that provide + * failover for effectively routing traffic in case the primary node fails. This is an additional feature that will + * ensure you remain up in case your primary node fails. + * + * @author Everett Toews + */ +public class HealthMonitor { + + private final Type type; + private final int delay; + private final int timeout; + private final int attemptsBeforeDeactivation; + private final String bodyRegex; + private final String statusRegex; + private final String path; + private final String hostHeader; + + protected HealthMonitor(Type type, int delay, int timeout, int attemptsBeforeDeactivation, String bodyRegex, + String statusRegex, String path, String hostHeader) { + this.type = checkNotNull(type, "type"); + this.delay = delay; + this.timeout = timeout; + this.attemptsBeforeDeactivation = attemptsBeforeDeactivation; + this.bodyRegex = bodyRegex; + this.statusRegex = statusRegex; + this.path = path; + this.hostHeader = hostHeader; + } + + public Type getType() { + return type; + } + + public int getDelay() { + return delay; + } + + public int getTimeout() { + return timeout; + } + + public int getAttemptsBeforeDeactivation() { + return attemptsBeforeDeactivation; + } + + public String getBodyRegex() { + return bodyRegex; + } + + public String getStatusRegex() { + return statusRegex; + } + + public String getPath() { + return path; + } + + public String getHostHeader() { + return hostHeader; + } + + @Override + public int hashCode() { + return Objects.hashCode(type, delay, timeout, attemptsBeforeDeactivation, bodyRegex, statusRegex, path, + hostHeader); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + HealthMonitor that = HealthMonitor.class.cast(obj); + + return Objects.equal(this.type, that.type) && Objects.equal(this.delay, that.delay) + && Objects.equal(this.timeout, that.timeout) + && Objects.equal(this.attemptsBeforeDeactivation, that.attemptsBeforeDeactivation) + && Objects.equal(this.bodyRegex, that.bodyRegex) && Objects.equal(this.statusRegex, that.statusRegex) + && Objects.equal(this.path, that.path) && Objects.equal(this.hostHeader, that.hostHeader); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).add("type", type).add("delay", delay).add("timeout", timeout) + .add("attemptsBeforeDeactivation", attemptsBeforeDeactivation).add("bodyRegex", bodyRegex) + .add("statusRegex", statusRegex).add("path", path).add("hostHeader", hostHeader); + } + + @Override + public String toString() { + return string().toString(); + } + + /** + * Every health monitor has a type attribute to signify what kind of monitor it is. + */ + public static enum Type { + CONNECT, HTTP, HTTPS, UNRECOGNIZED; + + public static Type fromValue(String type) { + try { + return valueOf(checkNotNull(type, "type")); + } + catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + } + + public static class Builder { + private Type type; + private int delay; + private int timeout; + private int attemptsBeforeDeactivation; + private String bodyRegex; + private String statusRegex; + private String path; + private String hostHeader; + + /** + * Type of the health monitor. Must be specified as CONNECT to monitor connections. + */ + public Builder type(Type type) { + this.type = type; + return this; + } + + /** + * Required. The minimum number of seconds to wait before executing the health monitor. + * Must be a number between 1 and 3600. + */ + public Builder delay(int delay) { + this.delay = delay; + return this; + } + + /** + * Required. Maximum number of seconds to wait for a connection to be established before timing out. + * Must be a number between 1 and 300. + */ + public Builder timeout(int timeout) { + this.timeout = timeout; + return this; + } + + /** + * Required. Number of permissible monitor failures before removing a node from rotation. + * Must be a number between 1 and 10. + */ + public Builder attemptsBeforeDeactivation(int attemptsBeforeDeactivation) { + this.attemptsBeforeDeactivation = attemptsBeforeDeactivation; + return this; + } + + /** + * Required (if using HTTP/S). A regular expression that will be used to evaluate the contents of the body of + * the response. + */ + public Builder bodyRegex(String bodyRegex) { + this.bodyRegex = bodyRegex; + return this; + } + + /** + * Required (if using HTTP/S). A regular expression that will be used to evaluate the HTTP status code returned + * in the response. + */ + public Builder statusRegex(String statusRegex) { + this.statusRegex = statusRegex; + return this; + } + + /** + * Required (if using HTTP/S). The HTTP path that will be used in the sample request. + */ + public Builder path(String path) { + this.path = path; + return this; + } + + /** + * Optional (if using HTTP/S). The name of a host for which the health monitors will check. + */ + public Builder hostHeader(String hostHeader) { + this.hostHeader = hostHeader; + return this; + } + + public HealthMonitor build() { + return new HealthMonitor(type, delay, timeout, attemptsBeforeDeactivation, bodyRegex, statusRegex, path, + hostHeader); + } + + public Builder from(HealthMonitor in) { + return this.type(in.getType()).delay(in.getDelay()).timeout(in.getTimeout()) + .attemptsBeforeDeactivation(in.getAttemptsBeforeDeactivation()).bodyRegex(in.getBodyRegex()) + .statusRegex(in.getStatusRegex()).path(in.getPath()).hostHeader(in.getHostHeader()); + } + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().from(this); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancer.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancer.java index c0e55ec6d4..aea3f27c8d 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancer.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancer.java @@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Date; +import java.util.Map; import java.util.Set; import org.jclouds.javax.annotation.Nullable; @@ -33,138 +34,154 @@ import com.google.common.base.Objects.ToStringHelper; import com.google.common.collect.ImmutableSet; /** - * * @author Adrian Cole */ public class LoadBalancer extends BaseLoadBalancer { - @SuppressWarnings("unchecked") - public static Builder builder() { - return new Builder(); + private final String region; + private final int id; + private final Status status; + private final Set virtualIPs; + private final String clusterName; + private final Date created; + private final Date updated; + private final boolean contentCaching; + private final int nodeCount; + private final SSLTermination sslTermination; + private final SourceAddresses sourceAddresses; + + public LoadBalancer(String region, int id, String name, String protocol, @Nullable Integer port, Set nodes, + @Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, Status status, + Set virtualIPs, @Nullable Map sessionPersistenceType, + String clusterName, Date created, Date updated, @Nullable Map connectionLogging, + @Nullable ConnectionThrottle connectionThrottle, boolean contentCaching, int nodeCount, + @Nullable HealthMonitor healthMonitor, @Nullable SSLTermination sslTermination, + SourceAddresses sourceAddresses, @Nullable Set accessRules, + @Nullable Set metadata) { + super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging, + connectionThrottle, healthMonitor, accessRules, metadata); + this.region = checkNotNull(region, "region"); + checkArgument(id != -1, "id must be specified"); + this.id = id; + this.status = checkNotNull(status, "status"); + this.virtualIPs = ImmutableSet.copyOf(checkNotNull(virtualIPs, "virtualIPs")); + this.clusterName = clusterName; + this.created = checkNotNull(created, "created"); + this.updated = checkNotNull(updated, "updated"); + this.contentCaching = contentCaching; + this.nodeCount = nodeCount; + this.sslTermination = sslTermination; + this.sourceAddresses = sourceAddresses; + } + + public String getRegion() { + return region; + } + + public int getId() { + return id; } /** - * {@inheritDoc} + * @see Status */ - @Override - public Builder toBuilder() { - return new Builder().from(this); + public Status getStatus() { + return status; } - public static class Builder extends BaseLoadBalancer.Builder { - private String region; - private int id = -1; - private Status status; - private Set virtualIPs = ImmutableSet. of(); - private String sessionPersistenceType; - private String clusterName; - private Date created; - private Date updated; - private boolean connectionLoggingEnabled; - private int nodeCount = 0; + /** + * @see VirtualIP + */ + public Set getVirtualIPs() { + return virtualIPs; + } - public Builder region(String region) { - this.region = region; - return this; - } + /** + * Name of the cluster. + */ + public String getClusterName() { + return clusterName; + } - public Builder id(int id) { - this.id = id; - return this; - } + /** + * When the load balancer was created. + */ + public Date getCreated() { + return created; + } - public Builder status(Status status) { - this.status = status; - return this; - } + /** + * When the load balancer was updated. + */ + public Date getUpdated() { + return updated; + } - public Builder algorithm(Algorithm algorithm) { - algorithm(algorithm.name()); - return this; - } + /** + * View the current content caching configuration. + */ + public boolean isContentCaching() { + return contentCaching; + } - public Builder virtualIPs(Iterable virtualIPs) { - this.virtualIPs = ImmutableSet. copyOf(checkNotNull(virtualIPs, "virtualIPs")); - return this; - } + /** + * Broken out as a separate field because when LoadBalancers are returned from + * {@link LoadBalancerApi#list()}, no Nodes are returned (so you can't rely on getNodes().size()) + * but a nodeCount is returned. When {@link LoadBalancerApi#get(int)} is called, nodes are + * returned by no nodeCount is returned. + * + * @return The number of Nodes in this LoadBalancer + */ + public int getNodeCount() { + return nodes.size() > 0 ? nodes.size() : nodeCount; + } - public Builder sessionPersistenceType(String sessionPersistenceType) { - this.sessionPersistenceType = sessionPersistenceType; - return this; - } + /** + * @see SSLTermination + */ + @Nullable + public SSLTermination getSSLTermination() { + return sslTermination; + } - public Builder clusterName(String clusterName) { - this.clusterName = clusterName; - return this; - } + /** + * @see SourceAddresses + */ + public SourceAddresses getSourceAddresses() { + return sourceAddresses; + } - public Builder created(Date created) { - this.created = created; - return this; - } + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues().add("id", id).add("region", region).add("status", status) + .add("name", name).add("protocol", protocol).add("port", port).add("nodeCount", getNodeCount()) + .add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm).add("halfClosed", halfClosed) + .add("clusterName", clusterName).add("created", created).add("updated", updated) + .add("contentCaching", contentCaching).add("sessionPersistenceType", getSessionPersistenceType()) + .add("sslTermination", sslTermination).add("connectionLogging", isConnectionLogging()) + .add("connectionThrottle", connectionThrottle).add("healthMonitor", healthMonitor) + .add("accessRules", accessList).add("metadata", getMetadata()).add("sourceAddresses", sourceAddresses) + .add("virtualIPs", virtualIPs); + } - public Builder updated(Date updated) { - this.updated = updated; - return this; - } + @Override + public String toString() { + return string().toString(); + } - public Builder connectionLoggingEnabled(boolean connectionLoggingEnabled) { - this.connectionLoggingEnabled = connectionLoggingEnabled; - return this; - } + @Override + public int hashCode() { + return Objects.hashCode(id, region); + } - /** - * @see LoadBalancer#getNodeCount() - */ - public Builder nodeCount(int nodeCount) { - this.nodeCount = nodeCount; - return this; - } - - public LoadBalancer build() { - return new LoadBalancer(region, id, name, protocol, port, algorithm, status, virtualIPs, nodes, - sessionPersistenceType, clusterName, created, updated, connectionLoggingEnabled, nodeCount); - } - - @Override - public Builder nodes(Iterable nodes) { - this.nodes = ImmutableSet. copyOf(checkNotNull(nodes, "nodes")); - return this; - } - - @Override - public Builder node(Node nodes) { - this.nodes.add(checkNotNull(nodes, "nodes")); - return this; - } - - @Override - public Builder algorithm(String algorithm) { - return Builder.class.cast(super.algorithm(algorithm)); - } - - @Override - public Builder from(LoadBalancer in) { - return Builder.class.cast(super.from(in)).id(in.getId()).status(in.getStatus()).virtualIPs(in.getVirtualIPs()) - .clusterName(in.getClusterName()).created(in.getCreated()).updated(in.getUpdated()) - .connectionLoggingEnabled(in.isConnectionLoggingEnabled()).nodeCount(in.getNodeCount()); - } - - @Override - public Builder name(String name) { - return Builder.class.cast(super.name(name)); - } - - @Override - public Builder port(Integer port) { - return Builder.class.cast(super.port(port)); - } - - @Override - public Builder protocol(String protocol) { - return Builder.class.cast(super.protocol(protocol)); - } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + LoadBalancer that = LoadBalancer.class.cast(obj); + return Objects.equal(this.id, that.id) && Objects.equal(this.region, that.region); } /** @@ -216,168 +233,221 @@ public class LoadBalancer extends BaseLoadBalancer { public static Status fromValue(String status) { try { return valueOf(checkNotNull(status, "status")); - } catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { return UNRECOGNIZED; } } } - /** - * All load balancers utilize an algorithm that defines how traffic should be directed between - * back-end nodes. The default algorithm for newly created load balancers is RANDOM, which can be - * overridden at creation time or changed after the load balancer has been initially provisioned. - * The algorithm name is to be constant within a major revision of the load balancing API, though - * new algorithms may be created with a unique algorithm name within a given major revision of - * the service API. - */ - public static enum Algorithm { - /** - * The node with the lowest number of connections will receive requests. - */ - LEAST_CONNECTIONS, - /** - * Back-end servers are selected at random. - */ - RANDOM, - /** - * Connections are routed to each of the back-end servers in turn. - */ - ROUND_ROBIN, - /** - * Each request will be assigned to a node based on the number of concurrent connections to - * the node and its weight. - */ - WEIGHTED_LEAST_CONNECTIONS, - /** - * A round robin algorithm, but with different proportions of traffic being directed to the - * back-end nodes. Weights must be defined as part of the load balancer's node configuration. - */ - WEIGHTED_ROUND_ROBIN, UNRECOGNIZED; + public static class Builder extends BaseLoadBalancer.Builder { + private String region; + private int id = -1; + private Status status; + private Set virtualIPs = ImmutableSet. of(); + private String clusterName; + private Date created; + private Date updated; + private boolean contentCaching; + private int nodeCount = 0; + private SSLTermination sslTermination; + private SourceAddresses sourceAddresses; - public static Algorithm fromValue(String algorithm) { - try { - return valueOf(checkNotNull(algorithm, "algorithm")); - } catch (IllegalArgumentException e) { - return UNRECOGNIZED; - } + public Builder region(String region) { + this.region = region; + return this; + } + + public Builder id(int id) { + this.id = id; + return this; + } + + public Builder status(Status status) { + this.status = status; + return this; + } + + public Builder virtualIPs(Iterable virtualIPs) { + this.virtualIPs = ImmutableSet. copyOf(checkNotNull(virtualIPs, "virtualIPs")); + return this; + } + + public Builder clusterName(String clusterName) { + this.clusterName = clusterName; + return this; + } + + public Builder created(Date created) { + this.created = created; + return this; + } + + public Builder updated(Date updated) { + this.updated = updated; + return this; + } + + public Builder contentCaching(boolean contentCaching) { + this.contentCaching = contentCaching; + return this; + } + + /** + * @see LoadBalancer#getNodeCount() + */ + public Builder nodeCount(int nodeCount) { + this.nodeCount = nodeCount; + return this; + } + + public Builder sslTermination(@Nullable SSLTermination sslTermination) { + this.sslTermination = sslTermination; + return this; + } + + public Builder sourceAddresses(@Nullable SourceAddresses sourceAddresses) { + this.sourceAddresses = sourceAddresses; + return this; + } + + public LoadBalancer build() { + return new LoadBalancer(region, id, name, protocol, port, nodes, timeout, halfClosed, algorithm, status, + virtualIPs, sessionPersistence, clusterName, created, updated, connectionLogging, connectionThrottle, + contentCaching, nodeCount, healthMonitor, sslTermination, sourceAddresses, accessRules, metadata); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder nodes(Iterable nodes) { + this.nodes = ImmutableSet. copyOf(checkNotNull(nodes, "nodes")); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Builder node(Node nodes) { + this.nodes.add(checkNotNull(nodes, "nodes")); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Builder algorithm(Algorithm algorithm) { + return Builder.class.cast(super.algorithm(algorithm)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder name(String name) { + return Builder.class.cast(super.name(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder port(Integer port) { + return Builder.class.cast(super.port(port)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder protocol(String protocol) { + return Builder.class.cast(super.protocol(protocol)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder timeout(@Nullable Integer timeout) { + return Builder.class.cast(super.timeout(timeout)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder halfClosed(@Nullable Boolean halfClosed) { + return Builder.class.cast(super.halfClosed(halfClosed)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder sessionPersistenceType(@Nullable SessionPersistenceType sessionPersistenceType) { + return Builder.class.cast(super.sessionPersistenceType(sessionPersistenceType)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder connectionLogging(@Nullable Boolean connectionLogging) { + return Builder.class.cast(super.connectionLogging(connectionLogging)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder connectionThrottle(@Nullable ConnectionThrottle connectionThrottle) { + return Builder.class.cast(super.connectionThrottle(connectionThrottle)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder healthMonitor(@Nullable HealthMonitor healthMonitor) { + return Builder.class.cast(super.healthMonitor(healthMonitor)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder accessRules(@Nullable Set accessRules) { + return Builder.class.cast(super.accessRules(accessRules)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder metadata(@Nullable Set metadata) { + return Builder.class.cast(super.metadata(metadata)); + } + + @Override + public Builder from(LoadBalancer in) { + return Builder.class.cast(super.from(in)).region(in.getRegion()).id(in.getId()).status(in.getStatus()) + .virtualIPs(in.getVirtualIPs()).clusterName(in.getClusterName()).created(in.getCreated()) + .updated(in.getUpdated()).contentCaching(in.isContentCaching()).nodeCount(in.getNodeCount()) + .sslTermination(in.getSSLTermination()).sourceAddresses(in.getSourceAddresses()); } } - public static Algorithm[] WEIGHTED_ALGORITHMS = { Algorithm.WEIGHTED_LEAST_CONNECTIONS, - Algorithm.WEIGHTED_ROUND_ROBIN }; - - private final String region; - private final int id; - private final Status status; - private final Algorithm algorithm; - private final Set virtualIPs; - private final String sessionPersistenceType; - private final String clusterName; - private final Date created; - private final Date updated; - private final boolean connectionLoggingEnabled; - private int nodeCount = 0; - - public LoadBalancer(String region, int id, String name, String protocol, Integer port, @Nullable String algorithm, - Status status, Iterable virtualIPs, Iterable nodes, String sessionPersistenceType, - String clusterName, Date created, Date updated, boolean connectionLoggingEnabled, Integer nodeCount) { - super(name, protocol, port, algorithm, nodes); - this.region = checkNotNull(region, "region"); - checkArgument(id != -1, "id must be specified"); - this.id = id; - this.status = checkNotNull(status, "status"); - this.algorithm = algorithm != null ? Algorithm.fromValue(algorithm) : null; - this.virtualIPs = ImmutableSet.copyOf(checkNotNull(virtualIPs, "virtualIPs")); - this.sessionPersistenceType = sessionPersistenceType; - this.clusterName = clusterName; - this.created = checkNotNull(created, "created"); - this.updated = checkNotNull(updated, "updated"); - this.connectionLoggingEnabled = connectionLoggingEnabled; - this.nodeCount = nodeCount; - } - - public String getRegion() { - return region; - } - - public int getId() { - return id; - } - - public Status getStatus() { - return status; - } - - /** - * - * @return algorithm, which may be null if the load balancer is deleted - */ - @Nullable - public Algorithm getTypedAlgorithm() { - return algorithm; - } - - public Set getVirtualIPs() { - return virtualIPs; - } - - public String getClusterName() { - return clusterName; - } - - public String getSessionPersistenceType() { - return sessionPersistenceType; - } - - public Date getCreated() { - return created; - } - - public Date getUpdated() { - return updated; - } - - public boolean isConnectionLoggingEnabled() { - return connectionLoggingEnabled; - } - - /** - * Broken out as a separate field because when LoadBalancers are returned from - * {@link LoadBalancerApi#list()}, no Nodes are returned (so you can't rely on getNodes().size()) - * but a nodeCount is returned. When {@link LoadBalancerApi#get(int)} is called, nodes are - * returned by no nodeCount is returned. - * - * @return The number of Nodes in this LoadBalancer - */ - public int getNodeCount() { - return nodes.size() > 0 ? nodes.size() : nodeCount; - } - - protected ToStringHelper string() { - return Objects.toStringHelper(this).omitNullValues() - .add("id", id).add("region", region).add("name", name).add("protocol", protocol).add("port", port) - .add("algorithm", algorithm).add("status", status).add("virtualIPs", virtualIPs).add("nodeCount", getNodeCount()) - .add("nodes", nodes).add("sessionPersistenceType", sessionPersistenceType).add("created", created) - .add("updated", updated).add("clusterName", clusterName).add("connectionLoggingEnabled", connectionLoggingEnabled); - } - - @Override - public String toString() { - return string().toString(); + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); } @Override - public int hashCode() { - return Objects.hashCode(id, region); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - LoadBalancer that = LoadBalancer.class.cast(obj); - return Objects.equal(this.id, that.id) && Objects.equal(this.region, that.region); + public Builder toBuilder() { + return new Builder().from(this); } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerAttributes.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerAttributes.java index 0fc4a0b476..8d1d7fe2a1 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerAttributes.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerAttributes.java @@ -19,22 +19,24 @@ package org.jclouds.rackspace.cloudloadbalancers.domain; import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer; +import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer.Algorithm; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; /** + * Used to update Load Balancers. * * @author Adrian Cole - * @see */ public class LoadBalancerAttributes { + protected String name; protected String protocol; protected Integer port; - protected String algorithm; + protected Algorithm algorithm; + protected Integer timeout; + protected Boolean halfClosed; public LoadBalancerAttributes name(String name) { this.name = name; @@ -46,43 +48,31 @@ public class LoadBalancerAttributes { return this; } - public LoadBalancerAttributes port(int port) { + public LoadBalancerAttributes port(Integer port) { this.port = port; return this; } - public LoadBalancerAttributes algorithm(String algorithm) { + public LoadBalancerAttributes algorithm(Algorithm algorithm) { this.algorithm = algorithm; return this; } - public static > LoadBalancerAttributes fromLoadBalancer(T lb) { - return Builder.name(lb.getName()).port(lb.getPort()).protocol(lb.getProtocol()).algorithm(lb.getAlgorithm()); + public LoadBalancerAttributes timeout(Integer timeout) { + this.timeout = timeout; + return this; } - public static class Builder { - public static LoadBalancerAttributes name(String name) { - return new LoadBalancerAttributes().name(name); - } - - public static LoadBalancerAttributes protocol(String protocol) { - return new LoadBalancerAttributes().protocol(protocol); - } - - public static LoadBalancerAttributes port(int port) { - return new LoadBalancerAttributes().port(port); - } - - public static LoadBalancerAttributes algorithm(String algorithm) { - return new LoadBalancerAttributes().algorithm(algorithm); - } + public LoadBalancerAttributes halfClosed(Boolean halfClosed) { + this.halfClosed = halfClosed; + return this; } protected ToStringHelper string() { - return Objects.toStringHelper(this).omitNullValues() - .add("name", name).add("algorithm", algorithm).add("port", port).add("protocol", protocol); + return Objects.toStringHelper(this).omitNullValues().add("name", name).add("algorithm", algorithm) + .add("port", port).add("protocol", protocol).add("timeout", timeout).add("halfClosed", halfClosed); } - + @Override public String toString() { return string().toString(); @@ -90,18 +80,68 @@ public class LoadBalancerAttributes { @Override public int hashCode() { - return Objects.hashCode(name, algorithm, port, protocol); + return Objects.hashCode(name, algorithm, port, protocol, timeout, halfClosed); } @Override public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; LoadBalancerAttributes that = LoadBalancerAttributes.class.cast(obj); - return Objects.equal(this.name, that.name) - && Objects.equal(this.algorithm, that.algorithm) - && Objects.equal(this.port, that.port) - && Objects.equal(this.protocol, that.protocol); + return Objects.equal(this.name, that.name) && Objects.equal(this.algorithm, that.algorithm) + && Objects.equal(this.port, that.port) && Objects.equal(this.protocol, that.protocol) + && Objects.equal(this.timeout, that.timeout) && Objects.equal(this.halfClosed, that.halfClosed); + } + + public static class Builder { + /** + * @see BaseLoadBalancer.Builder#name(String) + */ + public static LoadBalancerAttributes name(String name) { + return new LoadBalancerAttributes().name(name); + } + + /** + * @see BaseLoadBalancer.Builder#protocol(String) + */ + public static LoadBalancerAttributes protocol(String protocol) { + return new LoadBalancerAttributes().protocol(protocol); + } + + /** + * @see BaseLoadBalancer.Builder#port(Integer) + */ + public static LoadBalancerAttributes port(Integer port) { + return new LoadBalancerAttributes().port(port); + } + + /** + * @see BaseLoadBalancer.Builder#algorithm(Algorithm) + */ + public static LoadBalancerAttributes algorithm(Algorithm algorithm) { + return new LoadBalancerAttributes().algorithm(algorithm); + } + + /** + * @see BaseLoadBalancer.Builder#timeout(Integer) + */ + public static LoadBalancerAttributes timeout(Integer timeout) { + return new LoadBalancerAttributes().timeout(timeout); + } + + /** + * @see BaseLoadBalancer.Builder#halfClosed(Boolean) + */ + public static LoadBalancerAttributes halfClosed(Boolean halfClosed) { + return new LoadBalancerAttributes().halfClosed(halfClosed); + } + } + + public static > LoadBalancerAttributes fromLoadBalancer(T lb) { + return Builder.name(lb.getName()).port(lb.getPort()).protocol(lb.getProtocol()).algorithm(lb.getAlgorithm()) + .timeout(lb.getTimeout()).halfClosed(lb.isHalfClosed()); } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerRequest.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerRequest.java index abaa7aaba1..f21fe5c8cd 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerRequest.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/LoadBalancerRequest.java @@ -21,43 +21,77 @@ package org.jclouds.rackspace.cloudloadbalancers.domain; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import java.util.List; import java.util.Map; +import java.util.Set; +import org.jclouds.javax.annotation.Nullable; import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; /** + * Used to create Load Balancers. * * @author Adrian Cole - * @see */ public class LoadBalancerRequest extends BaseLoadBalancer { - @SuppressWarnings("unchecked") - public static Builder builder() { - return new Builder(); + private final Set> virtualIps; + + public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set nodes, + @Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed, + @Nullable Map sessionPersistenceType, + @Nullable Map connectionLogging, @Nullable ConnectionThrottle connectionThrottle, + @Nullable HealthMonitor healthMonitor, @Nullable Set accessRules, + @Nullable Set metadata, VirtualIP.Type virtualIPType, Integer virtualIPId) { + this(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging, + connectionThrottle, healthMonitor, accessRules, metadata, getVirtualIPsFromOptions(virtualIPType, + virtualIPId)); + } + + public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set nodes, + @Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed, + @Nullable Map sessionPersistenceType, + @Nullable Map connectionLogging, @Nullable ConnectionThrottle connectionThrottle, + @Nullable HealthMonitor healthMonitor, @Nullable Set accessRules, + @Nullable Set metadata, Set> virtualIPsFromOptions) { + super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging, + connectionThrottle, healthMonitor, accessRules, metadata); + this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions"); + } + + static Set> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) { + checkArgument(virtualIPType == null || virtualIPId == null, + "virtualIPType and virtualIPId cannot both be specified"); + if (virtualIPType != null) + return ImmutableSet.> of(ImmutableMap.of("type", virtualIPType.name())); + else if (virtualIPId != null) + return ImmutableSet.> of(ImmutableMap.of("id", virtualIPId.toString())); + else + throw new IllegalArgumentException("virtualIPType or virtualIPId must be specified"); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues().add("name", name).add("protocol", protocol) + .add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm) + .add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType()) + .add("connectionLogging", isConnectionLogging()).add("connectionThrottle", connectionThrottle) + .add("healthMonitor", healthMonitor).add("accessRules", accessList).add("metadata", metadata) + .add("virtualIps", virtualIps); } - /** - * {@inheritDoc} - */ @Override - public Builder toBuilder() { - return new Builder().from(this); + public String toString() { + return string().toString(); } public static class Builder extends BaseLoadBalancer.Builder { private VirtualIP.Type virtualIPType; private Integer virtualIPId; - private List> virtualIps; + private Set> virtualIps; public Builder virtualIPId(Integer virtualIPId) { this.virtualIPId = virtualIPId; @@ -69,49 +103,77 @@ public class LoadBalancerRequest extends BaseLoadBalancer> virtualIPs) { + this.virtualIps = virtualIPs; + return this; } + public LoadBalancerRequest build() { + if (virtualIps == null) { + return new LoadBalancerRequest(name, protocol, port, nodes, algorithm, timeout, halfClosed, + sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, accessRules, metadata, + virtualIPType, virtualIPId); + } + else { + return new LoadBalancerRequest(name, protocol, port, nodes, algorithm, timeout, halfClosed, + sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, accessRules, metadata, + virtualIps); + } + } + + /** + * {@inheritDoc} + */ @Override public Builder nodes(Iterable nodes) { this.nodes = ImmutableSet. copyOf(checkNotNull(nodes, "nodes")); return this; } + /** + * {@inheritDoc} + */ @Override public Builder node(NodeRequest nodes) { this.nodes.add(checkNotNull(nodes, "nodes")); return this; } - private Builder virtualIPs(List> virtualIPs) { - this.virtualIps = virtualIPs; - return this; - } - + /** + * {@inheritDoc} + */ @Override - public Builder algorithm(String algorithm) { + public Builder algorithm(Algorithm algorithm) { return Builder.class.cast(super.algorithm(algorithm)); } + /** + * {@inheritDoc} + */ @Override public Builder from(LoadBalancerRequest in) { return Builder.class.cast(super.from(in)).virtualIPs(in.virtualIps); } + /** + * {@inheritDoc} + */ @Override public Builder name(String name) { return Builder.class.cast(super.name(name)); } + /** + * {@inheritDoc} + */ @Override public Builder port(Integer port) { return Builder.class.cast(super.port(port)); } + /** + * {@inheritDoc} + */ @Override public Builder protocol(String protocol) { return Builder.class.cast(super.protocol(protocol)); @@ -119,38 +181,13 @@ public class LoadBalancerRequest extends BaseLoadBalancer> virtualIps; - - public LoadBalancerRequest(String name, String protocol, int port, String algorithm, Iterable nodes, - VirtualIP.Type virtualIPType, Integer virtualIPId) { - this(name, protocol, port, algorithm, nodes, getVirtualIPsFromOptions(virtualIPType, virtualIPId)); + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); } - private LoadBalancerRequest(String name, String protocol, int port, String algorithm, Iterable nodes, - List> virtualIPsFromOptions) { - super(name, protocol, port, algorithm, nodes); - this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions"); - } - - static List> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) { - checkArgument(virtualIPType == null || virtualIPId == null, - "virtualIPType and virtualIPId cannot both be specified"); - if (virtualIPType != null) - return ImmutableList.> of(ImmutableMap.of("type", virtualIPType.name())); - else if (virtualIPId != null) - return ImmutableList.> of(ImmutableMap.of("id", virtualIPId.toString())); - else - throw new IllegalArgumentException("virtualIPType or virtualIPId must be specified"); - } - - protected ToStringHelper string() { - return Objects.toStringHelper(this).omitNullValues() - .add("name", name).add("algorithm", algorithm).add("nodes", nodes).add("port", port) - .add("protocol", protocol).add("virtualIps", virtualIps); - } - @Override - public String toString() { - return string().toString(); + public Builder toBuilder() { + return new Builder().from(this); } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Metadata.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Metadata.java new file mode 100644 index 0000000000..bc4540567a --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Metadata.java @@ -0,0 +1,111 @@ +/** + * 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.rackspace.cloudloadbalancers.domain; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + + +/** + * @author Everett Toews + */ +public class Metadata { + private int id; + private String key; + private String value; + + private Metadata(Integer id, String key, String value) { + this.id = id; + this.key = key; + this.value = value; + } + + public int getId() { + return id; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Metadata that = Metadata.class.cast(obj); + + return Objects.equal(this.id, that.id); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues() + .add("id", id).add("key", key).add("value", value); + } + + @Override + public String toString() { + return string().toString(); + } + + public static class Builder { + private Integer id; + private String key; + private String value; + + public Builder id(Integer id) { + this.id = id; + return this; + } + + public Builder key(String key) { + this.key = key; + return this; + } + + public Builder value(String value) { + this.value = value; + return this; + } + + public Metadata build() { + return new Metadata(id, key, value); + } + + public Builder from(Metadata in) { + return id(in.getId()).key(in.getKey()).value(in.getValue()); + } + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().from(this); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Node.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Node.java index 794d08a8c5..bf0be57b19 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Node.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/Node.java @@ -51,73 +51,58 @@ import com.google.common.base.Objects.ToStringHelper; * nodes. * * @author Adrian Cole - * @see */ public class Node extends BaseNode { - @SuppressWarnings("unchecked") - public static Builder builder() { - return new Builder(); + private int id; + private Status status; + + // for serialization only + Node() { } - /** - * {@inheritDoc} - */ + public Node(int id, String address, int port, Condition condition, Type type, Status status, Integer weight) { + super(address, port, condition, type, weight); + checkArgument(id != -1, "id must be specified"); + this.id = id; + this.status = checkNotNull(status, "status"); + } + + public int getId() { + return id; + } + + public Status getStatus() { + return status; + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues() + .add("id", id).add("address", address).add("port", port).add("condition", condition) + .add("type", type).add("weight", weight).add("status", status); + } + @Override - public Builder toBuilder() { - return new Builder().from(this); + public String toString() { + return string().toString(); } - public static class Builder extends BaseNode.Builder { - private int id = -1; - private Status status; + @Override + public int hashCode() { + return Objects.hashCode(id); + } - public Builder id(int id) { - this.id = id; - return this; - } - - public Builder status(Status status) { - this.status = status; - return this; - } - - @Override - public Node build() { - return new Node(id, address, port, condition, status, weight); - } - - @Override - public Builder address(String address) { - return Builder.class.cast(super.address(address)); - } - - @Override - public Builder condition(Condition condition) { - return Builder.class.cast(super.condition(condition)); - } - - @Override - public Builder from(Node in) { - return Builder.class.cast(super.from(in)).id(in.getId()).status(in.getStatus()); - } - - @Override - public Builder port(int port) { - return Builder.class.cast(super.port(port)); - } - - @Override - public Builder weight(Integer weight) { - return Builder.class.cast(super.weight(weight)); - } + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Node that = Node.class.cast(obj); + return Objects.equal(this.id, that.id); } /** * The status is determined by the passive or active health monitors. - * */ public static enum Status { /** @@ -146,54 +131,82 @@ public class Node extends BaseNode { return UNRECOGNIZED; } } - } - private int id; - private Status status; + public static class Builder extends BaseNode.Builder { + private int id = -1; + private Status status; - // for serialization only - Node() { + public Builder id(int id) { + this.id = id; + return this; + } + /** + * @see Status + */ + public Builder status(Status status) { + this.status = status; + return this; + } + + @Override + public Node build() { + return new Node(id, address, port, condition, type, status, weight); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder address(String address) { + return Builder.class.cast(super.address(address)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder condition(Condition condition) { + return Builder.class.cast(super.condition(condition)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder type(Type type) { + return Builder.class.cast(super.type(type)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder port(int port) { + return Builder.class.cast(super.port(port)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder weight(Integer weight) { + return Builder.class.cast(super.weight(weight)); + } + @Override + public Builder from(Node in) { + return Builder.class.cast(super.from(in)).id(in.getId()).status(in.getStatus()); + } } - public Node(int id, String address, int port, Condition condition, Status status, Integer weight) { - super(address, port, condition, weight); - checkArgument(id != -1, "id must be specified"); - this.id = id; - this.status = checkNotNull(status, "status"); - } - - public int getId() { - return id; - } - - public Status getStatus() { - return status; - } - - protected ToStringHelper string() { - return Objects.toStringHelper(this).omitNullValues() - .add("address", address).add("port", port).add("condition", condition) - .add("weight", weight).add("status", status); - } - - @Override - public String toString() { - return string().toString(); + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); } @Override - public int hashCode() { - return Objects.hashCode(id); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - Node that = Node.class.cast(obj); - return Objects.equal(this.id, that.id); + public Builder toBuilder() { + return new Builder().from(this); } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeAttributes.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeAttributes.java index 1422307f14..33119f96ae 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeAttributes.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeAttributes.java @@ -20,48 +20,40 @@ package org.jclouds.rackspace.cloudloadbalancers.domain; import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseNode; import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseNode.Condition; +import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseNode.Type; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; /** + * Used to update Nodes. * * @author Dan Lo Bianco - * @see */ public class NodeAttributes { - protected String condition; + + protected Condition condition; + protected Type type; protected Integer weight; - public NodeAttributes condition(String condition) { + public NodeAttributes condition(Condition condition) { this.condition = condition; return this; } - public NodeAttributes weight(int weight) { + public NodeAttributes type(Type type) { + this.type = type; + return this; + } + + public NodeAttributes weight(Integer weight) { this.weight = weight; return this; } - public static > NodeAttributes fromNode(T n) { - return Builder.condition(n.getCondition()).weight(n.getWeight()); - } - - public static class Builder { - public static NodeAttributes condition(Condition condition) { - return new NodeAttributes().condition(condition.name()); - } - - public static NodeAttributes weight(int weight) { - return new NodeAttributes().weight(weight); - } - } - protected ToStringHelper string() { return Objects.toStringHelper(this).omitNullValues() - .add("condition", condition).add("weight", weight); + .add("condition", condition).add("type", type).add("weight", weight); } @Override @@ -71,7 +63,7 @@ public class NodeAttributes { @Override public int hashCode() { - return Objects.hashCode(condition, weight); + return Objects.hashCode(condition, type, weight); } @Override @@ -81,6 +73,34 @@ public class NodeAttributes { NodeAttributes that = NodeAttributes.class.cast(obj); return Objects.equal(this.condition, that.condition) + && Objects.equal(this.type, that.type) && Objects.equal(this.weight, that.weight); } + + public static class Builder { + /** + * @see BaseNode.Builder#condition(Condition) + */ + public static NodeAttributes condition(Condition condition) { + return new NodeAttributes().condition(condition); + } + + /** + * @see BaseNode.Builder#type(Type) + */ + public static NodeAttributes type(Type type) { + return new NodeAttributes().type(type); + } + + /** + * @see BaseNode.Builder#weight(Integer) + */ + public static NodeAttributes weight(Integer weight) { + return new NodeAttributes().weight(weight); + } + } + + public static > NodeAttributes fromNode(T n) { + return Builder.condition(n.getCondition()).type(n.getType()).weight(n.getWeight()); + } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeRequest.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeRequest.java index 84a43bb3a6..628665da1d 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeRequest.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/NodeRequest.java @@ -48,70 +48,20 @@ import com.google.common.base.Objects.ToStringHelper; * nodes. * * @author Adrian Cole - * @see */ public class NodeRequest extends BaseNode { - @SuppressWarnings("unchecked") - public static Builder builder() { - return new Builder(); - } - - /** - * {@inheritDoc} - */ - @Override - public Builder toBuilder() { - return new Builder().from(this); - } - - public static class Builder extends BaseNode.Builder { - - @Override - public NodeRequest build() { - return new NodeRequest(address, port, condition, weight); - } - - @Override - public Builder address(String address) { - return Builder.class.cast(super.address(address)); - } - - @Override - public Builder condition(Condition condition) { - return Builder.class.cast(super.condition(condition)); - } - - @Override - public Builder from(NodeRequest in) { - return Builder.class.cast(super.from(in)); - } - - @Override - public Builder port(int port) { - return Builder.class.cast(super.port(port)); - } - - @Override - public Builder weight(Integer weight) { - return Builder.class.cast(super.weight(weight)); - } - - } - // for serialization only NodeRequest() { - } - public NodeRequest(String address, int port, Condition condition, Integer weight) { - super(address, port, condition, weight); + public NodeRequest(String address, int port, Condition condition, Type type, Integer weight) { + super(address, port, condition, type, weight); } protected ToStringHelper string() { return Objects.toStringHelper(this).omitNullValues() - .add("address", address).add("port", port).add("condition", condition).add("weight", weight); + .add("address", address).add("port", port).add("condition", condition).add("type", type).add("weight", weight); } @Override @@ -133,4 +83,69 @@ public class NodeRequest extends BaseNode { return Objects.equal(this.address, that.address) && Objects.equal(this.port, that.port); } + + public static class Builder extends BaseNode.Builder { + + @Override + public NodeRequest build() { + return new NodeRequest(address, port, condition, type, weight); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder address(String address) { + return Builder.class.cast(super.address(address)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder condition(Condition condition) { + return Builder.class.cast(super.condition(condition)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder type(Type type) { + return Builder.class.cast(super.type(type)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder port(int port) { + return Builder.class.cast(super.port(port)); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder weight(Integer weight) { + return Builder.class.cast(super.weight(weight)); + } + @Override + public Builder from(NodeRequest in) { + return Builder.class.cast(super.from(in)); + } + } + + @SuppressWarnings("unchecked") + public static Builder builder() { + return new Builder(); + } + + /** + * {@inheritDoc} + */ + @Override + public Builder toBuilder() { + return new Builder().from(this); + } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SSLTermination.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SSLTermination.java new file mode 100644 index 0000000000..993ef2676c --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SSLTermination.java @@ -0,0 +1,152 @@ +/** + * 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.rackspace.cloudloadbalancers.domain; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * The SSL Termination feature allows a load balancer user to terminate SSL traffic at the load balancer layer versus + * at the web server layer. A user may choose to configure SSL Termination using a key and an SSL certificate or an + * (Intermediate) SSL certificate. + *

+ * When SSL Termination is configured on a load balancer, a secure shadow server is created that listens only for + * secure traffic on a user-specified port. This shadow server is only visible to and manageable by the system. + * Existing or updated attributes on a load balancer with SSL Termination will also apply to its shadow server. + * For example, if Connection Logging is enabled on an SSL load balancer, it will also be enabled on the shadow server + * and Cloud Files logs will contain log files for both. + *

+ * Notes + *

    + *
  1. SSL Termination may only be configured on load balancers with non-secure protocols. For example, SSL Termination + * can be applied to an HTTP load balancer, but not to an HTTPS load balancer.
  2. + *
  3. SSL-terminated load balancers decrypt the traffic at the traffic manager and pass unencrypted traffic to the + * back-end node. Because of this, the customer's back-end nodes don't know what protocol the client requested. + * Therefore the X-Forwarded-Proto (XFP) header has been added for identifying the originating protocol of an HTTP + * request as "http" or "https" depending on what protocol the client requested.
  4. + *
  5. Not every service will return certificates in the proper order. Please verify that your chain of certificates + * matches that of walking up the chain from the domain to the CA root.
  6. + *
+ * + * Warning + *
    + *
  1. If SSL is enabled on a load balancer that is configured with nodes that are NOT in the same datacenter, then + * decrypted traffic will be sent in clear text over the public internet to the external node(s) and will no longer + * be secure.
  2. + *
+ * @author Everett Toews + */ +public class SSLTermination { + + private final boolean enabled; + private final boolean secureTrafficOnly; + private final int securePort; + + protected SSLTermination(boolean enabled, boolean secureTrafficOnly, int securePort) { + this.enabled = enabled; + this.secureTrafficOnly = secureTrafficOnly; + this.securePort = securePort; + } + + public boolean getEnabled() { + return this.enabled; + } + + public boolean getSecureTrafficOnly() { + return this.secureTrafficOnly; + } + + public int getSecurePort() { + return this.securePort; + } + + @Override + public int hashCode() { + return Objects.hashCode(enabled, secureTrafficOnly, securePort); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + SSLTermination that = SSLTermination.class.cast(obj); + + return Objects.equal(this.enabled, that.enabled) && Objects.equal(this.secureTrafficOnly, that.secureTrafficOnly) + && Objects.equal(this.securePort, that.securePort); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).add("enabled", enabled).add("secureTrafficOnly", secureTrafficOnly) + .add("securePort", securePort); + } + + @Override + public String toString() { + return string().toString(); + } + + public static class Builder { + private boolean enabled; + private boolean secureTrafficOnly; + private int securePort; + + /** + * @see SSLTermination#getEnabled() + */ + public Builder enabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * @see SSLTermination#getSecureTrafficOnly() + */ + public Builder secureTrafficOnly(boolean secureTrafficOnly) { + this.secureTrafficOnly = secureTrafficOnly; + return this; + } + + /** + * @see SSLTermination#getSecurePort() + */ + public Builder securePort(int securePort) { + this.securePort = securePort; + return this; + } + + public SSLTermination build() { + return new SSLTermination(enabled, secureTrafficOnly, securePort); + } + + public Builder from(SSLTermination in) { + return this.enabled(in.getEnabled()).secureTrafficOnly(in.getSecureTrafficOnly()) + .securePort(in.getSecurePort()); + } + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().from(this); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SourceAddresses.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SourceAddresses.java new file mode 100644 index 0000000000..be499796d2 --- /dev/null +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/SourceAddresses.java @@ -0,0 +1,127 @@ +/* + * 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.rackspace.cloudloadbalancers.domain; + +import com.google.common.base.Objects; +import com.google.common.base.Objects.ToStringHelper; + +/** + * The load balancer source IP addresses are useful for customers who are automating the deployment of infrastructure + * and need to determine the IP addresses of requests coming from our load balancers for the purpose of creating more + * robust firewall rules. + * + * @author Everett Toews + */ +public class SourceAddresses { + + private final String ipv6Public; + private final String ipv4Public; + private final String ipv4Servicenet; + + protected SourceAddresses(String ipv6Public, String ipv4Public, String ipv4Servicenet) { + this.ipv6Public = ipv6Public; + this.ipv4Public = ipv4Public; + this.ipv4Servicenet = ipv4Servicenet; + } + + public String getIPV6Public() { + return this.ipv6Public; + } + + public String getIPV4Public() { + return this.ipv4Public; + } + + public String getIPV4Servicenet() { + return this.ipv4Servicenet; + } + + @Override + public int hashCode() { + return Objects.hashCode(ipv6Public, ipv4Public, ipv4Servicenet); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + SourceAddresses that = SourceAddresses.class.cast(obj); + return Objects.equal(this.ipv6Public, that.ipv6Public) && Objects.equal(this.ipv4Public, that.ipv4Public) + && Objects.equal(this.ipv4Servicenet, that.ipv4Servicenet); + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).add("ipv6Public", ipv6Public).add("ipv4Public", ipv4Public) + .add("ipv4Servicenet", ipv4Servicenet); + } + + @Override + public String toString() { + return string().toString(); + } + + public static class Builder { + private String ipv6Public; + private String ipv4Public; + private String ipv4Servicenet; + + /** + * @see SourceAddresses#getIPV6Public() + */ + public Builder ipv6Public(String ipv6Public) { + this.ipv6Public = ipv6Public; + return this; + } + + /** + * @see SourceAddresses#getIPV4Public() + */ + public Builder ipv4Public(String ipv4Public) { + this.ipv4Public = ipv4Public; + return this; + } + + /** + * @see SourceAddresses#getIPV4Servicenet() + */ + public Builder ipv4Servicenet(String ipv4Servicenet) { + this.ipv4Servicenet = ipv4Servicenet; + return this; + } + + public SourceAddresses build() { + return new SourceAddresses(ipv6Public, ipv4Public, ipv4Servicenet); + } + + public Builder from(SourceAddresses in) { + return this.ipv6Public(in.getIPV6Public()).ipv4Public(in.getIPV4Public()) + .ipv4Servicenet(in.getIPV4Servicenet()); + } + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().from(this); + } +} diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/VirtualIP.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/VirtualIP.java index ec26b3684a..7357417a80 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/VirtualIP.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/VirtualIP.java @@ -30,96 +30,18 @@ import com.google.common.base.Objects.ToStringHelper; * only within the region in which the load balancer resides. * * @author Adrian Cole - * @see
*/ public class VirtualIP implements Comparable { - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - private int id = -1; - private String address; - private Type type; - private IPVersion ipVersion = IPVersion.IPV4; - - public Builder id(int id) { - this.id = id; - return this; - } - - public Builder address(String address) { - this.address = address; - return this; - } - - public Builder type(Type type) { - this.type = type; - return this; - } - - public Builder ipVersion(IPVersion ipVersion) { - this.ipVersion = ipVersion; - return this; - } - - public VirtualIP build() { - return new VirtualIP(id, address, type, ipVersion); - } - } - - /** - * Virtual IP Types - */ - public static enum Type { - /** - * An address that is routable on the public Internet. - */ - PUBLIC, - /** - * An address that is routable only on ServiceNet. - */ - SERVICENET, UNRECOGNIZED; - - public static Type fromValue(String type) { - try { - return valueOf(checkNotNull(type, "type")); - } catch (IllegalArgumentException e) { - return UNRECOGNIZED; - } - } - - } - - /** - * Virtual IP Versions - */ - public static enum IPVersion { - - IPV4, IPV6, UNRECOGNIZED; - - public static IPVersion fromValue(String ipVersion) { - try { - return valueOf(checkNotNull(ipVersion, "ipVersion")); - } catch (IllegalArgumentException e) { - return UNRECOGNIZED; - } - } - - } - - // for serialization only - VirtualIP() { - - } private int id; private String address; private Type type; private IPVersion ipVersion; + // for serialization only + VirtualIP() { + } + public VirtualIP(int id, String address, Type type, IPVersion ipVersion) { checkArgument(id != -1, "id must be specified"); this.id = id; @@ -172,4 +94,79 @@ public class VirtualIP implements Comparable { VirtualIP that = VirtualIP.class.cast(obj); return Objects.equal(this.id, that.id); } + + /** + * Virtual IP Types + */ + public static enum Type { + /** + * An address that is routable on the public Internet. + */ + PUBLIC, + /** + * An address that is routable only on ServiceNet. + */ + SERVICENET, UNRECOGNIZED; + + public static Type fromValue(String type) { + try { + return valueOf(checkNotNull(type, "type")); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + + } + + /** + * Virtual IP Versions + */ + public static enum IPVersion { + + IPV4, IPV6, UNRECOGNIZED; + + public static IPVersion fromValue(String ipVersion) { + try { + return valueOf(checkNotNull(ipVersion, "ipVersion")); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + + } + + public static class Builder { + private int id = -1; + private String address; + private Type type; + private IPVersion ipVersion = IPVersion.IPV4; + + public Builder id(int id) { + this.id = id; + return this; + } + + public Builder address(String address) { + this.address = address; + return this; + } + + public Builder type(Type type) { + this.type = type; + return this; + } + + public Builder ipVersion(IPVersion ipVersion) { + this.ipVersion = ipVersion; + return this; + } + + public VirtualIP build() { + return new VirtualIP(id, address, type, ipVersion); + } + } + + public static Builder builder() { + return new Builder(); + } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseLoadBalancer.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseLoadBalancer.java index 1f8d3121d8..05cdb30dd7 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseLoadBalancer.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseLoadBalancer.java @@ -20,104 +20,74 @@ package org.jclouds.rackspace.cloudloadbalancers.domain.internal; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Map; import java.util.Set; import java.util.SortedSet; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.rackspace.cloudloadbalancers.domain.AccessRule; +import org.jclouds.rackspace.cloudloadbalancers.domain.ConnectionThrottle; +import org.jclouds.rackspace.cloudloadbalancers.domain.HealthMonitor; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer; +import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata; +import org.jclouds.rackspace.cloudloadbalancers.features.LoadBalancerApi; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; /** * * @author Adrian Cole - * @see */ public class BaseLoadBalancer, T extends BaseLoadBalancer> implements - Comparable> { + Comparable> { - public static , T extends BaseLoadBalancer> Builder builder() { - return new Builder(); - } - - @SuppressWarnings("unchecked") - public Builder toBuilder() { - return new Builder().from((T) this); - } - - public static class Builder, T extends BaseLoadBalancer> { - protected String name; - protected String protocol; - protected Integer port; - protected String algorithm; - protected Set nodes = Sets.newLinkedHashSet(); - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder protocol(String protocol) { - this.protocol = protocol; - return this; - } - - public Builder port(Integer port) { - this.port = port; - return this; - } - - public Builder algorithm(String algorithm) { - this.algorithm = algorithm; - return this; - } - - public Builder nodes(Iterable nodes) { - this.nodes = ImmutableSet. copyOf(checkNotNull(nodes, "nodes")); - return this; - } - - @SuppressWarnings("unchecked") - public Builder node(N node) { - this.nodes.add((N) checkNotNull(nodes, "nodes")); - return this; - } - - public BaseLoadBalancer build() { - return new BaseLoadBalancer(name, protocol, port, algorithm, nodes); - } - - public Builder from(T baseLoadBalancer) { - return name(baseLoadBalancer.getName()).port(baseLoadBalancer.getPort()).protocol( - baseLoadBalancer.getProtocol()).algorithm(baseLoadBalancer.getAlgorithm()).nodes( - baseLoadBalancer.getNodes()); - } - } - - // for serialization only - protected BaseLoadBalancer() { - - } + private static final String ENABLED = "enabled"; + private static final String PERSISTENCE_TYPE = "persistenceType"; + public static Algorithm[] WEIGHTED_ALGORITHMS = { Algorithm.WEIGHTED_LEAST_CONNECTIONS, + Algorithm.WEIGHTED_ROUND_ROBIN }; protected String name; protected String protocol; protected Integer port; - protected String algorithm; - // so tests will come out consistently - protected SortedSet nodes = ImmutableSortedSet.of(); + protected SortedSet nodes = ImmutableSortedSet.of(); // so tests will come out consistently + protected Algorithm algorithm; + protected Integer timeout; + protected Boolean halfClosed; + protected Map sessionPersistence; + protected Map connectionLogging; + protected ConnectionThrottle connectionThrottle; + protected HealthMonitor healthMonitor; + protected Set accessList; + protected Set metadata; - public BaseLoadBalancer(String name, String protocol, Integer port, @Nullable String algorithm, Iterable nodes) { + // for serialization only + protected BaseLoadBalancer() { + } + + public BaseLoadBalancer(String name, @Nullable String protocol, @Nullable Integer port, Iterable nodes, + @Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed, + @Nullable Map sessionPersistence, + @Nullable Map connectionLogging, @Nullable ConnectionThrottle connectionThrottle, + @Nullable HealthMonitor healthMonitor, @Nullable Set accessRules, + @Nullable Set metadata) { this.name = checkNotNull(name, "name"); this.protocol = protocol;// null on deleted LB this.port = port;// null on deleted LB - this.algorithm = algorithm;// null on deleted LB this.nodes = ImmutableSortedSet.copyOf(checkNotNull(nodes, "nodes")); + this.algorithm = algorithm;// null on deleted LB + this.timeout = timeout; + this.halfClosed = halfClosed; + this.sessionPersistence = sessionPersistence; + this.connectionLogging = connectionLogging; + this.connectionThrottle = connectionThrottle; + this.healthMonitor = healthMonitor; + this.accessList = accessRules; + this.metadata = metadata; } @Override @@ -129,33 +99,102 @@ public class BaseLoadBalancer, T extends BaseLoadBalancer< return name; } + /** + * @return protocol, which may be null if the load balancer is deleted. + */ + @Nullable public String getProtocol() { return protocol; } - public Integer getPort() { - return port; - } - /** - * - * @return algorithm, which may be null if the load balancer is deleted + * @return port, which may be null if port has not been set. */ @Nullable - public String getAlgorithm() { - return algorithm; + public Integer getPort() { + return port; } public Set getNodes() { return nodes; } - protected ToStringHelper string() { - return Objects.toStringHelper(this).omitNullValues() - .add("name", name).add("protocol", protocol).add("port", port) - .add("algorithm", algorithm).add("nodes", nodes); + /** + * @return algorithm, which may be null if the load balancer is deleted. + */ + @Nullable + public Algorithm getAlgorithm() { + return algorithm; } - + + /** + * @return timeout, which may be null if no timeout has been set. + */ + @Nullable + public Integer getTimeout() { + return timeout; + } + + /** + * @return halfClosed, which may be null if halfClosed has not been set. + */ + @Nullable + public Boolean isHalfClosed() { + return halfClosed; + } + + /** + * @return sessionPersistenceType, which may be null if sessionPersistenceType has not been set. + */ + @Nullable + public SessionPersistenceType getSessionPersistenceType() { + return sessionPersistence == null ? null : sessionPersistence.get(PERSISTENCE_TYPE); + } + + public boolean isConnectionLogging() { + return connectionLogging == null ? false : connectionLogging.get(ENABLED); + } + + /** + * @return connectionThrottle, which may be null if connectionThrottle has not been set. + */ + @Nullable + public ConnectionThrottle getConnectionThrottle() { + return connectionThrottle; + } + + /** + * @return healthMonitor, which may be null if healthMonitor has not been set. + */ + @Nullable + public HealthMonitor getHealthMonitor() { + return healthMonitor; + } + + /** + * @return accessRules, which may be null if accessRules has not been set. + */ + @Nullable + public Set getAccessRules() { + return accessList; + } + + /** + * @return metadata, which may be null if metadata has not been set. + */ + @Nullable + public Set getMetadata() { + return metadata; + } + + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues().add("name", name).add("protocol", protocol) + .add("port", port).add("nodes", nodes).add("timeout", timeout).add("algorithm", algorithm) + .add("timeout", timeout).add("sessionPersistenceType", getSessionPersistenceType()) + .add("connectionLogging", connectionLogging).add("connectionThrottle", connectionThrottle) + .add("healthMonitor", healthMonitor).add("accessRules", accessList).add("metadata", metadata); + } + @Override public String toString() { return string().toString(); @@ -168,10 +207,266 @@ public class BaseLoadBalancer, T extends BaseLoadBalancer< @Override public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; LoadBalancer that = LoadBalancer.class.cast(obj); return Objects.equal(this.name, that.name); } + + /** + * All load balancers utilize an algorithm that defines how traffic should be directed between + * back-end nodes. The default algorithm for newly created load balancers is RANDOM, which can be + * overridden at creation time or changed after the load balancer has been initially provisioned. + * The algorithm name is to be constant within a major revision of the load balancing API, though + * new algorithms may be created with a unique algorithm name within a given major revision of + * the service API. + */ + public static enum Algorithm { + /** + * The node with the lowest number of connections will receive requests. + */ + LEAST_CONNECTIONS, + /** + * Back-end servers are selected at random. + */ + RANDOM, + /** + * Connections are routed to each of the back-end servers in turn. + */ + ROUND_ROBIN, + /** + * Each request will be assigned to a node based on the number of concurrent connections to + * the node and its weight. + */ + WEIGHTED_LEAST_CONNECTIONS, + /** + * A round robin algorithm, but with different proportions of traffic being directed to the + * back-end nodes. Weights must be defined as part of the load balancer's node configuration. + */ + WEIGHTED_ROUND_ROBIN, UNRECOGNIZED; + + public static Algorithm fromValue(String algorithm) { + try { + return valueOf(checkNotNull(algorithm, "algorithm")); + } + catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + } + + /** + * Session persistence is a feature of the load balancing service that forces multiple requests from clients to be + * directed to the same node. This is common with many web applications that do not inherently share application + * state between back-end servers. + */ + public static enum SessionPersistenceType { + /** + * A session persistence mechanism that inserts an HTTP cookie and is used to determine the destination back-end + * node. This is supported for HTTP load balancing only. + */ + HTTP_COOKIE, + /** + * A session persistence mechanism that will keep track of the source IP address that is mapped and is able to + * determine the destination back-end node. This is supported for HTTPS pass-through and non-HTTP load balancing + * only. + */ + SOURCE_IP, + + UNRECOGNIZED; + + public static SessionPersistenceType fromValue(String sessionPersistenceType) { + try { + return valueOf(checkNotNull(sessionPersistenceType, "sessionPersistenceType")); + } + catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + } + + public static class Builder, T extends BaseLoadBalancer> { + protected String name; + protected String protocol; + protected Integer port; + protected Set nodes = Sets.newLinkedHashSet(); + protected Algorithm algorithm; + protected Integer timeout; + protected Boolean halfClosed; + protected Map sessionPersistence; + protected Map connectionLogging; + protected ConnectionThrottle connectionThrottle; + protected HealthMonitor healthMonitor; + protected Set accessRules; + protected Set metadata; + + /** + * Required. Name of the load balancer to create. The name must be 128 characters or less in length, and all + * UTF-8 characters are valid. + */ + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + /** + * Required. Protocol of the service which is being load balanced. + * + * @see LoadBalancerApi#listProtocols() + */ + public Builder protocol(String protocol) { + this.protocol = protocol; + return this; + } + + /** + * Required if the protocol being used is not in LoadBalancerApi#listProtocols() or the protocol is in + * LoadBalancerApi#listProtocols() but port=0. Port number for the service you are load balancing. + */ + public Builder port(@Nullable Integer port) { + this.port = port; + return this; + } + + /** + * Required. Nodes to be added to the load balancer. + */ + public Builder nodes(Iterable nodes) { + this.nodes = ImmutableSet. copyOf(checkNotNull(nodes, "nodes")); + return this; + } + + @SuppressWarnings("unchecked") + public Builder node(N node) { + this.nodes.add((N) checkNotNull(nodes, "nodes")); + return this; + } + + /** + * Algorithm that defines how traffic should be directed between back-end nodes. + * + * @see Algorithm + */ + public Builder algorithm(@Nullable Algorithm algorithm) { + this.algorithm = algorithm; + return this; + } + + /** + * The timeout value for the load balancer and communications with its nodes. Defaults to 30 seconds with + * a maximum of 120 seconds. + */ + public Builder timeout(@Nullable Integer timeout) { + this.timeout = timeout; + return this; + } + + /** + * Enable or Disable Half-Closed support for the load balancer. Half-Closed support provides the ability + * for one end of the connection to terminate its output, while still receiving data from the other end. + * Only available for TCP/TCP_CLIENT_FIRST protocols. + */ + public Builder halfClosed(@Nullable Boolean halfClosed) { + this.halfClosed = halfClosed; + return this; + } + + /** + * Specifies whether multiple requests from clients are directed to the same node. + * + * @see SessionPersistenceType + */ + public Builder sessionPersistenceType(@Nullable SessionPersistenceType sessionPersistenceType) { + if (sessionPersistenceType != null) { + this.sessionPersistence = Maps.newHashMap(); + this.sessionPersistence.put(PERSISTENCE_TYPE, sessionPersistenceType); + } + else { + this.sessionPersistence = null; + } + + return this; + } + + /** + * Current connection logging configuration. + */ + public Builder connectionLogging(@Nullable Boolean connectionLogging) { + if (connectionLogging != null) { + this.connectionLogging = Maps.newHashMap(); + this.connectionLogging.put(ENABLED, connectionLogging); + } + else { + this.connectionLogging = null; + } + + return this; + } + + /** + * Specifies limits on the number of connections per IP address to help mitigate malicious or abusive + * traffic to your applications. + * + * @see ConnectionThrottle + */ + public Builder connectionThrottle(@Nullable ConnectionThrottle connectionThrottle) { + this.connectionThrottle = connectionThrottle; + return this; + } + + /** + * The type of health monitor check to perform to ensure that the service is performing properly. + * + * @see HealthMonitor + */ + public Builder healthMonitor(@Nullable HealthMonitor healthMonitor) { + this.healthMonitor = healthMonitor; + return this; + } + + /** + * The access list management feature allows fine-grained network access controls to be applied to the load + * balancer's virtual IP address. + * + * @see AccessRule + */ + public Builder accessRules(@Nullable Set accessRules) { + this.accessRules = accessRules; + return this; + } + + /** + * Information (metadata) that can be associated with each load balancer for the client's personal use. + */ + public Builder metadata(@Nullable Set metadata) { + this.metadata = metadata; + return this; + } + + public BaseLoadBalancer build() { + return new BaseLoadBalancer(name, protocol, port, nodes, algorithm, timeout, halfClosed, + sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, accessRules, metadata); + } + + public Builder from(T baseLB) { + return name(baseLB.getName()).protocol(baseLB.getProtocol()).port(baseLB.getPort()) + .algorithm(baseLB.getAlgorithm()).timeout(baseLB.getTimeout()).halfClosed(baseLB.isHalfClosed()) + .nodes(baseLB.getNodes()).sessionPersistenceType(baseLB.getSessionPersistenceType()) + .connectionLogging(baseLB.isConnectionLogging()).connectionThrottle(baseLB.getConnectionThrottle()) + .healthMonitor(baseLB.getHealthMonitor()).accessRules(baseLB.getAccessRules()) + .metadata(baseLB.getMetadata()); + } + } + + public static , T extends BaseLoadBalancer> Builder builder() { + return new Builder(); + } + + @SuppressWarnings("unchecked") + public Builder toBuilder() { + return new Builder().from((T) this); + } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseNode.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseNode.java index 17ef110321..9596bbc921 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseNode.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/domain/internal/BaseNode.java @@ -21,6 +21,8 @@ package org.jclouds.rackspace.cloudloadbalancers.domain.internal; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer.Algorithm; + import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; @@ -49,53 +51,81 @@ import com.google.common.base.Objects.ToStringHelper; * nodes. * * @author Adrian Cole - * @see */ public class BaseNode> implements Comparable> { - public static > Builder builder() { - return new Builder(); + protected String address; + protected int port; + protected Condition condition; + protected Type type; + protected Integer weight; + + // for serialization only + protected BaseNode() { } - @SuppressWarnings("unchecked") - public Builder toBuilder() { - return new Builder().from((T) this); + public BaseNode(String address, int port, Condition condition, Type type, Integer weight) { + this.address = checkNotNull(address, "address"); + checkArgument(port != -1, "port must be specified"); + this.port = port; + this.condition = checkNotNull(condition, "condition"); + this.type = type; + this.weight = weight; } - public static class Builder> { - protected String address; - protected int port = -1; - protected Condition condition = Condition.ENABLED; - protected Integer weight; + public String getAddress() { + return address; + } - public Builder address(String address) { - this.address = address; - return this; - } + public int getPort() { + return port; + } - public Builder port(int port) { - this.port = port; - return this; - } + public Condition getCondition() { + return condition; + } - public Builder condition(Condition condition) { - this.condition = condition; - return this; - } + public Type getType() { + return type; + } - public Builder weight(Integer weight) { - this.weight = weight; - return this; - } + /** + * the maximum weight of a node is 100. + */ + public Integer getWeight() { + return weight; + } - public BaseNode build() { - return new BaseNode(address, port, condition, weight); - } + @Override + public int compareTo(BaseNode arg0) { + return address.compareTo(arg0.address); + } - public Builder from(T in) { - return address(in.getAddress()).port(in.getPort()).condition(in.getCondition()).weight(in.getWeight()); - } + protected ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues().add("address", address).add("port", port) + .add("condition", condition).add("type", type).add("weight", weight); + } + + @Override + public String toString() { + return string().toString(); + } + + @Override + public int hashCode() { + return Objects.hashCode(address, port, condition); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + + BaseNode that = BaseNode.class.cast(obj); + return Objects.equal(this.address, that.address) && Objects.equal(this.port, that.port) + && Objects.equal(this.condition, that.condition); } /** @@ -122,78 +152,112 @@ public class BaseNode> implements Comparable> public static Condition fromValue(String condition) { try { return valueOf(checkNotNull(condition, "condition")); - } catch (IllegalArgumentException e) { + } + catch (IllegalArgumentException e) { return UNRECOGNIZED; } } } - protected String address; - protected int port; - protected Condition condition; - protected Integer weight; - - // for serialization only - protected BaseNode() { - - } - - public BaseNode(String address, int port, Condition condition, Integer weight) { - this.address = checkNotNull(address, "address"); - checkArgument(port != -1, "port must be specified"); - this.port = port; - this.condition = checkNotNull(condition, "condition"); - this.weight = weight; - } - - public String getAddress() { - return address; - } - - public int getPort() { - return port; - } - - public Condition getCondition() { - return condition; - } - /** - * the maximum weight of a node is 100. + * Type of node. */ - public Integer getWeight() { - return weight; + public static enum Type { + /** + * Nodes defined as PRIMARY are in the normal rotation to receive traffic from the load balancer. + */ + PRIMARY, + + /** + * Nodes defined as SECONDARY are only in the rotation to receive traffic from the load balancer when all the + * primary nodes fail. This provides a failover feature that automatically routes traffic to the secondary node + * in the event that the primary node is disabled or in a failing state. Note that active health monitoring must + * be enabled on the load balancer to enable the failover feature to the secondary node. + */ + SECONDARY, + + UNRECOGNIZED; + + public static Type fromValue(String type) { + try { + return valueOf(checkNotNull(type, "type")); + } + catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } } - @Override - public int compareTo(BaseNode arg0) { - return address.compareTo(arg0.address); + public static class Builder> { + protected String address; + protected int port = -1; + protected Condition condition = Condition.ENABLED; + protected Type type; + protected Integer weight; + + /** + * Required. IP address or domain name for the node. + */ + public Builder address(String address) { + this.address = address; + return this; + } + + /** + * Required. Port number for the service you are load balancing. + */ + public Builder port(int port) { + this.port = port; + return this; + } + + /** + * Required. Condition for the node, which determines its role within the load balancer. + * + * @see Condition + */ + public Builder condition(Condition condition) { + this.condition = condition; + return this; + } + + /** + * Type of node to add. + * + * @see Type + */ + public Builder type(Type type) { + this.type = type; + return this; + } + + /** + * Weight of node to add. If the {@link Algorithm#WEIGHTED_ROUND_ROBIN} load balancer algorithm mode is + * selected, then the user should assign the relevant weight to the node using the weight attribute for + * the node. Must be an integer from 1 to 100. + */ + public Builder weight(Integer weight) { + this.weight = weight; + return this; + } + + public BaseNode build() { + return new BaseNode(address, port, condition, type, weight); + } + + public Builder from(T in) { + return address(in.getAddress()).port(in.getPort()).condition(in.getCondition()).type(in.getType()) + .weight(in.getWeight()); + } } - protected ToStringHelper string() { - return Objects.toStringHelper(this).omitNullValues() - .add("address", address).add("port", port).add("condition", condition).add("weight", weight); - } - - @Override - public String toString() { - return string().toString(); + public static > Builder builder() { + return new Builder(); } - @Override - public int hashCode() { - return Objects.hashCode(address, port, condition); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; - - BaseNode that = BaseNode.class.cast(obj); - return Objects.equal(this.address, that.address) - && Objects.equal(this.port, that.port) - && Objects.equal(this.condition, that.condition); + @SuppressWarnings("unchecked") + public Builder toBuilder() { + return new Builder().from((T) this); } } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/ConvertLB.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/ConvertLB.java index 4cf66416c3..2681a0a75c 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/ConvertLB.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/ConvertLB.java @@ -51,21 +51,29 @@ public class ConvertLB implements Function { @Override public LoadBalancer apply(LB lb) { try { - Builder builder = LoadBalancer.builder().region(region).name(lb.getName()).port(lb.getPort()) - .protocol(lb.getProtocol()).algorithm(lb.getAlgorithm()).nodes(lb.getNodes()).id(lb.id) - .status(lb.status).virtualIPs(lb.virtualIps).nodeCount(lb.nodeCount); + Builder builder = LoadBalancer.builder().id(lb.id).region(region).status(lb.status).name(lb.getName()) + .protocol(lb.getProtocol()).port(lb.getPort()).nodeCount(lb.nodeCount).nodes(lb.getNodes()) + .timeout(lb.getTimeout()).algorithm(lb.getAlgorithm()).halfClosed(lb.isHalfClosed()) + .sessionPersistenceType(lb.getSessionPersistenceType()).connectionLogging(lb.isConnectionLogging()) + .connectionThrottle(lb.getConnectionThrottle()).healthMonitor(lb.getHealthMonitor()) + .accessRules(lb.getAccessRules()).metadata(lb.getMetadata()).virtualIPs(lb.virtualIps); + if (lb.cluster.size() == 1) builder.clusterName(Iterables.get(lb.cluster.values(), 0)); - if (lb.sessionPersistence.size() == 1) - builder.sessionPersistenceType(Iterables.get(lb.sessionPersistence.values(), 0)); if (lb.created.size() == 1) builder.created(Iterables.get(lb.created.values(), 0)); if (lb.updated.size() == 1) builder.updated(Iterables.get(lb.updated.values(), 0)); - if (lb.connectionLogging.size() == 1) - builder.connectionLoggingEnabled(Iterables.get(lb.connectionLogging.values(), 0)); + if (lb.contentCaching.size() == 1) + builder.contentCaching(Iterables.get(lb.contentCaching.values(), 0)); + if (lb.sslTermination != null) + builder.sslTermination(lb.sslTermination); + if (lb.sourceAddresses != null) + builder.sourceAddresses(lb.sourceAddresses); + return builder.build(); - } catch (NullPointerException e) { + } + catch (NullPointerException e) { logger.warn(e, "nullpointer found parsing %s", lb); throw e; } diff --git a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/LB.java b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/LB.java index 5d92219ee8..993e991c67 100644 --- a/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/LB.java +++ b/apis/rackspace-cloudloadbalancers/src/main/java/org/jclouds/rackspace/cloudloadbalancers/functions/LB.java @@ -22,9 +22,11 @@ import java.util.Date; import java.util.Map; import java.util.Set; -import org.jclouds.rackspace.cloudloadbalancers.domain.Node; -import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Status; +import org.jclouds.rackspace.cloudloadbalancers.domain.Node; +import org.jclouds.rackspace.cloudloadbalancers.domain.SSLTermination; +import org.jclouds.rackspace.cloudloadbalancers.domain.SourceAddresses; +import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP; import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer; import com.google.common.base.Objects; @@ -33,17 +35,18 @@ import com.google.common.collect.Sets; /** * Only here as the datatype for cloudloadbalancers is awkward. - **/ + */ class LB extends BaseLoadBalancer { int id; int nodeCount; Status status; Set virtualIps = Sets.newLinkedHashSet(); - Map sessionPersistence = Maps.newLinkedHashMap(); Map cluster = Maps.newLinkedHashMap(); Map created = Maps.newLinkedHashMap(); Map updated = Maps.newLinkedHashMap(); - Map connectionLogging = Maps.newLinkedHashMap(); + Map contentCaching = Maps.newLinkedHashMap(); + SSLTermination sslTermination; + SourceAddresses sourceAddresses; @Override public int hashCode() { diff --git a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiExpectTest.java b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiExpectTest.java index 3e9ea0e440..deec610959 100644 --- a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiExpectTest.java +++ b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiExpectTest.java @@ -102,7 +102,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes .name("sample-loadbalancer") .protocol("HTTP") .port(80) - .algorithm(LoadBalancer.Algorithm.RANDOM.name()) + .algorithm(LoadBalancer.Algorithm.RANDOM) .virtualIPType(VirtualIP.Type.PUBLIC) .nodes(nodeRequests) .build(); @@ -125,7 +125,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes .name("foo") .protocol("HTTPS") .port(443) - .algorithm(LoadBalancer.Algorithm.RANDOM.name()); + .algorithm(LoadBalancer.Algorithm.RANDOM); api.update(2000, lbAttrs); } diff --git a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiLiveTest.java b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiLiveTest.java index ae55013038..04d9e0f60b 100644 --- a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiLiveTest.java +++ b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/LoadBalancerApiLiveTest.java @@ -151,7 +151,7 @@ public class LoadBalancerApiLiveTest extends BaseCloudLoadBalancersApiLiveTest { assertEquals(lb.getRegion(), region); assertEquals(lb.getName(), name); assertEquals(lb.getProtocol(), "HTTP"); - assertEquals(lb.getPort(), Integer.valueOf(80)); + assertEquals(lb.getPort(), new Integer(80)); assertEquals(Iterables.get(lb.getVirtualIPs(), 0).getType(), Type.PUBLIC); } diff --git a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/NodeApiExpectTest.java b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/NodeApiExpectTest.java index 3fb46dfc6e..5f5e2c4efe 100644 --- a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/NodeApiExpectTest.java +++ b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/features/NodeApiExpectTest.java @@ -91,6 +91,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest { .name("sample-loadbalancer") .protocol("HTTP") .port(80) - .algorithm("RANDOM") + .algorithm(Algorithm.RANDOM) .status(Status.ACTIVE) - .connectionLoggingEnabled(true) + .connectionLogging(true) + .contentCaching(true) .nodeCount(2) + .halfClosed(false) + .healthMonitor(HealthMonitor.builder().type(Type.CONNECT).delay(10).timeout(5).attemptsBeforeDeactivation(2).build()) + .sslTermination(SSLTermination.builder().enabled(true).secureTrafficOnly(false).securePort(443).build()) + .sourceAddresses(SourceAddresses.builder().ipv6Public("2001:4800:7901::5/64").ipv4Public("174.143.139.137").ipv4Servicenet("10.183.250.137").build()) + .connectionThrottle(ConnectionThrottle.builder().maxConnections(100).minConnections(10).maxConnectionRate(50).rateInterval(60).build()) + .accessRules(ImmutableSet.of( + AccessRule.builder().id(22215).type(AccessRule.Type.DENY).address("1.2.3.4/32").build(), + AccessRule.builder().id(22217).type(AccessRule.Type.ALLOW).address("12.0.0.0/8").build())) .virtualIPs(ImmutableSet.of( - VirtualIP.builder().id(1000).address("206.10.10.210").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV4).build())) + VirtualIP.builder().id(1000).address("206.10.10.210").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV4).build(), + VirtualIP.builder().id(1001).address("2001:4800:7901:0000:9a32:3c2a:0000:0001").type(VirtualIP.Type.PUBLIC).ipVersion(IPVersion.IPV6).build())) .nodes(ImmutableSet.of( Node.builder().id(1041).address("10.1.1.1").port(80).condition(Node.Condition.ENABLED).status(Node.Status.ONLINE).build(), Node.builder().id(1411).address("10.1.1.2").port(80).condition(Node.Condition.ENABLED).status(Node.Status.ONLINE).build())) - .sessionPersistenceType("HTTP_COOKIE") + .sessionPersistenceType(SessionPersistenceType.HTTP_COOKIE) .clusterName("c1.dfw1") .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:42Z")) - .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:44Z")).build(); + .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:44Z")) + .metadata(ImmutableSet. of( + Metadata.builder().id(1).key("color").value("red").build(), + Metadata.builder().id(2).key("label").value("web-load-balancer").build())).build(); } // add factory binding as this is not default diff --git a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/functions/ParseLoadBalancersTest.java b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/functions/ParseLoadBalancersTest.java index 8f9de47895..6891d8a070 100644 --- a/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/functions/ParseLoadBalancersTest.java +++ b/apis/rackspace-cloudloadbalancers/src/test/java/org/jclouds/rackspace/cloudloadbalancers/functions/ParseLoadBalancersTest.java @@ -27,6 +27,7 @@ import org.jclouds.http.HttpResponse; import org.jclouds.json.BaseIterableWithMarkerParserTest; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer; import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Status; +import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer.Algorithm; import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP; import org.testng.annotations.Test; @@ -52,7 +53,7 @@ public class ParseLoadBalancersTest extends BaseIterableWithMarkerParserTest