Issue 440: refactored zone and region logic into top-level jclouds so that we can decouple amazon's concepts from api implementations

This commit is contained in:
Adrian Cole 2011-01-04 20:05:49 +01:00
parent 93cd8eaef3
commit 478494b65c
33 changed files with 315 additions and 288 deletions

View File

@ -44,5 +44,10 @@
<artifactId>aws-simpledb</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds.provider</groupId>
<artifactId>aws-elb</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -34,6 +34,7 @@
<description>jclouds components to access an implementation of Elastic Load Balancer</description>
<properties>
<test.elb.zone>us-east-1a</test.elb.zone>
<test.elb.endpoint>https://elasticloadbalancing.us-east-1.amazonaws.com</test.elb.endpoint>
<test.elb.apiversion>2010-07-01</test.elb.apiversion>
<test.elb.identity>${test.aws.identity}</test.elb.identity>
@ -109,6 +110,10 @@
</goals>
<configuration>
<systemProperties>
<property>
<name>test.elb.zone</name>
<value>${test.elb.zone}</value>
</property>
<property>
<name>test.elb.endpoint</name>
<value>${test.elb.endpoint}</value>

View File

@ -23,15 +23,10 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_ZONECLIENT_ENDPOINT;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties;
import org.jclouds.PropertiesBuilder;
import org.jclouds.aws.domain.Region;
import com.google.common.base.Joiner;
/**
* Builds properties used in ELB Clients
@ -45,18 +40,7 @@ public class ELBPropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
properties.setProperty(PROPERTY_API_VERSION, ELBAsyncClient.VERSION);
properties.setProperty(PROPERTY_REGIONS,
Joiner.on(',').join(Region.US_EAST_1, Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT, "https://elasticloadbalancing.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1,
"https://elasticloadbalancing.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
"https://elasticloadbalancing.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.EU_WEST_1,
"https://elasticloadbalancing.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
"https://elasticloadbalancing.ap-southeast-1.amazonaws.com");
properties.setProperty(PROPERTY_ZONECLIENT_ENDPOINT, "https://ec2.us-east-1.amazonaws.com");
return properties;
}

View File

@ -19,7 +19,7 @@
package org.jclouds.elb.config;
import org.jclouds.aws.config.WithZonesFormSigningRestClientModule;
import org.jclouds.aws.config.FormSigningRestClientModule;
import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient;
import org.jclouds.http.RequiresHttp;
@ -32,7 +32,7 @@ import org.jclouds.rest.ConfiguresRestClient;
*/
@RequiresHttp
@ConfiguresRestClient
public class ELBRestClientModule extends WithZonesFormSigningRestClientModule<ELBClient, ELBAsyncClient> {
public class ELBRestClientModule extends FormSigningRestClientModule<ELBClient, ELBAsyncClient> {
public ELBRestClientModule() {
super(ELBClient.class, ELBAsyncClient.class);
}

View File

@ -23,8 +23,7 @@ import java.util.Set;
import org.jclouds.domain.Location;
import org.jclouds.loadbalancer.config.BindLoadBalancerSuppliersByClass;
import org.jclouds.location.suppliers.FirstZoneOrRegionMatchingRegionId;
import org.jclouds.location.suppliers.ZoneToRegionToProvider;
import org.jclouds.location.suppliers.RegionToProviderOrJustProvider;
import com.google.common.base.Supplier;
@ -33,13 +32,8 @@ import com.google.common.base.Supplier;
*/
public class ELBBindLoadBalancerSuppliersByClass extends BindLoadBalancerSuppliersByClass {
@Override
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
return FirstZoneOrRegionMatchingRegionId.class;
}
@Override
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
return ZoneToRegionToProvider.class;
return RegionToProviderOrJustProvider.class;
}
}

View File

