mirror of https://github.com/apache/jclouds.git
moved loadbalancerservice into its own module
This commit is contained in:
parent
ec0cd17270
commit
417cb3acf0
|
@ -1,74 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.aws.ec2;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.elb.ELBAsyncClient;
|
||||
import org.jclouds.aws.elb.ELBClient;
|
||||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ConfigureELBModule extends AbstractModule {
|
||||
private final Iterable<Module> infra;
|
||||
private final Properties properties;
|
||||
|
||||
ConfigureELBModule(Iterable<Module> infra, Properties properties) {
|
||||
this.infra = infra;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* setup ELB with the same parameters as EC2
|
||||
*/
|
||||
@Provides
|
||||
@Singleton
|
||||
ELBClient provideELBClient(Closer closer) {
|
||||
final RestContext<ELBClient, ELBAsyncClient> context = new RestContextFactory()
|
||||
.createContext("elb", infra, properties);
|
||||
closer.addToClose(new Closeable() {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (context != null)
|
||||
context.close();
|
||||
}
|
||||
|
||||
});
|
||||
return context.getApi();
|
||||
}
|
||||
}
|
|
@ -19,40 +19,28 @@
|
|||
|
||||
package org.jclouds.aws.ec2;
|
||||
|
||||
import static com.google.common.base.Predicates.instanceOf;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule;
|
||||
import org.jclouds.aws.ec2.compute.config.EC2ResolveImagesModule;
|
||||
import org.jclouds.aws.ec2.config.EC2RestClientModule;
|
||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
||||
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.logging.config.LoggingModule;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Creates {@link EC2ComputeServiceContext} or {@link Injector} instances based
|
||||
* on the most commonly requested arguments.
|
||||
* Creates {@link EC2ComputeServiceContext} or {@link Injector} instances based on the most commonly
|
||||
* requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or
|
||||
* Context provided.
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default
|
||||
* {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be
|
||||
* installed.
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @see EC2ComputeServiceContext
|
||||
|
@ -82,22 +70,4 @@ public class EC2ContextBuilder extends ComputeServiceContextBuilder<EC2Client, E
|
|||
protected void addImageResolutionModule() {
|
||||
modules.add(new EC2ResolveImagesModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Injector buildInjector() {
|
||||
try {
|
||||
Iterables.find(modules, Predicates.instanceOf(ConfigureELBModule.class));
|
||||
} catch (NoSuchElementException e) {
|
||||
Iterable<Module> infra = Iterables.filter(modules, new Predicate<Module>() {
|
||||
public boolean apply(Module input) {
|
||||
return input.getClass().isAnnotationPresent(ConfiguresExecutorService.class)
|
||||
|| input.getClass().isAnnotationPresent(ConfiguresHttpCommandExecutorService.class)
|
||||
|| instanceOf(LoggingModule.class).apply(input);
|
||||
}
|
||||
|
||||
});
|
||||
modules.add(new ConfigureELBModule(infra, properties));
|
||||
}
|
||||
return super.buildInjector();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,15 +30,11 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.aws.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.aws.ec2.compute.domain.RegionAndName;
|
||||
import org.jclouds.aws.ec2.compute.strategy.EC2DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.aws.ec2.compute.strategy.EC2LoadBalanceNodesStrategy;
|
||||
import org.jclouds.aws.ec2.compute.suppliers.RegionAndNameToImageSupplier;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.compute.strategy.LoadBalanceNodesStrategy;
|
||||
import org.jclouds.rest.annotations.Provider;
|
||||
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||
|
||||
|
@ -85,9 +81,4 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindLoadBalancerService() {
|
||||
bind(LoadBalanceNodesStrategy.class).to(EC2LoadBalanceNodesStrategy.class);
|
||||
bind(DestroyLoadBalancerStrategy.class).to(EC2DestroyLoadBalancerStrategy.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,10 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.aws.elb.config.ELBRestClientModule;
|
||||
import org.jclouds.aws.elb.loadbalancer.config.ELBLoadBalancerContextModule;
|
||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||
import org.jclouds.loadbalancer.LoadBalancerServiceContextBuilder;
|
||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
@ -43,7 +44,12 @@ import com.google.inject.Module;
|
|||
* @author Adrian Cole
|
||||
* @see ELBContext
|
||||
*/
|
||||
public class ELBContextBuilder extends RestContextBuilder<ELBClient, ELBAsyncClient> {
|
||||
public class ELBContextBuilder extends LoadBalancerServiceContextBuilder<ELBClient, ELBAsyncClient> {
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new ELBLoadBalancerContextModule());
|
||||
}
|
||||
|
||||
public ELBContextBuilder(Properties props) {
|
||||
super(ELBClient.class, ELBAsyncClient.class, props);
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.aws.elb.loadbalancer.config;
|
||||
|
||||
import org.jclouds.aws.elb.loadbalancer.strategy.ELBDestroyLoadBalancerStrategy;
|
||||
import org.jclouds.aws.elb.loadbalancer.strategy.ELBLoadBalanceNodesStrategy;
|
||||
import org.jclouds.http.RequiresHttp;
|
||||
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
/**
|
||||
* Configures the ELB connection.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@RequiresHttp
|
||||
@ConfiguresRestClient
|
||||
public class ELBLoadBalancerContextModule extends AbstractModule {
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(LoadBalanceNodesStrategy.class).to(ELBLoadBalanceNodesStrategy.class);
|
||||
bind(DestroyLoadBalancerStrategy.class).to(ELBDestroyLoadBalancerStrategy.class);
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.ec2.compute.strategy;
|
||||
package org.jclouds.aws.elb.loadbalancer.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -30,8 +30,8 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.aws.elb.ELBClient;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
|
||||
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -39,15 +39,15 @@ import org.jclouds.logging.Logger;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class EC2DestroyLoadBalancerStrategy implements DestroyLoadBalancerStrategy {
|
||||
public class ELBDestroyLoadBalancerStrategy implements DestroyLoadBalancerStrategy {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final ELBClient elbClient;
|
||||
|
||||
@Inject
|
||||
protected EC2DestroyLoadBalancerStrategy(ELBClient elbClient) {
|
||||
protected ELBDestroyLoadBalancerStrategy(ELBClient elbClient) {
|
||||
this.elbClient = checkNotNull(elbClient, "elbClient");
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.ec2.compute.strategy;
|
||||
package org.jclouds.aws.elb.loadbalancer.strategy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -31,47 +31,60 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.aws.ec2.util.EC2Utils.GetRegionFromLocation;
|
||||
import org.jclouds.aws.elb.ELBClient;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.LoadBalanceNodesStrategy;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerType;
|
||||
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
|
||||
import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
|
||||
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class EC2LoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
|
||||
public class ELBLoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected final ELBClient elbClient;
|
||||
protected final GetRegionFromLocation getRegionFromLocation;
|
||||
|
||||
@Inject
|
||||
protected EC2LoadBalanceNodesStrategy(ELBClient elbClient,
|
||||
GetRegionFromLocation getRegionFromLocation) {
|
||||
protected ELBLoadBalanceNodesStrategy(ELBClient elbClient, GetRegionFromLocation getRegionFromLocation) {
|
||||
this.elbClient = elbClient;
|
||||
this.getRegionFromLocation = getRegionFromLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String execute(Location location, String name, String protocol, int loadBalancerPort,
|
||||
int instancePort, Set<String> instanceIds) {
|
||||
public LoadBalancerMetadata execute(Location location, String name, String protocol, int loadBalancerPort,
|
||||
int instancePort, Iterable<? extends NodeMetadata> nodes) {
|
||||
String region = getRegionFromLocation.apply(location);
|
||||
String dnsName = new String();
|
||||
|
||||
dnsName = elbClient.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort,
|
||||
instancePort, EC2Utils.getAvailabilityZonesForRegion(region));
|
||||
|
||||
List<String> instanceIdlist = new ArrayList<String>(instanceIds);
|
||||
String[] instanceIdArray = new String[instanceIdlist.size()];
|
||||
for (int i = 0; i < instanceIdlist.size(); i++) {
|
||||
instanceIdArray[i] = instanceIdlist.get(i);
|
||||
}
|
||||
dnsName = elbClient.createLoadBalancerInRegion(region, name, protocol, loadBalancerPort, instancePort,
|
||||
EC2Utils.getAvailabilityZonesForRegion(region));
|
||||
|
||||
Set<String> registeredInstanceIds = elbClient.registerInstancesWithLoadBalancerInRegion(
|
||||
region, name, instanceIdArray);
|
||||
List<String> instanceIds = Lists.newArrayList(Iterables.transform(nodes, new Function<NodeMetadata, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(NodeMetadata from) {
|
||||
return from.getProviderId();
|
||||
}
|
||||
}));
|
||||
|
||||
String[] instanceIdArray = instanceIds.toArray(new String[] {});
|
||||
|
||||
Set<String> registeredInstanceIds = elbClient.registerInstancesWithLoadBalancerInRegion(region, name,
|
||||
instanceIdArray);
|
||||
|
||||
// deregister instances
|
||||
boolean changed = registeredInstanceIds.removeAll(instanceIds);
|
||||
|
@ -85,6 +98,7 @@ public class EC2LoadBalanceNodesStrategy implements LoadBalanceNodesStrategy {
|
|||
elbClient.deregisterInstancesWithLoadBalancerInRegion(region, name, instanceIdArray);
|
||||
}
|
||||
|
||||
return dnsName;
|
||||
return new LoadBalancerMetadataImpl(LoadBalancerType.LB, dnsName, name, dnsName, location, null,
|
||||
ImmutableMap.<String, String> of(), ImmutableSet.of(dnsName));
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.aws.ec2.compute;
|
||||
package org.jclouds.aws.elb.loadbalancer;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
@ -29,32 +29,25 @@ import org.jclouds.aws.domain.Region;
|
|||
import org.jclouds.aws.elb.ELBAsyncClient;
|
||||
import org.jclouds.aws.elb.ELBClient;
|
||||
import org.jclouds.aws.elb.domain.LoadBalancer;
|
||||
import org.jclouds.compute.BaseLoadBalancerServiceLiveTest;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.loadbalancer.BaseLoadBalancerServiceLiveTest;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lili Nadar
|
||||
*/
|
||||
@Test(groups = "live", sequential = true)
|
||||
public class EC2LoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveTest {
|
||||
|
||||
private RestContext<ELBClient, ELBAsyncClient> elbContext;
|
||||
public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveTest {
|
||||
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setServiceDefaults() {
|
||||
provider = "ec2";
|
||||
provider = "elb";
|
||||
computeProvider = "ec2";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,20 +55,9 @@ public class EC2LoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveT
|
|||
return new JschSshClientModule();
|
||||
}
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupELBClient() {
|
||||
elbContext = new RestContextFactory().createContext("elb", identity, credential,
|
||||
ImmutableSet.of(new Log4JLoggingModule()));
|
||||
}
|
||||
|
||||
@AfterGroups(groups = { "live" })
|
||||
public void tearDownELBClient() {
|
||||
if (elbContext != null)
|
||||
elbContext.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateNodesInLoadBalancer() {
|
||||
RestContext<ELBClient, ELBAsyncClient> elbContext = context.getProviderSpecificContext();
|
||||
// TODO create a LoadBalancer object and an appropriate list method so that this
|
||||
// does not have to be EC2 specific code
|
||||
ELBClient elbClient = elbContext.getApi();
|
||||
|
@ -86,10 +68,9 @@ public class EC2LoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveT
|
|||
}
|
||||
Set<LoadBalancer> elbs = elbClient.describeLoadBalancersInRegion(Region.US_EAST_1);
|
||||
assertNotNull(elbs);
|
||||
for(LoadBalancer elb:elbs)
|
||||
{
|
||||
if(elb.getName().equals(tag))
|
||||
assertEquals(elb.getInstanceIds(), instanceIds);
|
||||
for (LoadBalancer elb : elbs) {
|
||||
if (elb.getName().equals(tag))
|
||||
assertEquals(elb.getInstanceIds(), instanceIds);
|
||||
}
|
||||
}
|
||||
}
|
12
aws/pom.xml
12
aws/pom.xml
|
@ -125,6 +125,18 @@
|
|||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-loadbalancer</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-loadbalancer</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
|
|
|
@ -40,12 +40,6 @@ public interface ComputeServiceContext {
|
|||
|
||||
ComputeService getComputeService();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return null, if the cloud does not support load balancer services
|
||||
*/
|
||||
LoadBalancerService getLoadBalancerService();
|
||||
|
||||
<S, A> RestContext<S, A> getProviderSpecificContext();
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,7 +30,6 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
@ -52,9 +51,7 @@ import com.google.common.collect.Maps;
|
|||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Providers;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -64,15 +61,10 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
install(new ComputeServiceTimeoutsModule());
|
||||
bindLoadBalancerService();
|
||||
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
|
||||
}).to(CreateSshClientOncePortIsListeningOnNode.class);
|
||||
}
|
||||
|
||||
protected void bindLoadBalancerService() {
|
||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null)).in(Scopes.SINGLETON);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Map<OsFamily, Map<String, String>> provideOsVersionMap(ComputeServiceConstants.ReferenceData data, Json json) {
|
||||
|
|
|
@ -23,13 +23,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.Utils;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
@ -40,7 +38,6 @@ import org.jclouds.rest.RestContext;
|
|||
@Singleton
|
||||
public class ComputeServiceContextImpl<S, A> implements ComputeServiceContext {
|
||||
private final ComputeService computeService;
|
||||
private final LoadBalancerService loadBalancerService;
|
||||
private final RestContext<S, A> providerSpecificContext;
|
||||
private final Utils utils;
|
||||
private final Map<String, Credentials> credentialStore;
|
||||
|
@ -48,13 +45,12 @@ public class ComputeServiceContextImpl<S, A> implements ComputeServiceContext {
|
|||
@SuppressWarnings({ "unchecked" })
|
||||
@Inject
|
||||
public ComputeServiceContextImpl(ComputeService computeService, Map<String, Credentials> credentialStore,
|
||||
Utils utils, @Nullable LoadBalancerService loadBalancerService,
|
||||
Utils utils,
|
||||
@SuppressWarnings("rawtypes") RestContext providerSpecificContext) {
|
||||
this.credentialStore = credentialStore;
|
||||
this.utils = utils;
|
||||
this.providerSpecificContext = providerSpecificContext;
|
||||
this.computeService = checkNotNull(computeService, "computeService");
|
||||
this.loadBalancerService = loadBalancerService;
|
||||
}
|
||||
|
||||
public ComputeService getComputeService() {
|
||||
|
@ -71,12 +67,7 @@ public class ComputeServiceContextImpl<S, A> implements ComputeServiceContext {
|
|||
public void close() {
|
||||
providerSpecificContext.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancerService getLoadBalancerService() {
|
||||
return loadBalancerService;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Utils getUtils() {
|
||||
return utils();
|
||||
|
|
|
@ -97,10 +97,6 @@ import com.google.inject.Module;
|
|||
@Test(groups = { "integration", "live" }, sequential = true)
|
||||
public abstract class BaseComputeServiceLiveTest {
|
||||
|
||||
public void setServiceDefaults() {
|
||||
|
||||
}
|
||||
|
||||
protected String tag;
|
||||
|
||||
protected RetryablePredicate<IPSocket> socketTester;
|
||||
|
@ -111,28 +107,12 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
protected Template template;
|
||||
protected Map<String, String> keyPair;
|
||||
|
||||
protected void buildSocketTester() {
|
||||
SocketOpen socketOpen = Guice.createInjector(getSshModule()).getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
protected void setupKeyPairForTest() throws FileNotFoundException, IOException {
|
||||
keyPair = ComputeTestUtils.setupKeyPair();
|
||||
}
|
||||
|
||||
protected String provider;
|
||||
protected String identity;
|
||||
protected String credential;
|
||||
protected String endpoint;
|
||||
protected String apiversion;
|
||||
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
}
|
||||
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
|
@ -158,6 +138,21 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
buildSocketTester();
|
||||
}
|
||||
|
||||
public void setServiceDefaults() {
|
||||
|
||||
}
|
||||
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
}
|
||||
|
||||
protected void setupKeyPairForTest() throws FileNotFoundException, IOException {
|
||||
keyPair = ComputeTestUtils.setupKeyPair();
|
||||
}
|
||||
|
||||
private void initializeContextAndClient() throws IOException {
|
||||
if (context != null)
|
||||
context.close();
|
||||
|
@ -171,6 +166,11 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
return RestContextFactory.getPropertiesFromResource("/rest.properties");
|
||||
}
|
||||
|
||||
protected void buildSocketTester() {
|
||||
SocketOpen socketOpen = Guice.createInjector(getSshModule()).getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
abstract protected Module getSshModule();
|
||||
|
||||
// wait up to 5 seconds for an auth exception
|
||||
|
@ -474,7 +474,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
|
||||
template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
|
||||
.build();
|
||||
|
||||
|
||||
// note this is a dependency on the template resolution
|
||||
template.getOptions().runScript(
|
||||
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true)
|
||||
public abstract class BaseLoadBalancerServiceLiveTest {
|
||||
@BeforeClass
|
||||
abstract public void setServiceDefaults();
|
||||
|
||||
protected String provider;
|
||||
protected SshClient.Factory sshFactory;
|
||||
protected String tag;
|
||||
|
||||
protected RetryablePredicate<IPSocket> socketTester;
|
||||
protected SortedSet<NodeMetadata> nodes;
|
||||
protected ComputeServiceContext context;
|
||||
protected ComputeService client;
|
||||
protected LoadBalancerService lbClient;
|
||||
protected String identity;
|
||||
protected String credential;
|
||||
protected Template template;
|
||||
protected Map<String, String> keyPair;
|
||||
protected Set<String> loadbalancers;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException, RunNodesException {
|
||||
if (tag == null)
|
||||
tag = checkNotNull(provider, "provider") + "lb";
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + ".credential");
|
||||
|
||||
initializeContextAndClient();
|
||||
|
||||
Injector injector = Guice.createInjector(getSshModule());
|
||||
sshFactory = injector.getInstance(SshClient.Factory.class);
|
||||
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
injector.injectMembers(socketOpen); // add logger
|
||||
|
||||
Template template = client.templateBuilder().build();
|
||||
|
||||
nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
|
||||
}
|
||||
|
||||
private void initializeContextAndClient() throws IOException {
|
||||
if (context != null)
|
||||
context.close();
|
||||
context = new ComputeServiceContextFactory().createContext(provider, identity, credential,
|
||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()));
|
||||
client = context.getComputeService();
|
||||
lbClient = context.getLoadBalancerService();
|
||||
}
|
||||
|
||||
abstract protected Module getSshModule();
|
||||
|
||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||
return templateBuilder.build();
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testLoadBalanceNodesMatching() throws Exception {
|
||||
|
||||
// create load balancers
|
||||
loadbalancers = lbClient.loadBalanceNodesMatching(NodePredicates.withTag(tag), tag, "HTTP",
|
||||
80, 80);
|
||||
assertNotNull(loadbalancers);
|
||||
validateNodesInLoadBalancer();
|
||||
|
||||
}
|
||||
|
||||
// TODO create a LoadBalancerService method for this.
|
||||
protected abstract void validateNodesInLoadBalancer();
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testLoadBalanceNodesMatching")
|
||||
public void testDestroyLoadBalancers() throws Exception {
|
||||
for (String lb : loadbalancers) {
|
||||
lbClient.destroyLoadBalancer(lb);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (nodes != null) {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
for (NodeMetadata node : Iterables.filter(client.listNodesDetailsMatching(NodePredicates
|
||||
.all()), NodePredicates.withTag(tag))) {
|
||||
assert node.getState() == NodeState.TERMINATED : node;
|
||||
}
|
||||
}
|
||||
if (loadbalancers != null) {
|
||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
for (NodeMetadata node : Iterables.filter(client.listNodesDetailsMatching(NodePredicates
|
||||
.all()), NodePredicates.withTag(tag))) {
|
||||
assert node.getState() == NodeState.TERMINATED : node;
|
||||
}
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,6 @@ package org.jclouds.gogrid.compute.config;
|
|||
|
||||
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
||||
|
||||
|
||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
|
||||
====================================================================
|
||||
Licensed 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.
|
||||
====================================================================
|
||||
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-project</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../project/pom.xml</relativePath>
|
||||
</parent>
|
||||
<artifactId>jclouds-loadbalancer</artifactId>
|
||||
<name>jclouds loadbalancer core</name>
|
||||
<description>jclouds components to access loadbalancer providers</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/loadbalancer</connection>
|
||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/loadbalancer</developerConnection>
|
||||
<url>http://jclouds.googlecode.com/svn/trunk/loadbalancer</url>
|
||||
</scm>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-compute</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jclouds-log4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.14</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -17,15 +17,18 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.compute;
|
||||
package org.jclouds.loadbalancer;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.internal.BaseLoadBalancerService;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
|
||||
import org.jclouds.loadbalancer.internal.BaseLoadBalancerService;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
|
@ -40,11 +43,11 @@ public interface LoadBalancerService {
|
|||
/**
|
||||
* @return a reference to the context that created this LoadBalancerService.
|
||||
*/
|
||||
ComputeServiceContext getContext();
|
||||
LoadBalancerServiceContext getContext();
|
||||
|
||||
/**
|
||||
* @param filter
|
||||
* Predicate-based filter to define which nodes to loadbalance
|
||||
* @param location
|
||||
* null if default
|
||||
* @param loadBalancerName
|
||||
* Load balancer name
|
||||
* @param protocol
|
||||
|
@ -58,17 +61,19 @@ public interface LoadBalancerService {
|
|||
* The InstancePort data type is simple type of type: integer. It is the TCP port on
|
||||
* which the server on the instance is listening. Valid instance ports are one (1)
|
||||
* through 65535. This property cannot be modified for the life of the LoadBalancer.
|
||||
* @param nodes
|
||||
* nodes to loadbalance
|
||||
*
|
||||
* @return DNS Name of the load balancer; note we don't use String, as it is incompatible
|
||||
* with google appengine.
|
||||
* @see org.jclouds.compute.ComputeService
|
||||
*/
|
||||
// TODO: this needs to be split up into 2 items: create load balancer and registernodes
|
||||
@Beta
|
||||
Set<String> loadBalanceNodesMatching(Predicate<NodeMetadata> filter, String loadBalancerName,
|
||||
String protocol, int loadBalancerPort, int instancePort);
|
||||
LoadBalancerMetadata createLoadBalancerInLocation(@Nullable Location location, String loadBalancerName,
|
||||
String protocol, int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes);
|
||||
|
||||
@Beta
|
||||
void destroyLoadBalancer(String handle);
|
||||
|
||||
void destroyLoadBalancer(String id);
|
||||
|
||||
@Beta
|
||||
Set<String> listLoadBalancers();
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer;
|
||||
|
||||
import org.jclouds.loadbalancer.internal.LoadBalancerServiceContextImpl;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.Utils;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* Represents a cloud that has LoadBalancer functionality.
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@ImplementedBy(LoadBalancerServiceContextImpl.class)
|
||||
public interface LoadBalancerServiceContext {
|
||||
|
||||
LoadBalancerService getLoadBalancerService();
|
||||
|
||||
|
||||
<S, A> RestContext<S, A> getProviderSpecificContext();
|
||||
|
||||
|
||||
Utils getUtils();
|
||||
|
||||
/**
|
||||
* @see #getUtils
|
||||
*/
|
||||
Utils utils();
|
||||
|
||||
void close();
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.loadbalancer.internal.LoadBalancerServiceContextImpl;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public abstract class LoadBalancerServiceContextBuilder<S, A> extends RestContextBuilder<S, A> {
|
||||
|
||||
public LoadBalancerServiceContextBuilder(Class<S> syncClientType, Class<A> asyncClientType) {
|
||||
this(syncClientType, asyncClientType, new Properties());
|
||||
}
|
||||
|
||||
public LoadBalancerServiceContextBuilder(Class<S> syncClientType, Class<A> asyncClientType,
|
||||
Properties properties) {
|
||||
super(syncClientType, asyncClientType, properties);
|
||||
|
||||
}
|
||||
|
||||
public LoadBalancerServiceContext buildLoadBalancerServiceContext() {
|
||||
// need the generic type information
|
||||
return (LoadBalancerServiceContext) buildInjector().getInstance(
|
||||
Key.get(Types.newParameterizedType(LoadBalancerServiceContextImpl.class, syncClientType,
|
||||
asyncClientType)));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer;
|
||||
|
||||
import static org.jclouds.rest.RestContextFactory.createContextBuilder;
|
||||
import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.rest.RestContextSpec;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Helper class to instantiate {@code LoadBalancerServiceContext} instances.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LoadBalancerServiceContextFactory {
|
||||
|
||||
private final RestContextFactory contextFactory;
|
||||
|
||||
/**
|
||||
* Initializes with the default properties built-in to jclouds. This is typically stored in the
|
||||
* classpath resource {@code rest.properties}
|
||||
*
|
||||
* @see RestContextFactory#getPropertiesFromResource
|
||||
*/
|
||||
public LoadBalancerServiceContextFactory() {
|
||||
this(new RestContextFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds definitions in the specified properties.
|
||||
*/
|
||||
public LoadBalancerServiceContextFactory(Properties properties) {
|
||||
this(new RestContextFactory(properties));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Uses the supplied RestContextFactory to create {@link LoadBalancerServiceContext}s
|
||||
*/
|
||||
public LoadBalancerServiceContextFactory(RestContextFactory restContextFactory) {
|
||||
this.contextFactory = restContextFactory;
|
||||
}
|
||||
|
||||
public static <S, A> LoadBalancerServiceContext buildContextUnwrappingExceptions(
|
||||
LoadBalancerServiceContextBuilder<S, A> builder) {
|
||||
try {
|
||||
return builder.buildLoadBalancerServiceContext();
|
||||
} catch (Exception e) {
|
||||
return propagateAuthorizationOrOriginalException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(String, String, String)
|
||||
*/
|
||||
public LoadBalancerServiceContext createContext(String provider, String identity, String credential) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(contextFactory
|
||||
.createContextBuilder(provider, identity, credential));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(String, Properties)
|
||||
*/
|
||||
public LoadBalancerServiceContext createContext(String provider, Properties overrides) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(contextFactory
|
||||
.createContextBuilder(provider, overrides));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(String, Iterable)
|
||||
*/
|
||||
public LoadBalancerServiceContext createContext(String provider, Iterable<? extends Module> modules, Properties overrides) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(contextFactory
|
||||
.createContextBuilder(provider, modules, overrides));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(String, String,String, Iterable)
|
||||
*/
|
||||
public LoadBalancerServiceContext createContext(String provider, @Nullable String identity, @Nullable String credential,
|
||||
Iterable<? extends Module> modules) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(contextFactory
|
||||
.createContextBuilder(provider, identity, credential, modules));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(String, String,String, Iterable, Properties)
|
||||
*/
|
||||
public LoadBalancerServiceContext createContext(String provider, @Nullable String identity, @Nullable String credential,
|
||||
Iterable<? extends Module> modules, Properties overrides) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(contextFactory
|
||||
.createContextBuilder(provider, identity, credential, modules, overrides));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(RestContextSpec)
|
||||
*/
|
||||
public <S, A> LoadBalancerServiceContext createContext(RestContextSpec<S, A> contextSpec) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class
|
||||
.cast(createContextBuilder(contextSpec));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(RestContextSpec, Properties)
|
||||
*/
|
||||
public <S, A> LoadBalancerServiceContext createContext(RestContextSpec<S, A> contextSpec, Properties overrides) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(createContextBuilder(
|
||||
contextSpec, overrides));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see RestContextFactory#createContextBuilder(RestContextSpec, Iterable, Properties)
|
||||
*/
|
||||
public <S, A> LoadBalancerServiceContext createContext(RestContextSpec<S, A> contextSpec, Iterable<Module> modules,
|
||||
Properties overrides) {
|
||||
LoadBalancerServiceContextBuilder<?, ?> builder = LoadBalancerServiceContextBuilder.class.cast(createContextBuilder(
|
||||
contextSpec, modules, overrides));
|
||||
return buildContextUnwrappingExceptions(builder);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer.domain;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.domain.ResourceMetadata;
|
||||
import org.jclouds.loadbalancer.domain.internal.LoadBalancerMetadataImpl;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ImplementedBy(LoadBalancerMetadataImpl.class)
|
||||
public interface LoadBalancerMetadata extends ResourceMetadata<LoadBalancerType> {
|
||||
/**
|
||||
* Type of the resource, ex node, image, size
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
LoadBalancerType getType();
|
||||
|
||||
/**
|
||||
* id of the server within the naming scope it was created. potentially generated by the service.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
String getProviderId();
|
||||
|
||||
/**
|
||||
* user defined name of the server.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
String getName();
|
||||
|
||||
/**
|
||||
*
|
||||
* A means to uniquely address this resource within a provider. For example, if the namespace of
|
||||
* a node or image is region based, the id will likely include both the region and the
|
||||
* provider-supplied id encoded to avoid collisions.
|
||||
*
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* @return DNS Name of the load balancer; note we don't use InetAddress, as it is incompatible
|
||||
* with google appengine.
|
||||
*/
|
||||
// TODO: this is no longer the case
|
||||
Set<String> getAddresses();
|
||||
|
||||
}
|
|
@ -17,20 +17,14 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.compute.strategy;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
package org.jclouds.loadbalancer.domain;
|
||||
|
||||
/**
|
||||
* Creates a load balancer for nodes listed
|
||||
*
|
||||
* @author Lili Nader
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface LoadBalanceNodesStrategy {
|
||||
public enum LoadBalancerType {
|
||||
|
||||
String execute(Location loaction, String name, String protocol, int loadBalancerPort,
|
||||
int instancePort, Set<String> instanceIds);
|
||||
GSLB, LB;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer.domain.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.internal.ResourceMetadataImpl;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerType;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class LoadBalancerMetadataImpl extends ResourceMetadataImpl<LoadBalancerType> implements LoadBalancerMetadata {
|
||||
/** The serialVersionUID */
|
||||
private static final long serialVersionUID = 7374704415964898694L;
|
||||
private final String id;
|
||||
private final LoadBalancerType type;
|
||||
private final Set<String> addresses;
|
||||
|
||||
public LoadBalancerMetadataImpl(LoadBalancerType type, String providerId, String name, String id, Location location,
|
||||
URI uri, Map<String, String> userMetadata, Iterable<String> addresses) {
|
||||
super(providerId, name, location, uri, userMetadata);
|
||||
this.id = checkNotNull(id, "id");
|
||||
this.type = checkNotNull(type, "type");
|
||||
this.addresses = ImmutableSet.copyOf(checkNotNull(addresses, "addresses"));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public LoadBalancerType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((addresses == null) ? 0 : addresses.hashCode());
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + id + ", providerId=" + getProviderId() + ", name=" + getName() + ", location=" + getLocation()
|
||||
+ ", uri=" + getUri() + ", userMetadata=" + getUserMetadata() + ", type=" + type + ", addresses="
|
||||
+ addresses + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LoadBalancerMetadataImpl other = (LoadBalancerMetadataImpl) obj;
|
||||
if (addresses == null) {
|
||||
if (other.addresses != null)
|
||||
return false;
|
||||
} else if (!addresses.equals(other.addresses))
|
||||
return false;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
if (type != other.type)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.compute.internal;
|
||||
package org.jclouds.loadbalancer.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
@ -28,22 +28,18 @@ import javax.annotation.Resource;
|
|||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.LoadBalancerService;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.compute.strategy.LoadBalanceNodesStrategy;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||
import org.jclouds.loadbalancer.LoadBalancerService;
|
||||
import org.jclouds.loadbalancer.LoadBalancerServiceContext;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
|
||||
import org.jclouds.loadbalancer.reference.LoadBalancerConstants;
|
||||
import org.jclouds.loadbalancer.strategy.DestroyLoadBalancerStrategy;
|
||||
import org.jclouds.loadbalancer.strategy.LoadBalanceNodesStrategy;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
|
@ -54,26 +50,21 @@ import com.google.inject.Inject;
|
|||
@Singleton
|
||||
public class BaseLoadBalancerService implements LoadBalancerService {
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named("jclouds.lb.max_retries")
|
||||
@VisibleForTesting
|
||||
int dnsRetries = 5;
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
@Named(LoadBalancerConstants.LOADBALANCER_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
protected final ComputeServiceContext context;
|
||||
protected final LoadBalancerServiceContext context;
|
||||
protected final LoadBalanceNodesStrategy loadBalancerStrategy;
|
||||
protected final DestroyLoadBalancerStrategy destroyLoadBalancerStrategy;
|
||||
// protected final ListLoadBalancersStrategy listLoadBalancersStrategy;
|
||||
protected final BackoffLimitedRetryHandler backoffLimitedRetryHandler;
|
||||
|
||||
@Inject
|
||||
protected BaseLoadBalancerService(ComputeServiceContext context, LoadBalanceNodesStrategy loadBalancerStrategy,
|
||||
DestroyLoadBalancerStrategy destroyLoadBalancerStrategy,
|
||||
// ListLoadBalancersStrategy listLoadBalancersStrategy,
|
||||
BackoffLimitedRetryHandler backoffLimitedRetryHandler) {
|
||||
protected BaseLoadBalancerService(LoadBalancerServiceContext context, LoadBalanceNodesStrategy loadBalancerStrategy,
|
||||
DestroyLoadBalancerStrategy destroyLoadBalancerStrategy,
|
||||
// ListLoadBalancersStrategy listLoadBalancersStrategy,
|
||||
BackoffLimitedRetryHandler backoffLimitedRetryHandler) {
|
||||
this.context = checkNotNull(context, "context");
|
||||
this.loadBalancerStrategy = checkNotNull(loadBalancerStrategy, "loadBalancerStrategy");
|
||||
this.destroyLoadBalancerStrategy = checkNotNull(destroyLoadBalancerStrategy, "destroyLoadBalancerStrategy");
|
||||
|
@ -86,34 +77,24 @@ public class BaseLoadBalancerService implements LoadBalancerService {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public ComputeServiceContext getContext() {
|
||||
public LoadBalancerServiceContext getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> loadBalanceNodesMatching(Predicate<NodeMetadata> filter, String loadBalancerName,
|
||||
String protocol, int loadBalancerPort, int instancePort) {
|
||||
public LoadBalancerMetadata createLoadBalancerInLocation(Location location, String loadBalancerName,
|
||||
String protocol, int loadBalancerPort, int instancePort, Iterable<? extends NodeMetadata> nodes) {
|
||||
checkNotNull(loadBalancerName, "loadBalancerName");
|
||||
checkNotNull(protocol, "protocol");
|
||||
checkArgument(protocol.toUpperCase().equals("HTTP") || protocol.toUpperCase().equals("TCP"),
|
||||
"Acceptable values for protocol are HTTP or TCP");
|
||||
|
||||
Set<String> ids = Sets.newHashSet();
|
||||
Location location = null;
|
||||
for (NodeMetadata node : Iterables.filter(context.getComputeService().listNodesDetailsMatching(
|
||||
NodePredicates.all()), filter)) {
|
||||
ids.add(node.getProviderId());
|
||||
location = node.getLocation();
|
||||
}
|
||||
Set<String> dnsNames = Sets.newHashSet();
|
||||
"Acceptable values for protocol are HTTP or TCP");
|
||||
|
||||
logger.debug(">> creating load balancer (%s)", loadBalancerName);
|
||||
String dnsName = loadBalancerStrategy.execute(location, loadBalancerName, protocol, loadBalancerPort,
|
||||
instancePort, ids);
|
||||
dnsNames.add(dnsName);
|
||||
logger.debug("<< created load balancer (%s) DNS (%s)", loadBalancerName, dnsName);
|
||||
LoadBalancerMetadata lb = loadBalancerStrategy.execute(location, loadBalancerName, protocol, loadBalancerPort,
|
||||
instancePort, nodes);
|
||||
logger.debug("<< created load balancer (%s)", loadBalancerName, lb);
|
||||
|
||||
return dnsNames;
|
||||
return lb;
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer.internal;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.loadbalancer.LoadBalancerService;
|
||||
import org.jclouds.loadbalancer.LoadBalancerServiceContext;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.Utils;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class LoadBalancerServiceContextImpl<S, A> implements LoadBalancerServiceContext {
|
||||
private final LoadBalancerService loadBalancerService;
|
||||
private final RestContext<S, A> providerSpecificContext;
|
||||
private final Utils utils;
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Inject
|
||||
public LoadBalancerServiceContextImpl(LoadBalancerService loadBalancerService, Utils utils,
|
||||
@SuppressWarnings("rawtypes") RestContext providerSpecificContext) {
|
||||
this.utils = utils;
|
||||
this.providerSpecificContext = providerSpecificContext;
|
||||
this.loadBalancerService = checkNotNull(loadBalancerService, "loadBalancerService");
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "hiding" })
|
||||
@Override
|
||||
public <S, A> RestContext<S, A> getProviderSpecificContext() {
|
||||
return (RestContext<S, A>) providerSpecificContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
providerSpecificContext.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoadBalancerService getLoadBalancerService() {
|
||||
return loadBalancerService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utils getUtils() {
|
||||
return utils();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Utils utils() {
|
||||
return utils;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return providerSpecificContext.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return providerSpecificContext.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return providerSpecificContext.equals(obj);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer.reference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public interface LoadBalancerConstants {
|
||||
|
||||
public static final String LOADBALANCER_LOGGER = "jclouds.loadbalancer";
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* ====================================================================
|
||||
*/
|
||||
|
||||
package org.jclouds.compute.strategy;
|
||||
package org.jclouds.loadbalancer.strategy;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer.strategy;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
/**
|
||||
* Creates a load balancer for nodes listed
|
||||
*
|
||||
* @author Lili Nader
|
||||
*/
|
||||
public interface LoadBalanceNodesStrategy {
|
||||
/**
|
||||
* @param location
|
||||
* null if default
|
||||
* @param loadBalancerName
|
||||
* Load balancer name
|
||||
* @param protocol
|
||||
* LoadBalancer transport protocol to use for routing - TCP or HTTP. This property
|
||||
* cannot be modified for the life of the LoadBalancer.
|
||||
* @param loadBalancerPort
|
||||
* The external TCP port of the LoadBalancer. Valid LoadBalancer ports are - 80, 443
|
||||
* and 1024 through 65535. This property cannot be modified for the life of the
|
||||
* LoadBalancer.
|
||||
* @param instancePort
|
||||
* The InstancePort data type is simple type of type: integer. It is the TCP port on
|
||||
* which the server on the instance is listening. Valid instance ports are one (1)
|
||||
* through 65535. This property cannot be modified for the life of the LoadBalancer.
|
||||
* @param nodes
|
||||
* nodes to loadbalance
|
||||
*
|
||||
* @return newly created loadbalancer
|
||||
* @see org.jclouds.compute.ComputeService
|
||||
*/
|
||||
@Beta
|
||||
LoadBalancerMetadata execute(Location location, String name, String protocol, int loadBalancerPort,
|
||||
int instancePort, Iterable<? extends NodeMetadata> nodes);
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.loadbalancer;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.loadbalancer.domain.LoadBalancerMetadata;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
import org.jclouds.net.IPSocket;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
import org.jclouds.predicates.SocketOpen;
|
||||
import org.jclouds.rest.RestContextFactory;
|
||||
import org.jclouds.ssh.SshClient;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "live", sequential = true)
|
||||
public abstract class BaseLoadBalancerServiceLiveTest {
|
||||
|
||||
protected SshClient.Factory sshFactory;
|
||||
protected String tag;
|
||||
|
||||
protected RetryablePredicate<IPSocket> socketTester;
|
||||
protected Set<? extends NodeMetadata> nodes;
|
||||
protected Template template;
|
||||
protected Map<String, String> keyPair;
|
||||
protected LoadBalancerMetadata loadbalancer;
|
||||
|
||||
protected String provider;
|
||||
protected String identity;
|
||||
protected String credential;
|
||||
protected String endpoint;
|
||||
protected String apiversion;
|
||||
protected LoadBalancerServiceContext context;
|
||||
|
||||
protected String computeProvider;
|
||||
protected String computeIdentity;
|
||||
protected String computeCredential;
|
||||
protected String computeEndpoint;
|
||||
protected String computeApiversion;
|
||||
protected ComputeServiceContext computeContext;
|
||||
|
||||
protected void setupCredentials() {
|
||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||
credential = System.getProperty("test." + provider + ".credential");
|
||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||
|
||||
computeProvider = checkNotNull(System.getProperty("test.compute.provider"), "test.compute.provider");
|
||||
computeIdentity = checkNotNull(System.getProperty("test." + computeProvider + ".identity"), "test."
|
||||
+ computeProvider + ".identity");
|
||||
computeCredential = System.getProperty("test." + computeProvider + ".credential");
|
||||
computeEndpoint = System.getProperty("test." + computeProvider + ".endpoint");
|
||||
computeApiversion = System.getProperty("test." + computeProvider + ".apiversion");
|
||||
}
|
||||
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||
overrides.setProperty(provider + ".identity", identity);
|
||||
if (credential != null)
|
||||
overrides.setProperty(provider + ".credential", credential);
|
||||
if (endpoint != null)
|
||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||
if (apiversion != null)
|
||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||
return overrides;
|
||||
}
|
||||
|
||||
protected Properties setupComputeProperties() {
|
||||
Properties overrides = new Properties();
|
||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||
overrides.setProperty(computeProvider + ".identity", computeIdentity);
|
||||
if (computeCredential != null)
|
||||
overrides.setProperty(computeProvider + ".credential", computeCredential);
|
||||
if (computeEndpoint != null)
|
||||
overrides.setProperty(computeProvider + ".endpoint", computeEndpoint);
|
||||
if (computeApiversion != null)
|
||||
overrides.setProperty(computeProvider + ".apiversion", computeApiversion);
|
||||
return overrides;
|
||||
}
|
||||
|
||||
@BeforeGroups(groups = { "integration", "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||
setServiceDefaults();
|
||||
if (tag == null)
|
||||
tag = checkNotNull(provider, "provider");
|
||||
setupCredentials();
|
||||
initializeContext();
|
||||
initializeComputeContext();
|
||||
buildSocketTester();
|
||||
}
|
||||
|
||||
public void setServiceDefaults() {
|
||||
|
||||
}
|
||||
|
||||
private void initializeContext() throws IOException {
|
||||
if (context != null)
|
||||
context.close();
|
||||
context = new LoadBalancerServiceContextFactory(getRestProperties()).createContext(provider,
|
||||
ImmutableSet.of(new Log4JLoggingModule()), setupProperties());
|
||||
}
|
||||
|
||||
private void initializeComputeContext() throws IOException {
|
||||
if (computeContext != null)
|
||||
computeContext.close();
|
||||
computeContext = new ComputeServiceContextFactory(getRestProperties()).createContext(computeProvider,
|
||||
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), setupComputeProperties());
|
||||
}
|
||||
|
||||
protected Properties getRestProperties() {
|
||||
return RestContextFactory.getPropertiesFromResource("/rest.properties");
|
||||
}
|
||||
|
||||
protected void buildSocketTester() {
|
||||
SocketOpen socketOpen = Guice.createInjector(getSshModule()).getInstance(SocketOpen.class);
|
||||
socketTester = new RetryablePredicate<IPSocket>(socketOpen, 60, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
abstract protected Module getSshModule();
|
||||
|
||||
@BeforeGroups(groups = { "integration", "live" })
|
||||
public void createNodes() throws RunNodesException {
|
||||
try {
|
||||
nodes = computeContext.getComputeService().runNodesWithTag(tag, 2);
|
||||
} catch (RunNodesException e) {
|
||||
nodes = e.getSuccessfulNodes();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(enabled = true)
|
||||
public void testLoadBalanceNodesMatching() throws Exception {
|
||||
|
||||
// create load balancers
|
||||
loadbalancer = context.getLoadBalancerService().createLoadBalancerInLocation(null, tag, "HTTP", 80, 80, nodes);
|
||||
assertNotNull(loadbalancer);
|
||||
validateNodesInLoadBalancer();
|
||||
|
||||
}
|
||||
|
||||
// TODO create a LoadBalancerService method for this.
|
||||
protected abstract void validateNodesInLoadBalancer();
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testLoadBalanceNodesMatching")
|
||||
public void testDestroyLoadBalancers() throws Exception {
|
||||
context.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId());
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||
if (loadbalancer != null) {
|
||||
context.getLoadBalancerService().destroyLoadBalancer(tag);
|
||||
}
|
||||
if (nodes != null) {
|
||||
computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
||||
}
|
||||
computeContext.close();
|
||||
context.close();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue