moved loadbalancerservice into its own module

This commit is contained in:
Adrian Cole 2011-01-01 20:28:52 +01:00
parent ec0cd17270
commit 417cb3acf0
30 changed files with 1094 additions and 440 deletions

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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");
}

View File

@ -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));
}
}

View File

@ -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);
}
}
}

View File

@ -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>

View File

@ -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();
/**

View File

@ -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) {

View File

@ -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();

View File

@ -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()

View File

@ -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();
}
}

View File

@ -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;

73
loadbalancer/pom.xml Normal file
View File

@ -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>

View File

@ -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();

View File

@ -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();
}

View File

@ -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)));
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
/**

View File

@ -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);
}
}

View File

@ -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";
}

View File

@ -17,7 +17,7 @@
* ====================================================================
*/
package org.jclouds.compute.strategy;
package org.jclouds.loadbalancer.strategy;
import com.google.common.annotations.Beta;

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -36,6 +36,7 @@
<module>archetypes</module>
<module>core</module>
<module>compute</module>
<module>loadbalancer</module>
<module>blobstore</module>
<module>skeletons</module>
<module>filesystem</module>