mirror of https://github.com/apache/jclouds.git
More attributes and domain objects for Rackspace Cloud Load Balancers.
This commit is contained in:
parent
f8f99b41b1
commit
6bc848c232
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
@ -33,138 +34,154 @@ import com.google.common.base.Objects.ToStringHelper;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private final String region;
|
||||||
public static Builder builder() {
|
private final int id;
|
||||||
return new Builder();
|
private final Status status;
|
||||||
|
private final Set<VirtualIP> 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<Node> nodes,
|
||||||
|
@Nullable Integer timeout, @Nullable Boolean halfClosed, @Nullable Algorithm algorithm, Status status,
|
||||||
|
Set<VirtualIP> virtualIPs, @Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
||||||
|
String clusterName, Date created, Date updated, @Nullable Map<String, Boolean> connectionLogging,
|
||||||
|
@Nullable ConnectionThrottle connectionThrottle, boolean contentCaching, int nodeCount,
|
||||||
|
@Nullable HealthMonitor healthMonitor, @Nullable SSLTermination sslTermination,
|
||||||
|
SourceAddresses sourceAddresses, @Nullable Set<AccessRule> accessRules,
|
||||||
|
@Nullable Set<Metadata> 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 Status getStatus() {
|
||||||
public Builder toBuilder() {
|
return status;
|
||||||
return new Builder().from(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends BaseLoadBalancer.Builder<Node, LoadBalancer> {
|
/**
|
||||||
private String region;
|
* @see VirtualIP
|
||||||
private int id = -1;
|
*/
|
||||||
private Status status;
|
public Set<VirtualIP> getVirtualIPs() {
|
||||||
private Set<VirtualIP> virtualIPs = ImmutableSet.<VirtualIP> of();
|
return virtualIPs;
|
||||||
private String sessionPersistenceType;
|
}
|
||||||
private String clusterName;
|
|
||||||
private Date created;
|
|
||||||
private Date updated;
|
|
||||||
private boolean connectionLoggingEnabled;
|
|
||||||
private int nodeCount = 0;
|
|
||||||
|
|
||||||
public Builder region(String region) {
|
/**
|
||||||
this.region = region;
|
* Name of the cluster.
|
||||||
return this;
|
*/
|
||||||
}
|
public String getClusterName() {
|
||||||
|
return clusterName;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder id(int id) {
|
/**
|
||||||
this.id = id;
|
* When the load balancer was created.
|
||||||
return this;
|
*/
|
||||||
}
|
public Date getCreated() {
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder status(Status status) {
|
/**
|
||||||
this.status = status;
|
* When the load balancer was updated.
|
||||||
return this;
|
*/
|
||||||
}
|
public Date getUpdated() {
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder algorithm(Algorithm algorithm) {
|
/**
|
||||||
algorithm(algorithm.name());
|
* View the current content caching configuration.
|
||||||
return this;
|
*/
|
||||||
}
|
public boolean isContentCaching() {
|
||||||
|
return contentCaching;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder virtualIPs(Iterable<VirtualIP> virtualIPs) {
|
/**
|
||||||
this.virtualIPs = ImmutableSet.<VirtualIP> copyOf(checkNotNull(virtualIPs, "virtualIPs"));
|
* Broken out as a separate field because when LoadBalancers are returned from
|
||||||
return this;
|
* {@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;
|
* @see SSLTermination
|
||||||
return this;
|
*/
|
||||||
}
|
@Nullable
|
||||||
|
public SSLTermination getSSLTermination() {
|
||||||
|
return sslTermination;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder clusterName(String clusterName) {
|
/**
|
||||||
this.clusterName = clusterName;
|
* @see SourceAddresses
|
||||||
return this;
|
*/
|
||||||
}
|
public SourceAddresses getSourceAddresses() {
|
||||||
|
return sourceAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder created(Date created) {
|
protected ToStringHelper string() {
|
||||||
this.created = created;
|
return Objects.toStringHelper(this).omitNullValues().add("id", id).add("region", region).add("status", status)
|
||||||
return this;
|
.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) {
|
@Override
|
||||||
this.updated = updated;
|
public String toString() {
|
||||||
return this;
|
return string().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder connectionLoggingEnabled(boolean connectionLoggingEnabled) {
|
@Override
|
||||||
this.connectionLoggingEnabled = connectionLoggingEnabled;
|
public int hashCode() {
|
||||||
return this;
|
return Objects.hashCode(id, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @see LoadBalancer#getNodeCount()
|
public boolean equals(Object obj) {
|
||||||
*/
|
if (this == obj)
|
||||||
public Builder nodeCount(int nodeCount) {
|
return true;
|
||||||
this.nodeCount = nodeCount;
|
if (obj == null || getClass() != obj.getClass())
|
||||||
return this;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
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<Node> nodes) {
|
|
||||||
this.nodes = ImmutableSet.<Node> 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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<Node, LoadBalancer> {
|
||||||
public static Status fromValue(String status) {
|
public static Status fromValue(String status) {
|
||||||
try {
|
try {
|
||||||
return valueOf(checkNotNull(status, "status"));
|
return valueOf(checkNotNull(status, "status"));
|
||||||
} catch (IllegalArgumentException e) {
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
return UNRECOGNIZED;
|
return UNRECOGNIZED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static class Builder extends BaseLoadBalancer.Builder<Node, LoadBalancer> {
|
||||||
* All load balancers utilize an algorithm that defines how traffic should be directed between
|
private String region;
|
||||||
* back-end nodes. The default algorithm for newly created load balancers is RANDOM, which can be
|
private int id = -1;
|
||||||
* overridden at creation time or changed after the load balancer has been initially provisioned.
|
private Status status;
|
||||||
* The algorithm name is to be constant within a major revision of the load balancing API, though
|
private Set<VirtualIP> virtualIPs = ImmutableSet.<VirtualIP> of();
|
||||||
* new algorithms may be created with a unique algorithm name within a given major revision of
|
private String clusterName;
|
||||||
* the service API.
|
private Date created;
|
||||||
*/
|
private Date updated;
|
||||||
public static enum Algorithm {
|
private boolean contentCaching;
|
||||||
/**
|
private int nodeCount = 0;
|
||||||
* The node with the lowest number of connections will receive requests.
|
private SSLTermination sslTermination;
|
||||||
*/
|
private SourceAddresses sourceAddresses;
|
||||||
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) {
|
public Builder region(String region) {
|
||||||
try {
|
this.region = region;
|
||||||
return valueOf(checkNotNull(algorithm, "algorithm"));
|
return this;
|
||||||
} catch (IllegalArgumentException e) {
|
}
|
||||||
return UNRECOGNIZED;
|
|
||||||
}
|
public Builder id(int id) {
|
||||||
|
this.id = id;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder status(Status status) {
|
||||||
|
this.status = status;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder virtualIPs(Iterable<VirtualIP> virtualIPs) {
|
||||||
|
this.virtualIPs = ImmutableSet.<VirtualIP> 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<Node> nodes) {
|
||||||
|
this.nodes = ImmutableSet.<Node> 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<AccessRule> accessRules) {
|
||||||
|
return Builder.class.cast(super.accessRules(accessRules));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Builder metadata(@Nullable Set<Metadata> 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,
|
@SuppressWarnings("unchecked")
|
||||||
Algorithm.WEIGHTED_ROUND_ROBIN };
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
private final String region;
|
|
||||||
private final int id;
|
|
||||||
private final Status status;
|
|
||||||
private final Algorithm algorithm;
|
|
||||||
private final Set<VirtualIP> 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<VirtualIP> virtualIPs, Iterable<Node> 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<VirtualIP> 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public Builder toBuilder() {
|
||||||
return Objects.hashCode(id, region);
|
return new Builder().from(this);
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,22 +19,24 @@
|
||||||
package org.jclouds.rackspace.cloudloadbalancers.domain;
|
package org.jclouds.rackspace.cloudloadbalancers.domain;
|
||||||
|
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
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;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used to update Load Balancers.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s01s02.html"
|
|
||||||
* />
|
|
||||||
*/
|
*/
|
||||||
public class LoadBalancerAttributes {
|
public class LoadBalancerAttributes {
|
||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String protocol;
|
protected String protocol;
|
||||||
protected Integer port;
|
protected Integer port;
|
||||||
protected String algorithm;
|
protected Algorithm algorithm;
|
||||||
|
protected Integer timeout;
|
||||||
|
protected Boolean halfClosed;
|
||||||
|
|
||||||
public LoadBalancerAttributes name(String name) {
|
public LoadBalancerAttributes name(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -46,43 +48,31 @@ public class LoadBalancerAttributes {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoadBalancerAttributes port(int port) {
|
public LoadBalancerAttributes port(Integer port) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoadBalancerAttributes algorithm(String algorithm) {
|
public LoadBalancerAttributes algorithm(Algorithm algorithm) {
|
||||||
this.algorithm = algorithm;
|
this.algorithm = algorithm;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends BaseLoadBalancer<?, T>> LoadBalancerAttributes fromLoadBalancer(T lb) {
|
public LoadBalancerAttributes timeout(Integer timeout) {
|
||||||
return Builder.name(lb.getName()).port(lb.getPort()).protocol(lb.getProtocol()).algorithm(lb.getAlgorithm());
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public LoadBalancerAttributes halfClosed(Boolean halfClosed) {
|
||||||
public static LoadBalancerAttributes name(String name) {
|
this.halfClosed = halfClosed;
|
||||||
return new LoadBalancerAttributes().name(name);
|
return this;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
return Objects.toStringHelper(this).omitNullValues().add("name", name).add("algorithm", algorithm)
|
||||||
.add("name", name).add("algorithm", algorithm).add("port", port).add("protocol", protocol);
|
.add("port", port).add("protocol", protocol).add("timeout", timeout).add("halfClosed", halfClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return string().toString();
|
return string().toString();
|
||||||
|
@ -90,18 +80,68 @@ public class LoadBalancerAttributes {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(name, algorithm, port, protocol);
|
return Objects.hashCode(name, algorithm, port, protocol, timeout, halfClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) return true;
|
if (this == obj)
|
||||||
if (obj == null || getClass() != obj.getClass()) return false;
|
return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
LoadBalancerAttributes that = LoadBalancerAttributes.class.cast(obj);
|
LoadBalancerAttributes that = LoadBalancerAttributes.class.cast(obj);
|
||||||
return Objects.equal(this.name, that.name)
|
return Objects.equal(this.name, that.name) && Objects.equal(this.algorithm, that.algorithm)
|
||||||
&& Objects.equal(this.algorithm, that.algorithm)
|
&& Objects.equal(this.port, that.port) && Objects.equal(this.protocol, that.protocol)
|
||||||
&& Objects.equal(this.port, that.port)
|
&& Objects.equal(this.timeout, that.timeout) && Objects.equal(this.halfClosed, that.halfClosed);
|
||||||
&& Objects.equal(this.protocol, that.protocol);
|
}
|
||||||
|
|
||||||
|
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 <T extends BaseLoadBalancer<?, T>> LoadBalancerAttributes fromLoadBalancer(T lb) {
|
||||||
|
return Builder.name(lb.getName()).port(lb.getPort()).protocol(lb.getProtocol()).algorithm(lb.getAlgorithm())
|
||||||
|
.timeout(lb.getTimeout()).halfClosed(lb.isHalfClosed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used to create Load Balancers.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s01s02.html"
|
|
||||||
* />
|
|
||||||
*/
|
*/
|
||||||
public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalancerRequest> {
|
public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalancerRequest> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private final Set<Map<String, String>> virtualIps;
|
||||||
public static Builder builder() {
|
|
||||||
return new Builder();
|
public LoadBalancerRequest(String name, String protocol, @Nullable Integer port, Set<NodeRequest> nodes,
|
||||||
|
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
||||||
|
@Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
||||||
|
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
||||||
|
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
||||||
|
@Nullable Set<Metadata> 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<NodeRequest> nodes,
|
||||||
|
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
||||||
|
@Nullable Map<String, SessionPersistenceType> sessionPersistenceType,
|
||||||
|
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
||||||
|
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
||||||
|
@Nullable Set<Metadata> metadata, Set<Map<String, String>> virtualIPsFromOptions) {
|
||||||
|
super(name, protocol, port, nodes, algorithm, timeout, halfClosed, sessionPersistenceType, connectionLogging,
|
||||||
|
connectionThrottle, healthMonitor, accessRules, metadata);
|
||||||
|
this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Set<Map<String, String>> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
||||||
|
checkArgument(virtualIPType == null || virtualIPId == null,
|
||||||
|
"virtualIPType and virtualIPId cannot both be specified");
|
||||||
|
if (virtualIPType != null)
|
||||||
|
return ImmutableSet.<Map<String, String>> of(ImmutableMap.of("type", virtualIPType.name()));
|
||||||
|
else if (virtualIPId != null)
|
||||||
|
return ImmutableSet.<Map<String, String>> 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
|
@Override
|
||||||
public Builder toBuilder() {
|
public String toString() {
|
||||||
return new Builder().from(this);
|
return string().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends BaseLoadBalancer.Builder<NodeRequest, LoadBalancerRequest> {
|
public static class Builder extends BaseLoadBalancer.Builder<NodeRequest, LoadBalancerRequest> {
|
||||||
private VirtualIP.Type virtualIPType;
|
private VirtualIP.Type virtualIPType;
|
||||||
private Integer virtualIPId;
|
private Integer virtualIPId;
|
||||||
private List<Map<String, String>> virtualIps;
|
private Set<Map<String, String>> virtualIps;
|
||||||
|
|
||||||
public Builder virtualIPId(Integer virtualIPId) {
|
public Builder virtualIPId(Integer virtualIPId) {
|
||||||
this.virtualIPId = virtualIPId;
|
this.virtualIPId = virtualIPId;
|
||||||
|
@ -69,49 +103,77 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoadBalancerRequest build() {
|
private Builder virtualIPs(Set<Map<String, String>> virtualIPs) {
|
||||||
return virtualIps == null
|
this.virtualIps = virtualIPs;
|
||||||
? new LoadBalancerRequest(name, protocol, port, algorithm, nodes, virtualIPType, virtualIPId)
|
return this;
|
||||||
: new LoadBalancerRequest(name, protocol, port, algorithm, nodes, virtualIps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public Builder nodes(Iterable<NodeRequest> nodes) {
|
public Builder nodes(Iterable<NodeRequest> nodes) {
|
||||||
this.nodes = ImmutableSet.<NodeRequest> copyOf(checkNotNull(nodes, "nodes"));
|
this.nodes = ImmutableSet.<NodeRequest> copyOf(checkNotNull(nodes, "nodes"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Builder node(NodeRequest nodes) {
|
public Builder node(NodeRequest nodes) {
|
||||||
this.nodes.add(checkNotNull(nodes, "nodes"));
|
this.nodes.add(checkNotNull(nodes, "nodes"));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Builder virtualIPs(List<Map<String, String>> virtualIPs) {
|
/**
|
||||||
this.virtualIps = virtualIPs;
|
* {@inheritDoc}
|
||||||
return this;
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Builder algorithm(String algorithm) {
|
public Builder algorithm(Algorithm algorithm) {
|
||||||
return Builder.class.cast(super.algorithm(algorithm));
|
return Builder.class.cast(super.algorithm(algorithm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Builder from(LoadBalancerRequest in) {
|
public Builder from(LoadBalancerRequest in) {
|
||||||
return Builder.class.cast(super.from(in)).virtualIPs(in.virtualIps);
|
return Builder.class.cast(super.from(in)).virtualIPs(in.virtualIps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Builder name(String name) {
|
public Builder name(String name) {
|
||||||
return Builder.class.cast(super.name(name));
|
return Builder.class.cast(super.name(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Builder port(Integer port) {
|
public Builder port(Integer port) {
|
||||||
return Builder.class.cast(super.port(port));
|
return Builder.class.cast(super.port(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Builder protocol(String protocol) {
|
public Builder protocol(String protocol) {
|
||||||
return Builder.class.cast(super.protocol(protocol));
|
return Builder.class.cast(super.protocol(protocol));
|
||||||
|
@ -119,38 +181,13 @@ public class LoadBalancerRequest extends BaseLoadBalancer<NodeRequest, LoadBalan
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<Map<String, String>> virtualIps;
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Builder builder() {
|
||||||
public LoadBalancerRequest(String name, String protocol, int port, String algorithm, Iterable<NodeRequest> nodes,
|
return new Builder();
|
||||||
VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
|
||||||
this(name, protocol, port, algorithm, nodes, getVirtualIPsFromOptions(virtualIPType, virtualIPId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoadBalancerRequest(String name, String protocol, int port, String algorithm, Iterable<NodeRequest> nodes,
|
|
||||||
List<Map<String, String>> virtualIPsFromOptions) {
|
|
||||||
super(name, protocol, port, algorithm, nodes);
|
|
||||||
this.virtualIps = checkNotNull(virtualIPsFromOptions, "virtualIPsFromOptions");
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<Map<String, String>> getVirtualIPsFromOptions(VirtualIP.Type virtualIPType, Integer virtualIPId) {
|
|
||||||
checkArgument(virtualIPType == null || virtualIPId == null,
|
|
||||||
"virtualIPType and virtualIPId cannot both be specified");
|
|
||||||
if (virtualIPType != null)
|
|
||||||
return ImmutableList.<Map<String, String>> of(ImmutableMap.of("type", virtualIPType.name()));
|
|
||||||
else if (virtualIPId != null)
|
|
||||||
return ImmutableList.<Map<String, String>> 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
|
@Override
|
||||||
public String toString() {
|
public Builder toBuilder() {
|
||||||
return string().toString();
|
return new Builder().from(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,73 +51,58 @@ import com.google.common.base.Objects.ToStringHelper;
|
||||||
* nodes.
|
* nodes.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s02.html" />
|
|
||||||
*/
|
*/
|
||||||
public class Node extends BaseNode<Node> {
|
public class Node extends BaseNode<Node> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
private int id;
|
||||||
public static Builder builder() {
|
private Status status;
|
||||||
return new Builder();
|
|
||||||
|
// for serialization only
|
||||||
|
Node() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public Node(int id, String address, int port, Condition condition, Type type, Status status, Integer weight) {
|
||||||
* {@inheritDoc}
|
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
|
@Override
|
||||||
public Builder toBuilder() {
|
public String toString() {
|
||||||
return new Builder().from(this);
|
return string().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder extends BaseNode.Builder<Node> {
|
@Override
|
||||||
private int id = -1;
|
public int hashCode() {
|
||||||
private Status status;
|
return Objects.hashCode(id);
|
||||||
|
}
|
||||||
|
|
||||||
public Builder id(int id) {
|
@Override
|
||||||
this.id = id;
|
public boolean equals(Object obj) {
|
||||||
return this;
|
if (this == obj) return true;
|
||||||
}
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Node that = Node.class.cast(obj);
|
||||||
|
return Objects.equal(this.id, that.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The status is determined by the passive or active health monitors.
|
* The status is determined by the passive or active health monitors.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static enum Status {
|
public static enum Status {
|
||||||
/**
|
/**
|
||||||
|
@ -146,54 +131,82 @@ public class Node extends BaseNode<Node> {
|
||||||
return UNRECOGNIZED;
|
return UNRECOGNIZED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int id;
|
public static class Builder extends BaseNode.Builder<Node> {
|
||||||
private Status status;
|
private int id = -1;
|
||||||
|
private Status status;
|
||||||
|
|
||||||
// for serialization only
|
public Builder id(int id) {
|
||||||
Node() {
|
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) {
|
@SuppressWarnings("unchecked")
|
||||||
super(address, port, condition, weight);
|
public static Builder builder() {
|
||||||
checkArgument(id != -1, "id must be specified");
|
return new Builder();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public Builder toBuilder() {
|
||||||
return Objects.hashCode(id);
|
return new Builder().from(this);
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseNode.Condition;
|
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;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used to update Nodes.
|
||||||
*
|
*
|
||||||
* @author Dan Lo Bianco
|
* @author Dan Lo Bianco
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspace.com/loadbalancers/api/v1.0/clb-devguide/content/Modify_Nodes-d1e2503.html"
|
|
||||||
* />
|
|
||||||
*/
|
*/
|
||||||
public class NodeAttributes {
|
public class NodeAttributes {
|
||||||
protected String condition;
|
|
||||||
|
protected Condition condition;
|
||||||
|
protected Type type;
|
||||||
protected Integer weight;
|
protected Integer weight;
|
||||||
|
|
||||||
public NodeAttributes condition(String condition) {
|
public NodeAttributes condition(Condition condition) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
return this;
|
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;
|
this.weight = weight;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends BaseNode<T>> 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() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
return Objects.toStringHelper(this).omitNullValues()
|
||||||
.add("condition", condition).add("weight", weight);
|
.add("condition", condition).add("type", type).add("weight", weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,7 +63,7 @@ public class NodeAttributes {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(condition, weight);
|
return Objects.hashCode(condition, type, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -81,6 +73,34 @@ public class NodeAttributes {
|
||||||
|
|
||||||
NodeAttributes that = NodeAttributes.class.cast(obj);
|
NodeAttributes that = NodeAttributes.class.cast(obj);
|
||||||
return Objects.equal(this.condition, that.condition)
|
return Objects.equal(this.condition, that.condition)
|
||||||
|
&& Objects.equal(this.type, that.type)
|
||||||
&& Objects.equal(this.weight, that.weight);
|
&& 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 <T extends BaseNode<T>> NodeAttributes fromNode(T n) {
|
||||||
|
return Builder.condition(n.getCondition()).type(n.getType()).weight(n.getWeight());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,70 +48,20 @@ import com.google.common.base.Objects.ToStringHelper;
|
||||||
* nodes.
|
* nodes.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s02.html" />
|
|
||||||
*/
|
*/
|
||||||
public class NodeRequest extends BaseNode<NodeRequest> {
|
public class NodeRequest extends BaseNode<NodeRequest> {
|
||||||
|
|
||||||
@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<NodeRequest> {
|
|
||||||
|
|
||||||
@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
|
// for serialization only
|
||||||
NodeRequest() {
|
NodeRequest() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeRequest(String address, int port, Condition condition, Integer weight) {
|
public NodeRequest(String address, int port, Condition condition, Type type, Integer weight) {
|
||||||
super(address, port, condition, weight);
|
super(address, port, condition, type, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
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
|
@Override
|
||||||
|
@ -133,4 +83,69 @@ public class NodeRequest extends BaseNode<NodeRequest> {
|
||||||
return Objects.equal(this.address, that.address)
|
return Objects.equal(this.address, that.address)
|
||||||
&& Objects.equal(this.port, that.port);
|
&& Objects.equal(this.port, that.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Builder extends BaseNode.Builder<NodeRequest> {
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
* <p/>
|
||||||
|
* 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.
|
||||||
|
* <p/>
|
||||||
|
* Notes
|
||||||
|
* <ol>
|
||||||
|
* <li>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.</li>
|
||||||
|
* <li>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.</li>
|
||||||
|
* <li>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.</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* Warning
|
||||||
|
* <ol>
|
||||||
|
* <li>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.</li>
|
||||||
|
* </ol>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,96 +30,18 @@ import com.google.common.base.Objects.ToStringHelper;
|
||||||
* only within the region in which the load balancer resides.
|
* only within the region in which the load balancer resides.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s03s01.html"
|
|
||||||
* />
|
|
||||||
*/
|
*/
|
||||||
public class VirtualIP implements Comparable<VirtualIP> {
|
public class VirtualIP implements Comparable<VirtualIP> {
|
||||||
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 int id;
|
||||||
private String address;
|
private String address;
|
||||||
private Type type;
|
private Type type;
|
||||||
private IPVersion ipVersion;
|
private IPVersion ipVersion;
|
||||||
|
|
||||||
|
// for serialization only
|
||||||
|
VirtualIP() {
|
||||||
|
}
|
||||||
|
|
||||||
public VirtualIP(int id, String address, Type type, IPVersion ipVersion) {
|
public VirtualIP(int id, String address, Type type, IPVersion ipVersion) {
|
||||||
checkArgument(id != -1, "id must be specified");
|
checkArgument(id != -1, "id must be specified");
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -172,4 +94,79 @@ public class VirtualIP implements Comparable<VirtualIP> {
|
||||||
VirtualIP that = VirtualIP.class.cast(obj);
|
VirtualIP that = VirtualIP.class.cast(obj);
|
||||||
return Objects.equal(this.id, that.id);
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,104 +20,74 @@ package org.jclouds.rackspace.cloudloadbalancers.domain.internal;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
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.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;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s01s02.html"
|
|
||||||
* />
|
|
||||||
*/
|
*/
|
||||||
public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<N, T>> implements
|
public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<N, T>> implements
|
||||||
Comparable<BaseLoadBalancer<N, T>> {
|
Comparable<BaseLoadBalancer<N, T>> {
|
||||||
|
|
||||||
public static <N extends BaseNode<N>, T extends BaseLoadBalancer<N, T>> Builder<N, T> builder() {
|
private static final String ENABLED = "enabled";
|
||||||
return new Builder<N, T>();
|
private static final String PERSISTENCE_TYPE = "persistenceType";
|
||||||
}
|
public static Algorithm[] WEIGHTED_ALGORITHMS = { Algorithm.WEIGHTED_LEAST_CONNECTIONS,
|
||||||
|
Algorithm.WEIGHTED_ROUND_ROBIN };
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Builder<N, T> toBuilder() {
|
|
||||||
return new Builder<N, T>().from((T) this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder<N extends BaseNode<N>, T extends BaseLoadBalancer<N, T>> {
|
|
||||||
protected String name;
|
|
||||||
protected String protocol;
|
|
||||||
protected Integer port;
|
|
||||||
protected String algorithm;
|
|
||||||
protected Set<N> nodes = Sets.newLinkedHashSet();
|
|
||||||
|
|
||||||
public Builder<N, T> name(String name) {
|
|
||||||
this.name = name;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<N, T> protocol(String protocol) {
|
|
||||||
this.protocol = protocol;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<N, T> port(Integer port) {
|
|
||||||
this.port = port;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<N, T> algorithm(String algorithm) {
|
|
||||||
this.algorithm = algorithm;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<N, T> nodes(Iterable<N> nodes) {
|
|
||||||
this.nodes = ImmutableSet.<N> copyOf(checkNotNull(nodes, "nodes"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Builder<N, T> node(N node) {
|
|
||||||
this.nodes.add((N) checkNotNull(nodes, "nodes"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseLoadBalancer<N, T> build() {
|
|
||||||
return new BaseLoadBalancer<N, T>(name, protocol, port, algorithm, nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<N, T> from(T baseLoadBalancer) {
|
|
||||||
return name(baseLoadBalancer.getName()).port(baseLoadBalancer.getPort()).protocol(
|
|
||||||
baseLoadBalancer.getProtocol()).algorithm(baseLoadBalancer.getAlgorithm()).nodes(
|
|
||||||
baseLoadBalancer.getNodes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// for serialization only
|
|
||||||
protected BaseLoadBalancer() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String protocol;
|
protected String protocol;
|
||||||
protected Integer port;
|
protected Integer port;
|
||||||
protected String algorithm;
|
protected SortedSet<N> nodes = ImmutableSortedSet.of(); // so tests will come out consistently
|
||||||
// so tests will come out consistently
|
protected Algorithm algorithm;
|
||||||
protected SortedSet<N> nodes = ImmutableSortedSet.of();
|
protected Integer timeout;
|
||||||
|
protected Boolean halfClosed;
|
||||||
|
protected Map<String, SessionPersistenceType> sessionPersistence;
|
||||||
|
protected Map<String, Boolean> connectionLogging;
|
||||||
|
protected ConnectionThrottle connectionThrottle;
|
||||||
|
protected HealthMonitor healthMonitor;
|
||||||
|
protected Set<AccessRule> accessList;
|
||||||
|
protected Set<Metadata> metadata;
|
||||||
|
|
||||||
public BaseLoadBalancer(String name, String protocol, Integer port, @Nullable String algorithm, Iterable<N> nodes) {
|
// for serialization only
|
||||||
|
protected BaseLoadBalancer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseLoadBalancer(String name, @Nullable String protocol, @Nullable Integer port, Iterable<N> nodes,
|
||||||
|
@Nullable Algorithm algorithm, @Nullable Integer timeout, @Nullable Boolean halfClosed,
|
||||||
|
@Nullable Map<String, SessionPersistenceType> sessionPersistence,
|
||||||
|
@Nullable Map<String, Boolean> connectionLogging, @Nullable ConnectionThrottle connectionThrottle,
|
||||||
|
@Nullable HealthMonitor healthMonitor, @Nullable Set<AccessRule> accessRules,
|
||||||
|
@Nullable Set<Metadata> metadata) {
|
||||||
this.name = checkNotNull(name, "name");
|
this.name = checkNotNull(name, "name");
|
||||||
this.protocol = protocol;// null on deleted LB
|
this.protocol = protocol;// null on deleted LB
|
||||||
this.port = port;// 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.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
|
@Override
|
||||||
|
@ -129,33 +99,102 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return protocol, which may be null if the load balancer is deleted.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
public String getProtocol() {
|
public String getProtocol() {
|
||||||
return protocol;
|
return protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return port, which may be null if port has not been set.
|
||||||
* @return algorithm, which may be null if the load balancer is deleted
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getAlgorithm() {
|
public Integer getPort() {
|
||||||
return algorithm;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<N> getNodes() {
|
public Set<N> getNodes() {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
/**
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
* @return algorithm, which may be null if the load balancer is deleted.
|
||||||
.add("name", name).add("protocol", protocol).add("port", port)
|
*/
|
||||||
.add("algorithm", algorithm).add("nodes", nodes);
|
@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<AccessRule> getAccessRules() {
|
||||||
|
return accessList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return metadata, which may be null if metadata has not been set.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Set<Metadata> 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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return string().toString();
|
return string().toString();
|
||||||
|
@ -168,10 +207,266 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) return true;
|
if (this == obj)
|
||||||
if (obj == null || getClass() != obj.getClass()) return false;
|
return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
|
||||||
LoadBalancer that = LoadBalancer.class.cast(obj);
|
LoadBalancer that = LoadBalancer.class.cast(obj);
|
||||||
return Objects.equal(this.name, that.name);
|
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<N extends BaseNode<N>, T extends BaseLoadBalancer<N, T>> {
|
||||||
|
protected String name;
|
||||||
|
protected String protocol;
|
||||||
|
protected Integer port;
|
||||||
|
protected Set<N> nodes = Sets.newLinkedHashSet();
|
||||||
|
protected Algorithm algorithm;
|
||||||
|
protected Integer timeout;
|
||||||
|
protected Boolean halfClosed;
|
||||||
|
protected Map<String, SessionPersistenceType> sessionPersistence;
|
||||||
|
protected Map<String, Boolean> connectionLogging;
|
||||||
|
protected ConnectionThrottle connectionThrottle;
|
||||||
|
protected HealthMonitor healthMonitor;
|
||||||
|
protected Set<AccessRule> accessRules;
|
||||||
|
protected Set<Metadata> 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<N, T> 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<N, T> 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<N, T> port(@Nullable Integer port) {
|
||||||
|
this.port = port;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required. Nodes to be added to the load balancer.
|
||||||
|
*/
|
||||||
|
public Builder<N, T> nodes(Iterable<N> nodes) {
|
||||||
|
this.nodes = ImmutableSet.<N> copyOf(checkNotNull(nodes, "nodes"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Builder<N, T> 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<N, T> 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<N, T> 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<N, T> 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<N, T> 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<N, T> 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<N, T> 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<N, T> 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<N, T> accessRules(@Nullable Set<AccessRule> accessRules) {
|
||||||
|
this.accessRules = accessRules;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information (metadata) that can be associated with each load balancer for the client's personal use.
|
||||||
|
*/
|
||||||
|
public Builder<N, T> metadata(@Nullable Set<Metadata> metadata) {
|
||||||
|
this.metadata = metadata;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseLoadBalancer<N, T> build() {
|
||||||
|
return new BaseLoadBalancer<N, T>(name, protocol, port, nodes, algorithm, timeout, halfClosed,
|
||||||
|
sessionPersistence, connectionLogging, connectionThrottle, healthMonitor, accessRules, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<N, T> 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 <N extends BaseNode<N>, T extends BaseLoadBalancer<N, T>> Builder<N, T> builder() {
|
||||||
|
return new Builder<N, T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Builder<N, T> toBuilder() {
|
||||||
|
return new Builder<N, T>().from((T) this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
|
||||||
|
@ -49,53 +51,81 @@ import com.google.common.base.Objects.ToStringHelper;
|
||||||
* nodes.
|
* nodes.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
* @see <a href=
|
|
||||||
* "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s02.html" />
|
|
||||||
*/
|
*/
|
||||||
public class BaseNode<T extends BaseNode<T>> implements Comparable<BaseNode<T>> {
|
public class BaseNode<T extends BaseNode<T>> implements Comparable<BaseNode<T>> {
|
||||||
|
|
||||||
public static <T extends BaseNode<T>> Builder<T> builder() {
|
protected String address;
|
||||||
return new Builder<T>();
|
protected int port;
|
||||||
|
protected Condition condition;
|
||||||
|
protected Type type;
|
||||||
|
protected Integer weight;
|
||||||
|
|
||||||
|
// for serialization only
|
||||||
|
protected BaseNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
public BaseNode(String address, int port, Condition condition, Type type, Integer weight) {
|
||||||
public Builder<T> toBuilder() {
|
this.address = checkNotNull(address, "address");
|
||||||
return new Builder<T>().from((T) this);
|
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<T extends BaseNode<T>> {
|
public String getAddress() {
|
||||||
protected String address;
|
return address;
|
||||||
protected int port = -1;
|
}
|
||||||
protected Condition condition = Condition.ENABLED;
|
|
||||||
protected Integer weight;
|
|
||||||
|
|
||||||
public Builder<T> address(String address) {
|
public int getPort() {
|
||||||
this.address = address;
|
return port;
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<T> port(int port) {
|
public Condition getCondition() {
|
||||||
this.port = port;
|
return condition;
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<T> condition(Condition condition) {
|
public Type getType() {
|
||||||
this.condition = condition;
|
return type;
|
||||||
return this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Builder<T> weight(Integer weight) {
|
/**
|
||||||
this.weight = weight;
|
* the maximum weight of a node is 100.
|
||||||
return this;
|
*/
|
||||||
}
|
public Integer getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
|
|
||||||
public BaseNode<T> build() {
|
@Override
|
||||||
return new BaseNode<T>(address, port, condition, weight);
|
public int compareTo(BaseNode<T> arg0) {
|
||||||
}
|
return address.compareTo(arg0.address);
|
||||||
|
}
|
||||||
|
|
||||||
public Builder<T> from(T in) {
|
protected ToStringHelper string() {
|
||||||
return address(in.getAddress()).port(in.getPort()).condition(in.getCondition()).weight(in.getWeight());
|
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<T extends BaseNode<T>> implements Comparable<BaseNode<T>>
|
||||||
public static Condition fromValue(String condition) {
|
public static Condition fromValue(String condition) {
|
||||||
try {
|
try {
|
||||||
return valueOf(checkNotNull(condition, "condition"));
|
return valueOf(checkNotNull(condition, "condition"));
|
||||||
} catch (IllegalArgumentException e) {
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
return UNRECOGNIZED;
|
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() {
|
public static enum Type {
|
||||||
return weight;
|
/**
|
||||||
|
* 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 static class Builder<T extends BaseNode<T>> {
|
||||||
public int compareTo(BaseNode<T> arg0) {
|
protected String address;
|
||||||
return address.compareTo(arg0.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<T> address(String address) {
|
||||||
|
this.address = address;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required. Port number for the service you are load balancing.
|
||||||
|
*/
|
||||||
|
public Builder<T> 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<T> condition(Condition condition) {
|
||||||
|
this.condition = condition;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of node to add.
|
||||||
|
*
|
||||||
|
* @see Type
|
||||||
|
*/
|
||||||
|
public Builder<T> 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<T> weight(Integer weight) {
|
||||||
|
this.weight = weight;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseNode<T> build() {
|
||||||
|
return new BaseNode<T>(address, port, condition, type, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> from(T in) {
|
||||||
|
return address(in.getAddress()).port(in.getPort()).condition(in.getCondition()).type(in.getType())
|
||||||
|
.weight(in.getWeight());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
public static <T extends BaseNode<T>> Builder<T> builder() {
|
||||||
return Objects.toStringHelper(this).omitNullValues()
|
return new Builder<T>();
|
||||||
.add("address", address).add("port", port).add("condition", condition).add("weight", weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return string().toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@SuppressWarnings("unchecked")
|
||||||
public int hashCode() {
|
public Builder<T> toBuilder() {
|
||||||
return Objects.hashCode(address, port, condition);
|
return new Builder<T>().from((T) this);
|
||||||
}
|
|
||||||
|
|
||||||
@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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,21 +51,29 @@ public class ConvertLB implements Function<LB, LoadBalancer> {
|
||||||
@Override
|
@Override
|
||||||
public LoadBalancer apply(LB lb) {
|
public LoadBalancer apply(LB lb) {
|
||||||
try {
|
try {
|
||||||
Builder builder = LoadBalancer.builder().region(region).name(lb.getName()).port(lb.getPort())
|
Builder builder = LoadBalancer.builder().id(lb.id).region(region).status(lb.status).name(lb.getName())
|
||||||
.protocol(lb.getProtocol()).algorithm(lb.getAlgorithm()).nodes(lb.getNodes()).id(lb.id)
|
.protocol(lb.getProtocol()).port(lb.getPort()).nodeCount(lb.nodeCount).nodes(lb.getNodes())
|
||||||
.status(lb.status).virtualIPs(lb.virtualIps).nodeCount(lb.nodeCount);
|
.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)
|
if (lb.cluster.size() == 1)
|
||||||
builder.clusterName(Iterables.get(lb.cluster.values(), 0));
|
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)
|
if (lb.created.size() == 1)
|
||||||
builder.created(Iterables.get(lb.created.values(), 0));
|
builder.created(Iterables.get(lb.created.values(), 0));
|
||||||
if (lb.updated.size() == 1)
|
if (lb.updated.size() == 1)
|
||||||
builder.updated(Iterables.get(lb.updated.values(), 0));
|
builder.updated(Iterables.get(lb.updated.values(), 0));
|
||||||
if (lb.connectionLogging.size() == 1)
|
if (lb.contentCaching.size() == 1)
|
||||||
builder.connectionLoggingEnabled(Iterables.get(lb.connectionLogging.values(), 0));
|
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();
|
return builder.build();
|
||||||
} catch (NullPointerException e) {
|
}
|
||||||
|
catch (NullPointerException e) {
|
||||||
logger.warn(e, "nullpointer found parsing %s", lb);
|
logger.warn(e, "nullpointer found parsing %s", lb);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,11 @@ import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
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.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 org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
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.
|
* Only here as the datatype for cloudloadbalancers is awkward.
|
||||||
**/
|
*/
|
||||||
class LB extends BaseLoadBalancer<Node, LB> {
|
class LB extends BaseLoadBalancer<Node, LB> {
|
||||||
int id;
|
int id;
|
||||||
int nodeCount;
|
int nodeCount;
|
||||||
Status status;
|
Status status;
|
||||||
Set<VirtualIP> virtualIps = Sets.newLinkedHashSet();
|
Set<VirtualIP> virtualIps = Sets.newLinkedHashSet();
|
||||||
Map<String, String> sessionPersistence = Maps.newLinkedHashMap();
|
|
||||||
Map<String, String> cluster = Maps.newLinkedHashMap();
|
Map<String, String> cluster = Maps.newLinkedHashMap();
|
||||||
Map<String, Date> created = Maps.newLinkedHashMap();
|
Map<String, Date> created = Maps.newLinkedHashMap();
|
||||||
Map<String, Date> updated = Maps.newLinkedHashMap();
|
Map<String, Date> updated = Maps.newLinkedHashMap();
|
||||||
Map<String, Boolean> connectionLogging = Maps.newLinkedHashMap();
|
Map<String, Boolean> contentCaching = Maps.newLinkedHashMap();
|
||||||
|
SSLTermination sslTermination;
|
||||||
|
SourceAddresses sourceAddresses;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
|
||||||
.name("sample-loadbalancer")
|
.name("sample-loadbalancer")
|
||||||
.protocol("HTTP")
|
.protocol("HTTP")
|
||||||
.port(80)
|
.port(80)
|
||||||
.algorithm(LoadBalancer.Algorithm.RANDOM.name())
|
.algorithm(LoadBalancer.Algorithm.RANDOM)
|
||||||
.virtualIPType(VirtualIP.Type.PUBLIC)
|
.virtualIPType(VirtualIP.Type.PUBLIC)
|
||||||
.nodes(nodeRequests)
|
.nodes(nodeRequests)
|
||||||
.build();
|
.build();
|
||||||
|
@ -125,7 +125,7 @@ public class LoadBalancerApiExpectTest extends BaseCloudLoadBalancerApiExpectTes
|
||||||
.name("foo")
|
.name("foo")
|
||||||
.protocol("HTTPS")
|
.protocol("HTTPS")
|
||||||
.port(443)
|
.port(443)
|
||||||
.algorithm(LoadBalancer.Algorithm.RANDOM.name());
|
.algorithm(LoadBalancer.Algorithm.RANDOM);
|
||||||
|
|
||||||
api.update(2000, lbAttrs);
|
api.update(2000, lbAttrs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class LoadBalancerApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
assertEquals(lb.getRegion(), region);
|
assertEquals(lb.getRegion(), region);
|
||||||
assertEquals(lb.getName(), name);
|
assertEquals(lb.getName(), name);
|
||||||
assertEquals(lb.getProtocol(), "HTTP");
|
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);
|
assertEquals(Iterables.get(lb.getVirtualIPs(), 0).getType(), Type.PUBLIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
NodeRequest nodeRequest2 = NodeRequest.builder()
|
NodeRequest nodeRequest2 = NodeRequest.builder()
|
||||||
.address("10.1.1.2")
|
.address("10.1.1.2")
|
||||||
.condition(NodeRequest.Condition.ENABLED)
|
.condition(NodeRequest.Condition.ENABLED)
|
||||||
|
.type(Node.Type.SECONDARY)
|
||||||
.port(80)
|
.port(80)
|
||||||
.weight(8)
|
.weight(8)
|
||||||
.build();
|
.build();
|
||||||
|
@ -119,6 +120,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
|
|
||||||
NodeAttributes nodeAttributes = NodeAttributes.Builder
|
NodeAttributes nodeAttributes = NodeAttributes.Builder
|
||||||
.condition(NodeRequest.Condition.DISABLED)
|
.condition(NodeRequest.Condition.DISABLED)
|
||||||
|
.type(NodeRequest.Type.SECONDARY)
|
||||||
.weight(20);
|
.weight(20);
|
||||||
|
|
||||||
api.update(410, nodeAttributes);
|
api.update(410, nodeAttributes);
|
||||||
|
@ -156,6 +158,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
.address("10.1.1.1")
|
.address("10.1.1.1")
|
||||||
.port(80)
|
.port(80)
|
||||||
.condition(Node.Condition.ENABLED)
|
.condition(Node.Condition.ENABLED)
|
||||||
|
.type(Node.Type.PRIMARY)
|
||||||
.status(Node.Status.ONLINE)
|
.status(Node.Status.ONLINE)
|
||||||
.weight(3)
|
.weight(3)
|
||||||
.build();
|
.build();
|
||||||
|
@ -165,6 +168,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
.address("10.1.1.2")
|
.address("10.1.1.2")
|
||||||
.port(80)
|
.port(80)
|
||||||
.condition(Node.Condition.ENABLED)
|
.condition(Node.Condition.ENABLED)
|
||||||
|
.type(Node.Type.SECONDARY)
|
||||||
.status(Node.Status.ONLINE)
|
.status(Node.Status.ONLINE)
|
||||||
.weight(8)
|
.weight(8)
|
||||||
.build();
|
.build();
|
||||||
|
@ -174,6 +178,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
.address("10.1.1.3")
|
.address("10.1.1.3")
|
||||||
.port(80)
|
.port(80)
|
||||||
.condition(Node.Condition.DISABLED)
|
.condition(Node.Condition.DISABLED)
|
||||||
|
.type(Node.Type.PRIMARY)
|
||||||
.status(Node.Status.ONLINE)
|
.status(Node.Status.ONLINE)
|
||||||
.weight(12)
|
.weight(12)
|
||||||
.build();
|
.build();
|
||||||
|
@ -187,6 +192,7 @@ public class NodeApiExpectTest extends BaseCloudLoadBalancerApiExpectTest<CloudL
|
||||||
.address("10.1.1.1")
|
.address("10.1.1.1")
|
||||||
.port(80)
|
.port(80)
|
||||||
.condition(Node.Condition.ENABLED)
|
.condition(Node.Condition.ENABLED)
|
||||||
|
.type(Node.Type.PRIMARY)
|
||||||
.status(Node.Status.ONLINE)
|
.status(Node.Status.ONLINE)
|
||||||
.weight(12)
|
.weight(12)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -114,7 +114,7 @@ public class NodeApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
assert n.getAddress() != null : n;
|
assert n.getAddress() != null : n;
|
||||||
assert n.getPort() != -1 : n;
|
assert n.getPort() != -1 : n;
|
||||||
assert n.getStatus() != null : n;
|
assert n.getStatus() != null : n;
|
||||||
assert !Arrays.asList(LoadBalancer.WEIGHTED_ALGORITHMS).contains(lb.getTypedAlgorithm())
|
assert !Arrays.asList(LoadBalancer.WEIGHTED_ALGORITHMS).contains(lb.getAlgorithm())
|
||||||
|| n.getWeight() != null : n;
|
|| n.getWeight() != null : n;
|
||||||
|
|
||||||
Node getDetails = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).get(n.getId());
|
Node getDetails = clbApi.getNodeApiForZoneAndLoadBalancer(lb.getRegion(), lb.getId()).get(n.getId());
|
||||||
|
@ -125,7 +125,7 @@ public class NodeApiLiveTest extends BaseCloudLoadBalancersApiLiveTest {
|
||||||
assertEquals(getDetails.getAddress(), n.getAddress());
|
assertEquals(getDetails.getAddress(), n.getAddress());
|
||||||
assertEquals(getDetails.getPort(), n.getPort());
|
assertEquals(getDetails.getPort(), n.getPort());
|
||||||
assertEquals(getDetails.getStatus(), n.getStatus());
|
assertEquals(getDetails.getStatus(), n.getStatus());
|
||||||
if (Arrays.asList(LoadBalancer.WEIGHTED_ALGORITHMS).contains(lb.getTypedAlgorithm())) {
|
if (Arrays.asList(LoadBalancer.WEIGHTED_ALGORITHMS).contains(lb.getAlgorithm())) {
|
||||||
assertEquals(getDetails.getWeight(), n.getWeight());
|
assertEquals(getDetails.getWeight(), n.getWeight());
|
||||||
}
|
}
|
||||||
} catch (AssertionError e) {
|
} catch (AssertionError e) {
|
||||||
|
|
|
@ -21,13 +21,20 @@ package org.jclouds.rackspace.cloudloadbalancers.functions;
|
||||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.json.BaseItemParserTest;
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
|
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.HealthMonitor.Type;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
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.LoadBalancer.Status;
|
||||||
|
import org.jclouds.rackspace.cloudloadbalancers.domain.Metadata;
|
||||||
|
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.VirtualIP.IPVersion;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP.IPVersion;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.functions.ConvertLB;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer.Algorithm;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.functions.ParseLoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.internal.BaseLoadBalancer.SessionPersistenceType;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -57,19 +64,32 @@ public class ParseLoadBalancerTest extends BaseItemParserTest<LoadBalancer> {
|
||||||
.name("sample-loadbalancer")
|
.name("sample-loadbalancer")
|
||||||
.protocol("HTTP")
|
.protocol("HTTP")
|
||||||
.port(80)
|
.port(80)
|
||||||
.algorithm("RANDOM")
|
.algorithm(Algorithm.RANDOM)
|
||||||
.status(Status.ACTIVE)
|
.status(Status.ACTIVE)
|
||||||
.connectionLoggingEnabled(true)
|
.connectionLogging(true)
|
||||||
|
.contentCaching(true)
|
||||||
.nodeCount(2)
|
.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(
|
.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(
|
.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(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()))
|
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")
|
.clusterName("c1.dfw1")
|
||||||
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:42Z"))
|
.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.<Metadata> 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
|
// add factory binding as this is not default
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.json.BaseIterableWithMarkerParserTest;
|
import org.jclouds.json.BaseIterableWithMarkerParserTest;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer;
|
||||||
import org.jclouds.rackspace.cloudloadbalancers.domain.LoadBalancer.Status;
|
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.jclouds.rackspace.cloudloadbalancers.domain.VirtualIP;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ public class ParseLoadBalancersTest extends BaseIterableWithMarkerParserTest<Loa
|
||||||
.id(71)
|
.id(71)
|
||||||
.protocol("HTTP")
|
.protocol("HTTP")
|
||||||
.port(80)
|
.port(80)
|
||||||
.algorithm("RANDOM")
|
.algorithm(Algorithm.RANDOM)
|
||||||
.status(Status.ACTIVE)
|
.status(Status.ACTIVE)
|
||||||
.nodeCount(1)
|
.nodeCount(1)
|
||||||
.virtualIPs(ImmutableSet.of(
|
.virtualIPs(ImmutableSet.of(
|
||||||
|
@ -67,7 +68,7 @@ public class ParseLoadBalancersTest extends BaseIterableWithMarkerParserTest<Loa
|
||||||
.id(166)
|
.id(166)
|
||||||
.protocol("HTTP")
|
.protocol("HTTP")
|
||||||
.port(80)
|
.port(80)
|
||||||
.algorithm("RANDOM")
|
.algorithm(Algorithm.RANDOM)
|
||||||
.status(Status.ACTIVE)
|
.status(Status.ACTIVE)
|
||||||
.nodeCount(1)
|
.nodeCount(1)
|
||||||
.virtualIPs(ImmutableSet.of(
|
.virtualIPs(ImmutableSet.of(
|
||||||
|
|
|
@ -1,25 +1 @@
|
||||||
{
|
{"loadBalancer":{"virtualIps":[{"type":"PUBLIC"}],"name":"sample-loadbalancer","protocol":"HTTP","port":80,"algorithm":"RANDOM","nodes":[{"address":"10.1.1.1","port":80,"condition":"ENABLED"},{"address":"10.1.1.2","port":80,"condition":"ENABLED"}]}}
|
||||||
"loadBalancer": {
|
|
||||||
"virtualIps": [
|
|
||||||
{
|
|
||||||
"type": "PUBLIC"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name": "sample-loadbalancer",
|
|
||||||
"protocol": "HTTP",
|
|
||||||
"port": 80,
|
|
||||||
"algorithm": "RANDOM",
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"address": "10.1.1.1",
|
|
||||||
"port": 80,
|
|
||||||
"condition": "ENABLED"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"address": "10.1.1.2",
|
|
||||||
"port": 80,
|
|
||||||
"condition": "ENABLED"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +1,105 @@
|
||||||
{
|
{
|
||||||
"loadBalancer":{
|
"loadBalancer": {
|
||||||
"id": 2000,
|
"id": 2000,
|
||||||
"name":"sample-loadbalancer",
|
"name": "sample-loadbalancer",
|
||||||
"protocol":"HTTP",
|
"protocol": "HTTP",
|
||||||
"port": 80,
|
"port": 80,
|
||||||
"algorithm":"RANDOM",
|
"algorithm": "RANDOM",
|
||||||
"status":"ACTIVE",
|
"status": "ACTIVE",
|
||||||
"connectionLogging":{
|
"cluster": {
|
||||||
"enabled":"true"
|
"name": "c1.dfw1"
|
||||||
},
|
},
|
||||||
"virtualIps":[
|
"nodes": [
|
||||||
{
|
|
||||||
"id": 1000,
|
|
||||||
"address":"206.10.10.210",
|
|
||||||
"type":"PUBLIC",
|
|
||||||
"ipVersion":"IPV4"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nodes":[
|
|
||||||
{
|
{
|
||||||
"id": 1041,
|
"id": 1041,
|
||||||
"address":"10.1.1.1",
|
"address": "10.1.1.1",
|
||||||
"port": 80,
|
"port": 80,
|
||||||
"condition":"ENABLED",
|
"condition": "ENABLED",
|
||||||
"status":"ONLINE"
|
"status": "ONLINE"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 1411,
|
"id": 1411,
|
||||||
"address":"10.1.1.2",
|
"address": "10.1.1.2",
|
||||||
"port": 80,
|
"port": 80,
|
||||||
"condition":"ENABLED",
|
"condition": "ENABLED",
|
||||||
"status":"ONLINE"
|
"status": "ONLINE"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sessionPersistence":{
|
"created": {
|
||||||
"persistenceType":"HTTP_COOKIE"
|
"time": "2010-11-30T03:23:42Z"
|
||||||
},
|
},
|
||||||
"connectionThrottle":{
|
"healthMonitor": {
|
||||||
|
"type": "CONNECT",
|
||||||
|
"delay": 10,
|
||||||
|
"timeout": 5,
|
||||||
|
"attemptsBeforeDeactivation": 2
|
||||||
|
},
|
||||||
|
"sslTermination": {
|
||||||
|
"enabled": true,
|
||||||
|
"secureTrafficOnly": false,
|
||||||
|
"securePort": 443
|
||||||
|
},
|
||||||
|
"sessionPersistence": {
|
||||||
|
"persistenceType": "HTTP_COOKIE"
|
||||||
|
},
|
||||||
|
"virtualIps": [
|
||||||
|
{
|
||||||
|
"id": 1000,
|
||||||
|
"address": "206.10.10.210",
|
||||||
|
"type": "PUBLIC",
|
||||||
|
"ipVersion": "IPV4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 1001,
|
||||||
|
"address": "2001:4800:7901:0000:9a32:3c2a:0000:0001",
|
||||||
|
"type": "PUBLIC",
|
||||||
|
"ipVersion": "IPV6"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sourceAddresses": {
|
||||||
|
"ipv6Public": "2001:4800:7901::5/64",
|
||||||
|
"ipv4Servicenet": "10.183.250.137",
|
||||||
|
"ipv4Public": "174.143.139.137"
|
||||||
|
},
|
||||||
|
"updated": {
|
||||||
|
"time": "2010-11-30T03:23:44Z"
|
||||||
|
},
|
||||||
|
"halfClosed": false,
|
||||||
|
"accessList": [
|
||||||
|
{
|
||||||
|
"address": "1.2.3.4/32",
|
||||||
|
"id": 22215,
|
||||||
|
"type": "DENY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "12.0.0.0/8",
|
||||||
|
"id": 22217,
|
||||||
|
"type": "ALLOW"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connectionThrottle": {
|
||||||
"minConnections": 10,
|
"minConnections": 10,
|
||||||
"maxConnections": 100,
|
"maxConnections": 100,
|
||||||
"maxConnectionRate": 50,
|
"maxConnectionRate": 50,
|
||||||
"rateInterval": 60
|
"rateInterval": 60
|
||||||
},
|
},
|
||||||
"cluster":{
|
"connectionLogging": {
|
||||||
"name":"c1.dfw1"
|
"enabled": true
|
||||||
},
|
},
|
||||||
"created":{
|
"contentCaching": {
|
||||||
"time":"2010-11-30T03:23:42Z"
|
"enabled": true
|
||||||
},
|
},
|
||||||
"updated":{
|
"metadata": [
|
||||||
"time":"2010-11-30T03:23:44Z"
|
{
|
||||||
}
|
"id": 1,
|
||||||
|
"key": "color",
|
||||||
|
"value": "red"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"key": "label",
|
||||||
|
"value": "web-load-balancer"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1 @@
|
||||||
{
|
{"loadBalancer":{"name":"foo","protocol":"HTTPS","port":443,"algorithm":"RANDOM"}}
|
||||||
"loadBalancer": {
|
|
||||||
"name": "foo",
|
|
||||||
"protocol": "HTTPS",
|
|
||||||
"port": 443,
|
|
||||||
"algorithm": "RANDOM"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,23 @@
|
||||||
{"node": {
|
{
|
||||||
"id":410,
|
"node": {
|
||||||
"address":"10.1.1.1",
|
"id": 410,
|
||||||
"port":80,
|
"address": "10.1.1.1",
|
||||||
"condition":"ENABLED",
|
"port": 80,
|
||||||
"status":"ONLINE",
|
"condition": "ENABLED",
|
||||||
"weight":12,
|
"status": "ONLINE",
|
||||||
"type":"PRIMARY",
|
"weight": 12,
|
||||||
"metadata":[]
|
"type": "PRIMARY",
|
||||||
|
"metadata": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"key": "color",
|
||||||
|
"value": "red"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"key": "label",
|
||||||
|
"value": "web-load-balancer"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1 +1 @@
|
||||||
{"node":{"condition":"DISABLED","weight":20}}
|
{"node":{"condition":"DISABLED","type":"SECONDARY","weight":20}}
|
|
@ -1 +1 @@
|
||||||
{"nodes":[{"address":"10.1.1.1","port":80,"condition":"ENABLED","weight":3},{"address":"10.1.1.2","port":80,"condition":"ENABLED","weight":8},{"address":"10.1.1.3","port":80,"condition":"DISABLED","weight":12}]}
|
{"nodes":[{"address":"10.1.1.1","port":80,"condition":"ENABLED","weight":3},{"address":"10.1.1.2","port":80,"condition":"ENABLED","type":"SECONDARY","weight":8},{"address":"10.1.1.3","port":80,"condition":"DISABLED","weight":12}]}
|
Loading…
Reference in New Issue