@ -42,18 +42,24 @@ import com.google.common.collect.ImmutableSet;
@Singleton
public class LoadBalancerToLoadBalancerMetadata implements Function<LoadBalancer, LoadBalancerMetadata> {
protected final Supplier<Map<String, ? extends Location>> locationMap;
protected final Supplier<Location> defaultLocationSupplier;
@Inject
public LoadBalancerToLoadBalancerMetadata(Supplier<Map<String, ? extends Location>> locationMap) {
public LoadBalancerToLoadBalancerMetadata(Supplier<Location> defaultLocationSupplier,
Supplier<Map<String, ? extends Location>> locationMap) {
this.locationMap = locationMap;
this.defaultLocationSupplier = defaultLocationSupplier;
}
@Override
public LoadBalancerMetadata apply(LoadBalancer input) {
Location location = locationMap.get().get(input.getRegion());
Location location = input.getRegion() != null ? locationMap.get().get(input.getRegion())
: defaultLocationSupplier.get();
String id = input.getRegion() != null ? input.getRegion() + "/" + input.getName() : input.getName();
// TODO Builder
return new LoadBalancerMetadataImpl(LoadBalancerType.LB, input.getName(), input.getName(), input.getRegion()
+ "/" + input.getName(), location, null, ImmutableMap.<String, String> of(), ImmutableSet.of(input
.getDnsName()));
return new LoadBalancerMetadataImpl(LoadBalancerType.LB, input.getName(), input.getName(), id, location, null,
ImmutableMap.<String, String> of(), ImmutableSet.of(input.getDnsName()));
}
}

View File

@ -36,9 +36,9 @@ public class ELBGetLoadBalancerMetadataStrategy implements GetLoadBalancerMetada
public LoadBalancerMetadata getLoadBalancer(String id) {
String[] parts = parseHandle(id);
String region = parts[0];
String instanceId = parts[1];
String name = parts[1];
try {
return converter.apply(getOnlyElement(client.describeLoadBalancersInRegion(region, region, instanceId)));
return converter.apply(getOnlyElement(client.describeLoadBalancersInRegion(region, name)));
} catch (NoSuchElementException e) {
return null;
}

View File

@ -80,7 +80,7 @@ public class ELBAsyncClientTest extends RestClientTest<ELBAsyncClient> {
public void testDescribeLoadBalancers() throws SecurityException, NoSuchMethodException, IOException {
Method method = ELBAsyncClient.class.getMethod("describeLoadBalancersInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method, (String) null);
HttpRequest request = processor.createRequest(method);
assertRequestLineEquals(request, "POST https://elasticloadbalancing.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: elasticloadbalancing.us-east-1.amazonaws.com\n");
@ -178,9 +178,11 @@ public class ELBAsyncClientTest extends RestClientTest<ELBAsyncClient> {
return new TestELBRestClientModule();
}
protected String provider = "elb";
@Override
public RestContextSpec<?, ?> createContextSpec() {
return new RestContextFactory().createContextSpec("elb", "identity", "credential", new Properties());
return new RestContextFactory().createContextSpec(provider, "identity", "credential", new Properties());
}
@Override

View File

@ -22,13 +22,10 @@ package org.jclouds.elb;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertNotNull;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.jclouds.Constants;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.elb.domain.LoadBalancer;
import org.jclouds.loadbalancer.LoadBalancerServiceContextFactory;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -37,9 +34,7 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.inject.Module;
/**
@ -57,6 +52,7 @@ public class ELBClientLiveTest {
protected String credential;
protected String endpoint;
protected String apiversion;
protected String name = "TestLoadBalancer";
protected void setupCredentials() {
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
@ -90,34 +86,35 @@ public class ELBClientLiveTest {
}
@Test
void testCreateLoadBalancer() {
String name = "TestLoadBalancer";
for (Entry<String, String> regionZone : ImmutableMap.<String, String> of(Region.US_EAST_1,
AvailabilityZone.US_EAST_1A, Region.US_WEST_1, AvailabilityZone.US_WEST_1A, Region.EU_WEST_1,
AvailabilityZone.EU_WEST_1A, Region.AP_SOUTHEAST_1, AvailabilityZone.AP_SOUTHEAST_1A).entrySet()) {
String dnsName = client.createLoadBalancerInRegion(regionZone.getKey(), name, "http", 80, 80,
regionZone.getValue());
assertNotNull(dnsName);
assert (dnsName.startsWith(name));
}
public void testCreateLoadBalancer() {
createLoadBalancerInRegionZone(null,
checkNotNull(System.getProperty("test." + provider + ".zone"), "test." + provider + ".zone"), name);
}
protected void createLoadBalancerInRegionZone(String region, String zone, String name) {
String dnsName = client.createLoadBalancerInRegion(region, name, "http", 80, 80, zone);
assertNotNull(dnsName);
assert (dnsName.startsWith(name));
}
@Test(dependsOnMethods = "testCreateLoadBalancer")
void testDescribeLoadBalancers() {
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
Region.AP_SOUTHEAST_1)) {
Set<? extends LoadBalancer> allResults = client.describeLoadBalancersInRegion(region);
assertNotNull(allResults);
assert (allResults.size() >= 1) : region;
}
public void testDescribeLoadBalancers() {
describeLoadBalancerInRegion(null);
}
protected void describeLoadBalancerInRegion(String region) {
Set<? extends LoadBalancer> allResults = client.describeLoadBalancersInRegion(region);
assertNotNull(allResults);
assert (allResults.size() >= 1) : region;
}
@Test
void testDeleteLoadBalancer() {
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
Region.AP_SOUTHEAST_1)) {
client.deleteLoadBalancerInRegion(region, "TestLoadBalancer");
}
public void testDeleteLoadBalancer() {
deleteLoadBalancerInRegion(null);
}
protected void deleteLoadBalancerInRegion(String region) {
client.deleteLoadBalancerInRegion(region, name);
}
@AfterTest

View File

@ -25,7 +25,6 @@ import static org.testng.Assert.assertNotNull;
import java.util.HashSet;
import java.util.Set;
import org.jclouds.aws.domain.Region;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.elb.ELBAsyncClient;
import org.jclouds.elb.ELBClient;
@ -63,7 +62,7 @@ public class ELBLoadBalancerServiceLiveTest extends BaseLoadBalancerServiceLiveT
for (NodeMetadata node : nodes) {
instanceIds.add(node.getProviderId());
}
Set<? extends LoadBalancer> elbs = elbClient.describeLoadBalancersInRegion(Region.US_EAST_1);
Set<? extends LoadBalancer> elbs = elbClient.describeLoadBalancersInRegion(null);
assertNotNull(elbs);
for (LoadBalancer elb : elbs) {
if (elb.getName().equals(tag))

View File

@ -23,6 +23,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties;
@ -48,13 +49,13 @@ public class CloudWatchPropertiesBuilder extends PropertiesBuilder {
Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT,
"https://monitoring.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1,
properties.setProperty(PROPERTY_REGION + "." + Region.US_EAST_1 + ".endpoint",
"https://monitoring.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + ".endpoint",
"https://monitoring.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.EU_WEST_1,
properties.setProperty(PROPERTY_REGION + "." + Region.EU_WEST_1 + ".endpoint",
"https://monitoring.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + ".endpoint",
"https://monitoring.ap-southeast-1.amazonaws.com");
return properties;
}

View File

@ -38,6 +38,7 @@ import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import org.jclouds.location.config.ProvideRegionsViaProperties;
import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;

View File

@ -1,168 +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.config;
import java.net.URI;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.domain.AvailabilityZoneInfo;
import org.jclouds.aws.ec2.xml.DescribeAvailabilityZonesResponseHandler;
import org.jclouds.aws.ec2.xml.DescribeRegionsResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.concurrent.Timeout;
import org.jclouds.concurrent.internal.SyncProxy;
import org.jclouds.internal.ClassMethodArgs;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.rest.AsyncClientFactory;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
*
* @author Adrian Cole
*/
public class ProvidersViaAPI {
@Singleton
public static class RegionIdsToURI implements javax.inject.Provider<Map<String, URI>> {
private final ZoneAndRegionClient client;
private URI endpoint;
@Inject
public RegionIdsToURI(@Zone URI endpoint, ZoneAndRegionClient client) {
this.client = client;
this.endpoint = endpoint;
}
@Singleton
@Region
@Override
public Map<String, URI> get() {
return client.describeRegions(endpoint);
}
}
@Singleton
public static class RegionIdToZoneId implements javax.inject.Provider<Map<String, String>> {
private final ZoneAndRegionClient client;
private final Set<String> regions;
private final RegionIdsToURI regionIdsToURI;
@Inject
public RegionIdToZoneId(RegionIdsToURI regionIdsToURI, ZoneAndRegionClient client, @Region Set<String> regions) {
this.client = client;
this.regions = regions;
this.regionIdsToURI = regionIdsToURI;
}
@Singleton
@Zone
@Override
public Map<String, String> get() {
Builder<String, String> map = ImmutableMap.<String, String> builder();
for (Entry<String, URI> region : regionIdsToURI.get().entrySet()) {
if (regions.contains(region.getKey()))
for (AvailabilityZoneInfo zoneInfo : client.describeAvailabilityZonesInRegion(region.getValue())) {
map.put(zoneInfo.getZone(), region.getKey());
}
}
return map.build();
}
}
static class ProvidesZoneAndRegionClientModule extends AbstractModule {
@Provides
@Singleton
@Zone
URI provideURI(@Named(AWSConstants.PROPERTY_ZONECLIENT_ENDPOINT) String endpoint) {
return URI.create(endpoint);
}
@Provides
@Singleton
ZoneAndRegionClient provideZoneAndRegionClient(AsyncClientFactory factory) throws IllegalArgumentException,
SecurityException, NoSuchMethodException {
return SyncProxy.proxy(ZoneAndRegionClient.class,
new SyncProxy(ZoneAndRegionClient.class, factory.create(ZoneAndRegionAsyncClient.class),
new ConcurrentHashMap<ClassMethodArgs, Object>(), ImmutableMap.<Class<?>, Class<?>> of()));
}
@Override
protected void configure() {
}
}
@RequestFilters(FormSigner.class)
@FormParams(keys = "Version", values = "2010-06-15")
@VirtualHost
static interface ZoneAndRegionAsyncClient {
@POST
@Path("/")
@FormParams(keys = "Action", values = "DescribeAvailabilityZones")
@XMLResponseParser(DescribeAvailabilityZonesResponseHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<? extends Set<AvailabilityZoneInfo>> describeAvailabilityZonesInRegion(@EndpointParam URI region);
@POST
@Path("/")
@FormParams(keys = "Action", values = "DescribeRegions")
@XMLResponseParser(DescribeRegionsResponseHandler.class)
ListenableFuture<? extends Map<String, URI>> describeRegions(@EndpointParam URI endpoint);
}
@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS)
static interface ZoneAndRegionClient {
Set<AvailabilityZoneInfo> describeAvailabilityZonesInRegion(URI region);
Map<String, URI> describeRegions(URI endpoint);
}
}

View File

@ -24,10 +24,10 @@ import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.aws.config.ProvidersViaAPI.ProvidesZoneAndRegionClientModule;
import org.jclouds.http.RequiresHttp;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.location.config.ProvideZonesViaProperties;
import org.jclouds.rest.ConfiguresRestClient;
import com.google.common.base.Function;
@ -54,8 +54,7 @@ public class WithZonesFormSigningRestClientModule<S, A> extends FormSigningRestC
}
protected void bindZonesToProvider() {
install(new ProvidesZoneAndRegionClientModule());
bindZonesToProvider(ProvidersViaAPI.RegionIdToZoneId.class);
bindZonesToProvider(ProvideZonesViaProperties.class);
}
protected void bindZonesToProvider(Class<? extends javax.inject.Provider<Map<String, String>>> providerClass) {

View File

@ -27,8 +27,8 @@ import org.jclouds.compute.config.BindComputeSuppliersByClass;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.FirstZoneOrRegionMatchingRegionId;
import org.jclouds.location.suppliers.ZoneToRegionToProvider;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZoneOrRegionMatchingRegionId;
import org.jclouds.location.suppliers.ZoneToRegionToProviderOrJustProvider;
import com.google.common.base.Supplier;
/**
@ -47,11 +47,11 @@ public class EC2BindComputeSuppliersByClass extends BindComputeSuppliersByClass
@Override
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
return FirstZoneOrRegionMatchingRegionId.class;
return OnlyLocationOrFirstZoneOrRegionMatchingRegionId.class;
}
@Override
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
return ZoneToRegionToProvider.class;
return ZoneToRegionToProviderOrJustProvider.class;
}
}

View File

@ -60,7 +60,7 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
@Override
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
String provider = injector.getInstance(Key.get(String.class, Provider.class));
if ("ec2".equals(provider))
if ("ec2".equals(provider) || "aws-ec2".equals(provider))
return template.osFamily(AMZN_LINUX).os64Bit(true);
else if ("nova".equals(provider))
return super.provideTemplate(injector, template);

View File

@ -86,10 +86,10 @@ public class EC2Utils {
return Iterables.concat(client.describeInstancesInRegion(region, id));
}
// there may not be a region, and in this case we do-not encode it into the string
public static String[] parseHandle(String id) {
String[] parts = checkNotNull(id, "id").split("/");
checkArgument(parts.length == 2, "id syntax is region/instanceid");
return parts;
return (parts.length == 1) ? new String[] { null, id } : parts;
}
public static <R extends HttpRequest> R indexIterableToFormValuesWithPrefix(R request, String prefix, Object input) {

View File

@ -29,6 +29,7 @@ import static org.jclouds.aws.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_
import static org.jclouds.blobstore.reference.BlobStoreConstants.DIRECTORY_SUFFIX_FOLDER;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX;
import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties;
@ -62,11 +63,12 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_REGIONS,
Joiner.on(',').join(Region.US_STANDARD, Region.US_WEST_1, "EU", Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_STANDARD, "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1, "https://s3-us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + "EU", "https://s3-eu-west-1.amazonaws.com");
properties
.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1, "https://s3-ap-southeast-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.US_STANDARD + ".endpoint", "https://s3.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + ".endpoint",
"https://s3-us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + "EU" + ".endpoint", "https://s3-eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + ".endpoint",
"https://s3-ap-southeast-1.amazonaws.com");
return properties;
}

View File

@ -43,7 +43,7 @@ import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import org.jclouds.location.suppliers.FirstZoneOrRegionMatchingRegionId;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZoneOrRegionMatchingRegionId;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@ -65,7 +65,7 @@ public class S3BlobStoreContextModule extends AbstractModule {
protected void configure() {
install(new BlobStoreMapModule());
bind(new TypeLiteral<Supplier<Location>>() {
}).to(new TypeLiteral<FirstZoneOrRegionMatchingRegionId>() {
}).to(new TypeLiteral<OnlyLocationOrFirstZoneOrRegionMatchingRegionId>() {
});
bind(ConsistencyModel.class).toInstance(ConsistencyModel.EVENTUAL);
bind(AsyncBlobStore.class).to(S3AsyncBlobStore.class).in(Scopes.SINGLETON);

View File

@ -23,6 +23,7 @@ import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties;
@ -44,17 +45,17 @@ public class SQSPropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_HEADER_TAG, "amz");
properties.setProperty(PROPERTY_API_VERSION, SQSAsyncClient.VERSION);
properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(Region.US_EAST_1,
Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_REGIONS,
Joiner.on(',').join(Region.US_EAST_1, Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT, "https://sqs.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1,
"https://sqs.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
"https://sqs.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.EU_WEST_1,
"https://sqs.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
"https://sqs.ap-southeast-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.US_EAST_1 + ".endpoint",
"https://sqs.us-east-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + ".endpoint",
"https://sqs.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.EU_WEST_1 + ".endpoint",
"https://sqs.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + ".endpoint",
"https://sqs.ap-southeast-1.amazonaws.com");
return properties;
}

View File

@ -75,7 +75,7 @@ public class EC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.10");
assertEquals(template.getImage().getOperatingSystem().is64Bit(), false);
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(template.getImage().getVersion(), "20101215");
assertEquals(template.getImage().getVersion(), "20110101");
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
assertEquals(template.getLocation().getId(), "us-east-1");
assertEquals(getCores(template.getHardware()), 1.0d);

View File

@ -1,5 +1,25 @@
package org.jclouds.aws.config;
/**
*
* 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.location.config;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.net.URI;
@ -8,7 +28,6 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
@ -20,6 +39,12 @@ import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
/**
*
* looks for properties bound to the naming convention jclouds.location.region.{@code regionId}.endpoint
*
* @author Adrian Cole
*/
@Singleton
public class ProvideRegionsViaProperties implements javax.inject.Provider<Map<String, URI>> {
@ -41,7 +66,7 @@ public class ProvideRegionsViaProperties implements javax.inject.Provider<Map<St
regions.put(
region,
URI.create(injector.getInstance(Key.get(String.class,
Names.named(Constants.PROPERTY_ENDPOINT + "." + region)))));
Names.named(PROPERTY_REGION + "." + region + ".endpoint")))));
}
return regions.build();
} catch (ConfigurationException e) {

View File

@ -0,0 +1,78 @@
/**
*
* 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.location.config;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.inject.ConfigurationException;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.name.Names;
/**
*
* looks for properties bound to the naming convention jclouds.location.region.{@code regionId}.zones
*
* @author Adrian Cole
*/
@Singleton
public class ProvideZonesViaProperties implements javax.inject.Provider<Map<String, String>> {
private final Injector injector;
private final Set<String> regions;
@Inject
ProvideZonesViaProperties(Injector injector, @Region Set<String> regions) {
this.injector = injector;
this.regions = regions;
}
@Singleton
@Zone
@Override
public Map<String, String> get() {
try {
Builder<String, String> zones = ImmutableMap.<String, String> builder();
for (String region : regions) {
for (String zone : Splitter.on(',').split(
injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGION + "." + region + ".zones"))))) {
zones.put(zone, region);
}
}
return zones.build();
} catch (ConfigurationException e) {
// this happens if regions property isn't set
// services not run by AWS may not have zones, so this is ok.
return ImmutableMap.<String, String> of();
}
}
}

