Finished partial fix in 91f405c9fe.

This commit is contained in:
Adrian Cole 2014-11-16 10:15:06 -08:00 committed by Adrian Cole
parent ca58491ce8
commit d6aeb77cae
8 changed files with 94 additions and 123 deletions

View File

@ -16,17 +16,34 @@
*/ */
package org.jclouds.openstack.keystone.v2_0.functions; package org.jclouds.openstack.keystone.v2_0.functions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.location.functions.RegionToEndpoint;
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier; import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
/** import com.google.common.base.Function;
* @author Adam Lowe import com.google.common.base.Supplier;
*/
public class RegionToAdminEndpointURI extends RegionToEndpoint { public final class RegionToAdminEndpointURI implements Function<Object, URI> {
private final RegionIdToAdminURISupplier regionToAdminEndpoints;
@Inject @Inject
public RegionToAdminEndpointURI(RegionIdToAdminURISupplier regionToEndpointSupplier) { RegionToAdminEndpointURI(RegionIdToAdminURISupplier regionToAdminEndpoints) {
super(regionToEndpointSupplier); this.regionToAdminEndpoints = regionToAdminEndpoints;
}
@Override
public URI apply(Object from) {
Map<String, Supplier<URI>> regionToAdminEndpoint = regionToAdminEndpoints.get();
checkState(!regionToAdminEndpoint.isEmpty(), "no region name to admin endpoint mappings in keystone!");
checkArgument(regionToAdminEndpoint.containsKey(from),
"requested location %s, which is not in the keystone admin endpoints: %s", from, regionToAdminEndpoint);
return regionToAdminEndpoint.get(from).get();
} }
} }

View File

@ -18,45 +18,33 @@ package org.jclouds.s3.functions;
import java.net.URI; import java.net.URI;
import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.jclouds.logging.Logger;
import org.jclouds.s3.Bucket; import org.jclouds.s3.Bucket;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Optional; import com.google.common.base.Optional;
/** public final class AssignCorrectHostnameForBucket implements Function<Object, URI> {
*
* @author Adrian Cole
*/
@Singleton
public class AssignCorrectHostnameForBucket implements Function<Object, URI> {
@Resource
protected Logger logger = Logger.NULL;
protected final RegionToEndpointOrProviderIfNull r2; private final RegionToEndpointOrProviderIfNull delegate;
protected final Function<String, Optional<String>> bucketToRegion; private final Function<String, Optional<String>> bucketToRegion;
@Inject @Inject
public AssignCorrectHostnameForBucket(RegionToEndpointOrProviderIfNull r2, AssignCorrectHostnameForBucket(RegionToEndpointOrProviderIfNull delegate,
@Bucket Function<String, Optional<String>> bucketToRegion) { @Bucket Function<String, Optional<String>> bucketToRegion) {
this.bucketToRegion = bucketToRegion; this.bucketToRegion = bucketToRegion;
this.r2 = r2; this.delegate = delegate;
} }
@Override @Override
public URI apply(@Nullable Object from) { public URI apply(Object from) {
String bucket = from.toString(); String bucket = from.toString();
Optional<String> region = bucketToRegion.apply(bucket); Optional<String> region = bucketToRegion.apply(bucket);
if (region.isPresent()) { if (region.isPresent()) {
return r2.apply(region.get()); return delegate.apply(region.get());
} }
return r2.apply(null); return delegate.apply(null);
} }
} }

View File

