mirror of https://github.com/apache/jclouds.git
algorithm can be null when lb is deleted
This commit is contained in:
parent
1680931776
commit
0068fbbd63
|
@ -34,6 +34,7 @@ import org.jclouds.cloudloadbalancers.features.LoadBalancerAsyncClient;
|
|||
import org.jclouds.cloudloadbalancers.features.LoadBalancerClient;
|
||||
import org.jclouds.cloudloadbalancers.features.NodeAsyncClient;
|
||||
import org.jclouds.cloudloadbalancers.features.NodeClient;
|
||||
import org.jclouds.cloudloadbalancers.functions.ConvertLB;
|
||||
import org.jclouds.cloudloadbalancers.handlers.ParseCloudLoadBalancersErrorFromHttpResponse;
|
||||
import org.jclouds.cloudloadbalancers.reference.RackspaceConstants;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
|
@ -63,6 +64,7 @@ import com.google.inject.Injector;
|
|||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
|
||||
/**
|
||||
* Configures theRackspace Cloud Load Balancers connection.
|
||||
|
@ -109,6 +111,7 @@ public class CloudLoadBalancersRestClientModule extends
|
|||
install(new OpenStackAuthenticationModule());
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
bindRegionsToProvider();
|
||||
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
|
||||
super.configure();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Date;
|
|||
import java.util.Set;
|
||||
|
||||
import org.jclouds.cloudloadbalancers.domain.internal.BaseLoadBalancer;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
|
@ -77,8 +78,8 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
|||
}
|
||||
|
||||
public Builder algorithm(Algorithm algorithm) {
|
||||
algorithm(algorithm.name());
|
||||
return this;
|
||||
algorithm(algorithm.name());
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder virtualIPs(Iterable<VirtualIP> virtualIPs) {
|
||||
|
@ -214,49 +215,48 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
|||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
* 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,
|
||||
LEAST_CONNECTIONS,
|
||||
/**
|
||||
* Back-end servers are selected at random.
|
||||
*/
|
||||
RANDOM,
|
||||
RANDOM,
|
||||
/**
|
||||
* Connections are routed to each of the back-end servers in turn.
|
||||
*/
|
||||
ROUND_ROBIN,
|
||||
ROUND_ROBIN,
|
||||
/**
|
||||
* Each request will be assigned to a node based on the number of concurrent connections
|
||||
* to the node and its weight.
|
||||
* Each request will be assigned to a node based on the number of concurrent connections to
|
||||
* the node and its weight.
|
||||
*/
|
||||
WEIGHTED_LEAST_CONNECTIONS,
|
||||
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.
|
||||
* 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;
|
||||
WEIGHTED_ROUND_ROBIN, UNRECOGNIZED;
|
||||
|
||||
public static Algorithm fromValue(String status) {
|
||||
public static Algorithm fromValue(String algorithm) {
|
||||
try {
|
||||
return valueOf(checkNotNull(status, "status"));
|
||||
return valueOf(checkNotNull(algorithm, "algorithm"));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Algorithm[] WEIGHTED_ALGORITHMS = {Algorithm.WEIGHTED_LEAST_CONNECTIONS,
|
||||
Algorithm.WEIGHTED_ROUND_ROBIN};
|
||||
public static Algorithm[] WEIGHTED_ALGORITHMS = { Algorithm.WEIGHTED_LEAST_CONNECTIONS,
|
||||
Algorithm.WEIGHTED_ROUND_ROBIN };
|
||||
|
||||
private final String region;
|
||||
private final int id;
|
||||
|
@ -269,15 +269,15 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
|||
private final Date updated;
|
||||
private final boolean connectionLoggingEnabled;
|
||||
|
||||
public LoadBalancer(String region, int id, String name, String protocol, Integer port, String algorithm, Status status,
|
||||
Iterable<VirtualIP> virtualIPs, Iterable<Node> nodes, String sessionPersistenceType, String clusterName,
|
||||
Date created, Date updated, boolean connectionLoggingEnabled) {
|
||||
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) {
|
||||
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.fromValue(algorithm);
|
||||
this.algorithm = algorithm != null ? Algorithm.fromValue(algorithm) : null;
|
||||
this.virtualIPs = ImmutableSet.copyOf(checkNotNull(virtualIPs, "virtualIPs"));
|
||||
this.sessionPersistenceType = sessionPersistenceType;
|
||||
this.clusterName = clusterName;
|
||||
|
@ -298,8 +298,13 @@ public class LoadBalancer extends BaseLoadBalancer<Node, LoadBalancer> {
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return algorithm, which may be null if the load balancer is deleted
|
||||
*/
|
||||
@Nullable
|
||||
public Algorithm getTypedAlgorithm() {
|
||||
return algorithm;
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public Set<VirtualIP> getVirtualIPs() {
|
||||
|
|
|
@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
@ -107,7 +109,7 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
|||
// so tests will come out consistently
|
||||
protected SortedSet<N> nodes = ImmutableSortedSet.of();
|
||||
|
||||
public BaseLoadBalancer(String name, String protocol, Integer port, String algorithm, Iterable<N> nodes) {
|
||||
public BaseLoadBalancer(String name, String protocol, Integer port, @Nullable String algorithm, Iterable<N> nodes) {
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.protocol = protocol;// null on deleted LB
|
||||
this.port = port;// null on deleted LB
|
||||
|
@ -132,6 +134,11 @@ public class BaseLoadBalancer<N extends BaseNode<N>, T extends BaseLoadBalancer<
|
|||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return algorithm, which may be null if the load balancer is deleted
|
||||
*/
|
||||
@Nullable
|
||||
public String getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
|
|
@ -18,39 +18,57 @@
|
|||
*/
|
||||
package org.jclouds.cloudloadbalancers.functions;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
|
||||
import org.jclouds.cloudloadbalancers.domain.LoadBalancer.Builder;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ConvertLB implements Function<LB, LoadBalancer> {
|
||||
|
||||
public static interface Factory {
|
||||
ConvertLB createForRegion(String region);
|
||||
}
|
||||
|
||||
@Resource
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final String region;
|
||||
|
||||
ConvertLB(String region) {
|
||||
@Inject
|
||||
ConvertLB(@Assisted String region) {
|
||||
this.region = region.toUpperCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancer apply(LB lb) {
|
||||
Builder builder = LoadBalancer.builder().region(region).name(lb.getName()).port(lb.getPort()).protocol(
|
||||
lb.getProtocol()).algorithm(lb.getAlgorithm()).nodes(lb.getNodes()).id(lb.id).status(lb.status)
|
||||
.virtualIPs(lb.virtualIps);
|
||||
if (lb.cluster.size() == 1)
|
||||
builder.clusterName(Iterables.get(lb.cluster.values(), 0));
|
||||
if (lb.sessionPersistence.size() == 1)
|
||||
builder.sessionPersistenceType(Iterables.get(lb.sessionPersistence.values(), 0));
|
||||
if (lb.created.size() == 1)
|
||||
builder.created(Iterables.get(lb.created.values(), 0));
|
||||
if (lb.updated.size() == 1)
|
||||
builder.updated(Iterables.get(lb.updated.values(), 0));
|
||||
if (lb.connectionLogging.size() == 1)
|
||||
builder.connectionLoggingEnabled(Iterables.get(lb.connectionLogging.values(), 0));
|
||||
return builder.build();
|
||||
try {
|
||||
Builder builder = LoadBalancer.builder().region(region).name(lb.getName()).port(lb.getPort()).protocol(
|
||||
lb.getProtocol()).algorithm(lb.getAlgorithm()).nodes(lb.getNodes()).id(lb.id).status(lb.status)
|
||||
.virtualIPs(lb.virtualIps);
|
||||
if (lb.cluster.size() == 1)
|
||||
builder.clusterName(Iterables.get(lb.cluster.values(), 0));
|
||||
if (lb.sessionPersistence.size() == 1)
|
||||
builder.sessionPersistenceType(Iterables.get(lb.sessionPersistence.values(), 0));
|
||||
if (lb.created.size() == 1)
|
||||
builder.created(Iterables.get(lb.created.values(), 0));
|
||||
if (lb.updated.size() == 1)
|
||||
builder.updated(Iterables.get(lb.updated.values(), 0));
|
||||
if (lb.connectionLogging.size() == 1)
|
||||
builder.connectionLoggingEnabled(Iterables.get(lb.connectionLogging.values(), 0));
|
||||
return builder.build();
|
||||
} catch (NullPointerException e) {
|
||||
logger.warn(e, "nullpointer found parsing %s", lb);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -18,11 +18,15 @@
|
|||
*/
|
||||
package org.jclouds.cloudloadbalancers.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
|
||||
import org.jclouds.cloudloadbalancers.functions.ConvertLB.Factory;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
|
@ -37,15 +41,19 @@ import com.google.common.collect.Iterables;
|
|||
public class UnwrapLoadBalancer implements Function<HttpResponse, LoadBalancer>, InvocationContext<UnwrapLoadBalancer> {
|
||||
|
||||
private final ParseJson<Map<String, LB>> json;
|
||||
private final Factory factory;
|
||||
|
||||
private ConvertLB convertLB;
|
||||
|
||||
@Inject
|
||||
UnwrapLoadBalancer(ParseJson<Map<String, LB>> json) {
|
||||
this.json = json;
|
||||
UnwrapLoadBalancer(ParseJson<Map<String, LB>> json, ConvertLB.Factory factory) {
|
||||
this.json = checkNotNull(json, "json");
|
||||
this.factory = checkNotNull(factory, "factory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancer apply(HttpResponse arg0) {
|
||||
checkState(convertLB != null, "convertLB should be set by InvocationContext");
|
||||
Map<String, LB> map = json.apply(arg0);
|
||||
if (map == null || map.size() == 0)
|
||||
return null;
|
||||
|
@ -59,7 +67,7 @@ public class UnwrapLoadBalancer implements Function<HttpResponse, LoadBalancer>,
|
|||
}
|
||||
|
||||
UnwrapLoadBalancer setRegion(String region) {
|
||||
this.convertLB = new ConvertLB(region);
|
||||
this.convertLB = factory.createForRegion(region);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,15 @@
|
|||
*/
|
||||
package org.jclouds.cloudloadbalancers.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
|
||||
import org.jclouds.cloudloadbalancers.functions.ConvertLB.Factory;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
|
@ -40,11 +43,14 @@ public class UnwrapLoadBalancers implements Function<HttpResponse, Set<LoadBalan
|
|||
InvocationContext<UnwrapLoadBalancers> {
|
||||
|
||||
private final ParseJson<Map<String, Set<LB>>> json;
|
||||
private final Factory factory;
|
||||
|
||||
private ConvertLB convertLB;
|
||||
|
||||
@Inject
|
||||
UnwrapLoadBalancers(ParseJson<Map<String, Set<LB>>> json) {
|
||||
this.json = json;
|
||||
UnwrapLoadBalancers(ParseJson<Map<String, Set<LB>>> json, ConvertLB.Factory factory) {
|
||||
this.json = checkNotNull(json, "json");
|
||||
this.factory = checkNotNull(factory, "factory");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,7 +68,7 @@ public class UnwrapLoadBalancers implements Function<HttpResponse, Set<LoadBalan
|
|||
}
|
||||
|
||||
UnwrapLoadBalancers setRegion(String region) {
|
||||
this.convertLB = new ConvertLB(region);
|
||||
this.convertLB = factory.createForRegion(region);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,13 +30,15 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
@Test(groups = "unit", testName = "UnwrapLoadBalancerTest")
|
||||
public class UnwrapLoadBalancerTest extends BaseItemParserTest<LoadBalancer> {
|
||||
|
||||
@Override
|
||||
|
@ -67,6 +69,20 @@ public class UnwrapLoadBalancerTest extends BaseItemParserTest<LoadBalancer> {
|
|||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-11-30T03:23:44Z")).build();
|
||||
}
|
||||
|
||||
// add factory binding as this is not default
|
||||
@Override
|
||||
protected Injector injector() {
|
||||
return super.injector().createChildInjector(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<HttpResponse, LoadBalancer> parser(Injector i) {
|
||||
return i.getInstance(UnwrapLoadBalancer.class).setRegion("DFW");
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.cloudloadbalancers.functions;
|
||||
|
||||
import org.jclouds.cloudloadbalancers.domain.LoadBalancer;
|
||||
import org.jclouds.cloudloadbalancers.domain.LoadBalancer.Status;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "UnwrapLoadBalancerWhenDeletedTest")
|
||||
public class UnwrapLoadBalancerWhenDeletedTest extends BaseItemParserTest<LoadBalancer> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/getloadbalancer-deleted.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancer expected() {
|
||||
return LoadBalancer.builder().region("LON").id(4865).name("adriancole-LON").status(Status.DELETED).created(
|
||||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-12-05T18:03:23Z")).updated(
|
||||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-12-05T18:04:04Z")).build();
|
||||
}
|
||||
|
||||
// add factory binding as this is not default
|
||||
@Override
|
||||
protected Injector injector() {
|
||||
return super.injector().createChildInjector(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<HttpResponse, LoadBalancer> parser(Injector i) {
|
||||
return i.getInstance(UnwrapLoadBalancer.class).setRegion("LON");
|
||||
}
|
||||
}
|
|
@ -30,7 +30,9 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -64,6 +66,20 @@ public class UnwrapLoadBalancersTest extends BaseSetParserTest<LoadBalancer> {
|
|||
|
||||
}
|
||||
|
||||
// add factory binding as this is not default
|
||||
@Override
|
||||
protected Injector injector() {
|
||||
return super.injector().createChildInjector(new AbstractModule() {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(new FactoryModuleBuilder().build(ConvertLB.Factory.class));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<HttpResponse, Set<LoadBalancer>> parser(Injector i) {
|
||||
return i.getInstance(UnwrapLoadBalancers.class).setRegion("DFW");
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"loadBalancer":{"name":"adriancole-LON","id":4865,"status":"DELETED","created":{"time":"2011-12-05T18:03:23Z"},"updated":{"time":"2011-12-05T18:04:04Z"}}}
|
Loading…
Reference in New Issue