View File

@ -57,13 +57,13 @@ public class RegionToEndpointOrProviderIfNull implements Function<Object, URI> {
@Override
public URI apply(@Nullable Object from) {
checkState(from == null || from.equals(defaultProvider) || regionToEndpoint != null, "requested location " + from
if (from == null || from.equals(defaultProvider))
return defaultUri;
checkState(from.equals(defaultProvider) || regionToEndpoint != null, "requested location " + from
+ ", but only the default location " + defaultProvider + " is configured");
checkArgument(
from == null || from.equals(defaultProvider)
|| (regionToEndpoint != null && regionToEndpoint.containsKey(from)),
checkArgument(from.equals(defaultProvider) || (regionToEndpoint != null && regionToEndpoint.containsKey(from)),
"requested location %s, which is not in the configured locations: %s", from, regionToEndpoint);
return from == null || from.equals(defaultProvider) ? defaultUri : regionToEndpoint.get(from);
return regionToEndpoint.get(from);
}
}

View File

@ -25,4 +25,5 @@ package org.jclouds.location.reference;
*/
public interface LocationConstants {
public static final String PROPERTY_REGIONS = "jclouds.location.regions";
public static final String PROPERTY_REGION = "jclouds.location.region";
}

View File

@ -20,6 +20,7 @@
package org.jclouds.location.suppliers;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import java.util.NoSuchElementException;
import java.util.Set;
@ -40,7 +41,7 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole
*/
@Singleton
public class FirstZoneOrRegionMatchingRegionId implements Supplier<Location> {
public class OnlyLocationOrFirstZoneOrRegionMatchingRegionId implements Supplier<Location> {
@Singleton
public static final class IsRegionAndIdEqualsOrIsZoneParentIdEquals implements Predicate<Location> {
@ -73,7 +74,7 @@ public class FirstZoneOrRegionMatchingRegionId implements Supplier<Location> {
private final Supplier<Set<? extends Location>> locationsSupplier;
@Inject
FirstZoneOrRegionMatchingRegionId(IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher,
OnlyLocationOrFirstZoneOrRegionMatchingRegionId(IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher,
@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
this.matcher = checkNotNull(matcher, "matcher");
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier");
@ -83,6 +84,8 @@ public class FirstZoneOrRegionMatchingRegionId implements Supplier<Location> {
@Singleton
public Location get() {
Set<? extends Location> locations = locationsSupplier.get();
if (locationsSupplier.get().size() == 1)
return getOnlyElement(locationsSupplier.get());
try {
Location toReturn = Iterables.find(locations, matcher);
return toReturn.getScope() == LocationScope.REGION ? toReturn : toReturn.getParent();

View File

@ -0,0 +1,70 @@
/**
*
* 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.location.suppliers;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class RegionToProviderOrJustProvider implements Supplier<Set<? extends Location>> {
private final Set<String> regions;
private final String providerName;
@Inject
RegionToProviderOrJustProvider(@Region Set<String> regions, @Provider String providerName) {
this.regions = checkNotNull(regions, "regions");
this.providerName = checkNotNull(providerName, "providerName");
}
@Override
public Set<? extends Location> get() {
final Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
if (regions.size() == 0)
return ImmutableSet.of(provider);
return ImmutableSet.<Location> copyOf(Iterables.transform(regions, new Function<String, Location>() {
@Override
public Location apply(String input) {
return new LocationImpl(LocationScope.REGION, input, input, provider);
}
}));
}
}

View File

@ -38,39 +38,42 @@ import org.jclouds.location.Zone;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ZoneToRegionToProvider implements Supplier<Set<? extends Location>> {
public class ZoneToRegionToProviderOrJustProvider implements Supplier<Set<? extends Location>> {
private final Map<String, String> zoneToRegion;
private final String providerName;
@Inject
ZoneToRegionToProvider(@Zone Map<String, String> zoneToRegion, @Provider String providerName) {
ZoneToRegionToProviderOrJustProvider(@Zone Map<String, String> zoneToRegion, @Provider String providerName) {
this.zoneToRegion = checkNotNull(zoneToRegion, "zoneToRegion");
this.providerName = checkNotNull(providerName, "providerName");
}
@Override
public Set<? extends Location> get() {
Location ec2 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
Set<Location> locations = newLinkedHashSet();
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
if (zoneToRegion.size() == 0)
return ImmutableSet.of(provider);
Set<Location> providers = newLinkedHashSet();
for (String region : newLinkedHashSet(zoneToRegion.values())) {
locations.add(new LocationImpl(LocationScope.REGION, region, region, ec2));
providers.add(new LocationImpl(LocationScope.REGION, region, region, provider));
}
ImmutableMap<String, Location> idToLocation = uniqueIndex(locations, new Function<Location, String>() {
ImmutableMap<String, Location> idToLocation = uniqueIndex(providers, new Function<Location, String>() {
@Override
public String apply(Location from) {
return from.getId();
}
});
for (String zone : zoneToRegion.keySet()) {
locations.add(new LocationImpl(LocationScope.ZONE, zone, zone, idToLocation.get(zoneToRegion.get(zone))));
providers.add(new LocationImpl(LocationScope.ZONE, zone, zone, idToLocation.get(zoneToRegion.get(zone))));
}
return locations;
return providers;
}
}

View File

@ -44,6 +44,9 @@ aws-simpledb.propertiesbuilder=org.jclouds.aws.simpledb.SimpleDBPropertiesBuilde
elb.contextbuilder=org.jclouds.elb.ELBContextBuilder
elb.propertiesbuilder=org.jclouds.elb.ELBPropertiesBuilder
aws-elb.contextbuilder=org.jclouds.elb.ELBContextBuilder
aws-elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder
cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder
cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder
@ -53,6 +56,9 @@ s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
aws-ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
aws-ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder

View File

@ -27,7 +27,7 @@ import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZoneOrRegionMatchingRegionId;
import com.google.common.base.Supplier;
import com.google.inject.AbstractModule;
@ -67,7 +67,7 @@ public abstract class BindLoadBalancerSuppliersByClass extends AbstractModule {
}
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
return OnlyLocationOrFirstZone.class;
return OnlyLocationOrFirstZoneOrRegionMatchingRegionId.class;
}
protected void bindImageSupplier(Class<? extends Supplier<Set<? extends Image>>> clazz) {

View File

@ -67,6 +67,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>

View File

@ -25,11 +25,14 @@ import static org.jclouds.aws.domain.Region.EU_WEST_1;
import static org.jclouds.aws.domain.Region.US_EAST_1;
import static org.jclouds.aws.domain.Region.US_WEST_1;
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties;
import java.util.Set;
import org.jclouds.aws.domain.Region;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
@ -47,10 +50,13 @@ public class SimpleDBPropertiesBuilder extends org.jclouds.simpledb.SimpleDBProp
properties.setProperty(PROPERTY_AUTH_TAG, "AWS");
properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(DEFAULT_REGIONS));
properties.setProperty(PROPERTY_ENDPOINT, "https://sdb.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + US_EAST_1, "https://sdb.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + US_WEST_1, "https://sdb.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + EU_WEST_1, "https://sdb.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + AP_SOUTHEAST_1, "https://sdb.ap-southeast-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.US_EAST_1 + ".endpoint", "https://sdb.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + ".endpoint",
"https://sdb.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.EU_WEST_1 + ".endpoint",
"https://sdb.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + ".endpoint",
"https://sdb.ap-southeast-1.amazonaws.com");
return properties;
}

View File

@ -37,5 +37,6 @@
<module>slicehost</module>
<module>cloudsigma</module>
<module>aws-simpledb</module>
<module>aws-elb</module>
</modules>
</project>