@ -19,7 +19,6 @@ package org.jclouds.s3.functions;
import java.net.URI; import java.net.URI;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.s3.Bucket; import org.jclouds.s3.Bucket;
@ -28,27 +27,22 @@ import com.google.common.base.Function;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
/** public final class DefaultEndpointThenInvalidateRegion implements Function<Object, URI> {
*
* @author Adrian Cole
*/
@Singleton
public class DefaultEndpointThenInvalidateRegion implements Function<Object, URI> {
private final Function<Object, URI> delegate;
private final LoadingCache<String, Optional<String>> bucketToRegionCache; private final LoadingCache<String, Optional<String>> bucketToRegionCache;
private final AssignCorrectHostnameForBucket r2;
@Inject @Inject
public DefaultEndpointThenInvalidateRegion(AssignCorrectHostnameForBucket r2, DefaultEndpointThenInvalidateRegion(AssignCorrectHostnameForBucket delegate,
@Bucket LoadingCache<String, Optional<String>> bucketToRegionCache) { @Bucket LoadingCache<String, Optional<String>> bucketToRegionCache) {
this.r2 = r2; this.delegate = delegate;
this.bucketToRegionCache = bucketToRegionCache; this.bucketToRegionCache = bucketToRegionCache;
} }
@Override @Override
public URI apply(@Nullable Object from) { public URI apply(@Nullable Object from) {
try { try {
return r2.apply(from); return delegate.apply(from);
} finally { } finally {
bucketToRegionCache.invalidate(from.toString()); bucketToRegionCache.invalidate(from.toString());
} }

View File

@ -21,6 +21,8 @@ import static org.testng.Assert.assertEquals;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -29,44 +31,41 @@ import com.google.common.base.Optional;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Module;
import com.google.inject.Provides;
/** @Test
* Tests behavior of {@code AssignCorrectHostnameForBucket}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire
@Test(groups = "unit", testName = "AssignCorrectHostnameForBucketTest")
public class AssignCorrectHostnameForBucketTest { public class AssignCorrectHostnameForBucketTest {
static final RegionToEndpointOrProviderIfNull REGION_TO_ENDPOINT = Guice.createInjector(new Module() {
@Override public void configure(Binder binder) {
binder.bindConstant().annotatedWith(Provider.class).to("s3");
}
@Provides @Provider Supplier<URI> defaultUri() {
return Suppliers.ofInstance(URI.create("https://s3.amazonaws.com"));
}
@Provides @Region Supplier<Map<String, Supplier<URI>>> regionToEndpoints() {
Map<String, Supplier<URI>> regionToEndpoint = ImmutableMap.of( //
"us-standard", defaultUri(), //
"us-west-1", Suppliers.ofInstance(URI.create("https://s3-us-west-1.amazonaws.com")));
return Suppliers.ofInstance(regionToEndpoint);
}
}).getInstance(RegionToEndpointOrProviderIfNull.class);
public void testWhenNoBucketRegionMappingInCache() { public void testWhenNoBucketRegionMappingInCache() {
AssignCorrectHostnameForBucket fn = new AssignCorrectHostnameForBucket(REGION_TO_ENDPOINT,
AssignCorrectHostnameForBucket fn = new AssignCorrectHostnameForBucket(new RegionToEndpointOrProviderIfNull( Functions.forMap(ImmutableMap.of("bucket", Optional.<String>absent())));
"aws-s3", Suppliers.ofInstance(URI.create("https://s3.amazonaws.com")),
Suppliers.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap.of("us-standard",
Suppliers.ofInstance(URI.create("https://s3.amazonaws.com")), "us-west-1",
Suppliers.ofInstance(URI.create("https://s3-us-west-1.amazonaws.com"))))),
Functions.forMap(ImmutableMap.<String, Optional<String>> of("bucket", Optional.<String> absent())));
assertEquals(fn.apply("bucket"), URI.create("https://s3.amazonaws.com")); assertEquals(fn.apply("bucket"), URI.create("https://s3.amazonaws.com"));
} }
public void testWhenBucketRegionMappingInCache() { public void testWhenBucketRegionMappingInCache() {
AssignCorrectHostnameForBucket fn = new AssignCorrectHostnameForBucket(REGION_TO_ENDPOINT,
AssignCorrectHostnameForBucket fn = new AssignCorrectHostnameForBucket(new RegionToEndpointOrProviderIfNull( Functions.forMap(ImmutableMap.of("bucket", Optional.of("us-west-1"))));
"aws-s3", Suppliers.ofInstance(URI.create("https://s3.amazonaws.com")),
Suppliers.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap.of("us-standard",
Suppliers.ofInstance(URI.create("https://s3.amazonaws.com")), "us-west-1",
Suppliers.ofInstance(URI.create("https://s3-us-west-1.amazonaws.com"))))),
Functions.forMap(ImmutableMap.<String, Optional<String>> of("bucket", Optional.of("us-west-1"))));
assertEquals(fn.apply("bucket"), URI.create("https://s3-us-west-1.amazonaws.com")); assertEquals(fn.apply("bucket"), URI.create("https://s3-us-west-1.amazonaws.com"));
} }
} }

View File

@ -17,37 +17,30 @@
package org.jclouds.s3.functions; package org.jclouds.s3.functions;
import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify; import static org.easymock.EasyMock.verify;
import static org.jclouds.s3.functions.AssignCorrectHostnameForBucketTest.REGION_TO_ENDPOINT;
import java.net.URI;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.base.Functions;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
/**
* @author Adrian Cole
*/
@Test(testName = "DefaultEndpointThenInvalidateRegionTest")
public class DefaultEndpointThenInvalidateRegionTest { public class DefaultEndpointThenInvalidateRegionTest {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Test @Test
void testInvalidate() throws Exception { public void testInvalidate() throws Exception {
AssignCorrectHostnameForBucket r2 = createMock(AssignCorrectHostnameForBucket.class);
LoadingCache<String, Optional<String>> bucketToRegionCache = createMock(LoadingCache.class); LoadingCache<String, Optional<String>> bucketToRegionCache = createMock(LoadingCache.class);
expect(r2.apply("mybucket")).andReturn(URI.create("http://east-url"));
bucketToRegionCache.invalidate("mybucket"); bucketToRegionCache.invalidate("mybucket");
replay(bucketToRegionCache);
replay(r2, bucketToRegionCache); AssignCorrectHostnameForBucket delegate = new AssignCorrectHostnameForBucket(REGION_TO_ENDPOINT,
Functions.forMap(ImmutableMap.of("mybucket", Optional.of("us-west-1"))));
new DefaultEndpointThenInvalidateRegion(r2, bucketToRegionCache).apply("mybucket");
verify(r2, bucketToRegionCache);
new DefaultEndpointThenInvalidateRegion(delegate, bucketToRegionCache).apply("mybucket");
verify(bucketToRegionCache);
} }
} }

View File

@ -17,40 +17,33 @@
package org.jclouds.location.functions; package org.jclouds.location.functions;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.location.Region; import org.jclouds.location.Region;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
/** public final class RegionToEndpoint implements Function<Object, URI> {
*
* @author Adrian Cole
*/
@Singleton
public class RegionToEndpoint implements Function<Object, URI> {
private final Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier; private final Supplier<Map<String, Supplier<URI>>> regionToEndpoints;
@Inject @Inject
public RegionToEndpoint(@Region Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier) { RegionToEndpoint(@Region Supplier<Map<String, Supplier<URI>>> regionToEndpoints) {
this.regionToEndpointSupplier = checkNotNull(regionToEndpointSupplier, "regionToEndpointSupplier"); this.regionToEndpoints = regionToEndpoints;
} }
@Override @Override
public URI apply(Object from) { public URI apply(Object from) {
Map<String, Supplier<URI>> regionToEndpoint = regionToEndpointSupplier.get(); Map<String, Supplier<URI>> regionToEndpoint = regionToEndpoints.get();
checkState(regionToEndpoint.size() > 0, "no region name to endpoint mappings configured!"); checkState(!regionToEndpoint.isEmpty(), "no region name to endpoint mappings configured!");
checkArgument(regionToEndpoint.containsKey(from), checkArgument(regionToEndpoint.containsKey(from),
"requested location %s, which is not in the configured locations: %s", from, regionToEndpoint); "requested location %s, which is not a configured region: %s", from, regionToEndpoint);
return regionToEndpoint.get(from).get(); return regionToEndpoint.get(from).get();
} }
} }

View File

@ -17,13 +17,11 @@
package org.jclouds.location.functions; package org.jclouds.location.functions;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Provider; import org.jclouds.location.Provider;
@ -38,25 +36,23 @@ import com.google.common.base.Supplier;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton public final class RegionToEndpointOrProviderIfNull implements Function<Object, URI> {
public class RegionToEndpointOrProviderIfNull implements Function<Object, URI> {
private final Supplier<URI> defaultUri; private final Supplier<URI> defaultUri;
private final String defaultProvider; private final String defaultProvider;
private final Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier; private final Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier;
@Inject @Inject
public RegionToEndpointOrProviderIfNull(@Provider String defaultProvider, @Provider Supplier<URI> defaultUri, RegionToEndpointOrProviderIfNull(@Provider String defaultProvider, @Provider Supplier<URI> defaultUri,
@Region Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier) { @Region Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier) {
this.defaultProvider = checkNotNull(defaultProvider, "defaultProvider"); this.defaultProvider = defaultProvider;
this.defaultUri = checkNotNull(defaultUri, "defaultUri"); this.defaultUri = defaultUri;
this.regionToEndpointSupplier = checkNotNull(regionToEndpointSupplier, "regionToEndpointSupplier"); this.regionToEndpointSupplier = regionToEndpointSupplier;
} }
@Override @Override
public URI apply(@Nullable Object from) { public URI apply(@Nullable Object from) {
if (from == null) if (from == null)
return defaultUri.get(); return defaultUri.get();
checkArgument(from instanceof String, "region is a String argument");
Map<String, Supplier<URI>> regionToEndpoint = regionToEndpointSupplier.get(); Map<String, Supplier<URI>> regionToEndpoint = regionToEndpointSupplier.get();
if (from.equals(defaultProvider)) { if (from.equals(defaultProvider)) {
if (regionToEndpoint.containsKey(from)) if (regionToEndpoint.containsKey(from))

View File

@ -17,42 +17,33 @@
package org.jclouds.location.functions; package org.jclouds.location.functions;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone; import org.jclouds.location.Zone;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
/** public final class ZoneToEndpoint implements Function<Object, URI> {
*
* @author Adrian Cole
*/
@Singleton
public class ZoneToEndpoint implements Function<Object, URI> {
private final Supplier<Map<String, Supplier<URI>>> zoneToEndpointSupplier; private final Supplier<Map<String, Supplier<URI>>> zoneToEndpoints;
@Inject @Inject
public ZoneToEndpoint(@Zone Supplier<Map<String, Supplier<URI>>> zoneToEndpointSupplier) { ZoneToEndpoint(@Zone Supplier<Map<String, Supplier<URI>>> zoneToEndpoints) {
this.zoneToEndpointSupplier = checkNotNull(zoneToEndpointSupplier, "zoneToEndpointSupplier"); this.zoneToEndpoints = zoneToEndpoints;
} }
@Override @Override
public URI apply(@Nullable Object from) { public URI apply(Object from) {
checkArgument(from != null && from instanceof String, "you must specify a zone, as a String argument"); Map<String, Supplier<URI>> zoneToEndpoint = zoneToEndpoints.get();
Map<String, Supplier<URI>> zoneToEndpoint = zoneToEndpointSupplier.get(); checkState(!zoneToEndpoint.isEmpty(), "no zone name to endpoint mappings configured!");
checkState(zoneToEndpoint.size() > 0, "no zone name to endpoint mappings configured!");
checkArgument(zoneToEndpoint.containsKey(from), checkArgument(zoneToEndpoint.containsKey(from),
"requested location %s, which is not in the configured locations: %s", from, zoneToEndpoint); "requested location %s, which is not a configured zone: %s", from, zoneToEndpoint);
return zoneToEndpoint.get(from).get(); return zoneToEndpoint.get(from).get();
} }
} }