mirror of https://github.com/apache/jclouds.git
Issue 826:support api-generated location metadata across service types, note this ensures authenticationexceptions propagate even after context creation
This commit is contained in:
parent
d4fb6bb802
commit
bdd739ad04
|
@ -27,10 +27,12 @@ import org.jclouds.byon.Node;
|
||||||
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
|
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
|
||||||
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
|
||||||
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.concurrent.SingleThreaded;
|
import org.jclouds.concurrent.SingleThreaded;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.Provider;
|
import org.jclouds.location.Provider;
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
@ -45,7 +47,7 @@ import com.google.inject.TypeLiteral;
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@SingleThreaded
|
@SingleThreaded
|
||||||
public class BYONComputeServiceContextModule extends
|
public class BYONComputeServiceContextModule extends
|
||||||
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
|
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
|
||||||
|
|
||||||
public BYONComputeServiceContextModule() {
|
public BYONComputeServiceContextModule() {
|
||||||
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
|
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
|
||||||
|
@ -60,14 +62,12 @@ public class BYONComputeServiceContextModule extends
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
|
||||||
}).to(OnlyLocationOrFirstZone.class);
|
|
||||||
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
||||||
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
bind(new TypeLiteral<Supplier<InputStream>>() {
|
bind(new TypeLiteral<Supplier<InputStream>>() {
|
||||||
}).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class);
|
}).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
bind(new TypeLiteral<Function<URI, InputStream>>() {
|
||||||
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
}).to(SupplyFromProviderURIOrNodesProperty.class);
|
||||||
|
install(new LocationsFromComputeServiceAdapterModule<NodeMetadata, Hardware, Image, Location>(){});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.location.suppliers.JustProvider;
|
import org.jclouds.location.suppliers.all.JustProvider;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
|
|
@ -31,7 +31,6 @@ import org.jclouds.blobstore.attr.ConsistencyModel;
|
||||||
import org.jclouds.blobstore.domain.Blob;
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.config.JustProviderLocationModule;
|
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
|
@ -59,7 +58,6 @@ public class TransientBlobStoreContextModule extends AbstractModule {
|
||||||
}).toInstance(containerToLocation);
|
}).toInstance(containerToLocation);
|
||||||
install(new BlobStoreObjectModule());
|
install(new BlobStoreObjectModule());
|
||||||
install(new BlobStoreMapModule());
|
install(new BlobStoreMapModule());
|
||||||
install(new JustProviderLocationModule());
|
|
||||||
bind(BlobStore.class).to(TransientBlobStore.class);
|
bind(BlobStore.class).to(TransientBlobStore.class);
|
||||||
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
|
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
|
||||||
bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class);
|
bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class);
|
||||||
|
|
|
@ -55,7 +55,6 @@ import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.json.Json;
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.location.Provider;
|
import org.jclouds.location.Provider;
|
||||||
import org.jclouds.location.config.LocationModule;
|
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
@ -81,7 +80,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
configureLocationModule();
|
|
||||||
install(new ComputeServiceTimeoutsModule());
|
install(new ComputeServiceTimeoutsModule());
|
||||||
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
|
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
|
||||||
}).to(CreateSshClientOncePortIsListeningOnNode.class);
|
}).to(CreateSshClientOncePortIsListeningOnNode.class);
|
||||||
|
@ -115,10 +113,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
install(new FactoryModuleBuilder().build(BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory.class));
|
install(new FactoryModuleBuilder().build(BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void configureLocationModule() {
|
|
||||||
install(new LocationModule(authException));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
static class RunScriptOnNodeFactoryImpl implements RunScriptOnNode.Factory {
|
static class RunScriptOnNodeFactoryImpl implements RunScriptOnNode.Factory {
|
||||||
|
|
||||||
|
@ -210,8 +204,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
return "%s-%s";
|
return "%s-%s";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected Supplier<Map<String, ? extends Image>> provideImageMap(@Memoized Supplier<Set<? extends Image>> images) {
|
protected Supplier<Map<String, ? extends Image>> provideImageMap(@Memoized Supplier<Set<? extends Image>> images) {
|
||||||
|
@ -235,12 +227,12 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Memoized
|
@Memoized
|
||||||
protected Supplier<Set<? extends Image>> supplyImageCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
protected Supplier<Set<? extends Image>> supplyImageCache(AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
final Supplier<Set<? extends Image>> imageSupplier, Injector injector) {
|
final Supplier<Set<? extends Image>> imageSupplier, Injector injector) {
|
||||||
if (shouldParseImagesOnDemand(injector)) {
|
if (shouldParseImagesOnDemand(injector)) {
|
||||||
return supplyImageCache(seconds, imageSupplier);
|
return supplyImageCache(authException, seconds, imageSupplier);
|
||||||
} else {
|
} else {
|
||||||
return supplyNonParsingImageCache(seconds, imageSupplier, injector);
|
return supplyNonParsingImageCache(authException, seconds, imageSupplier, injector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +240,7 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Supplier<Set<? extends Image>> supplyImageCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
protected Supplier<Set<? extends Image>> supplyImageCache(AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
final Supplier<Set<? extends Image>> imageSupplier) {
|
final Supplier<Set<? extends Image>> imageSupplier) {
|
||||||
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Image>>(authException,
|
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Image>>(authException,
|
||||||
seconds, new Supplier<Set<? extends Image>>() {
|
seconds, new Supplier<Set<? extends Image>>() {
|
||||||
|
@ -262,9 +254,9 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
/**
|
/**
|
||||||
* For overriding; default impl is same as {@link supplyImageCache(seconds, imageSupplier)}
|
* For overriding; default impl is same as {@link supplyImageCache(seconds, imageSupplier)}
|
||||||
*/
|
*/
|
||||||
protected Supplier<Set<? extends Image>> supplyNonParsingImageCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
protected Supplier<Set<? extends Image>> supplyNonParsingImageCache(AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
final Supplier<Set<? extends Image>> imageSupplier, Injector injector) {
|
final Supplier<Set<? extends Image>> imageSupplier, Injector injector) {
|
||||||
return supplyImageCache(seconds, imageSupplier);
|
return supplyImageCache(authException, seconds, imageSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -290,7 +282,7 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
@Memoized
|
@Memoized
|
||||||
protected Supplier<Set<? extends Hardware>> supplySizeCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
protected Supplier<Set<? extends Hardware>> supplySizeCache(AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
final Supplier<Set<? extends Hardware>> hardwareSupplier) {
|
final Supplier<Set<? extends Hardware>> hardwareSupplier) {
|
||||||
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Hardware>>(authException,
|
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Hardware>>(authException,
|
||||||
seconds, new Supplier<Set<? extends Hardware>>() {
|
seconds, new Supplier<Set<? extends Hardware>>() {
|
||||||
|
|
|
@ -20,13 +20,8 @@ package org.jclouds.compute.config;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
@ -41,54 +36,18 @@ public abstract class BindComputeSuppliersByClass extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bindImageSupplier(defineImageSupplier());
|
bindImageSupplier(defineImageSupplier());
|
||||||
bindLocationSupplier(defineLocationSupplier());
|
|
||||||
bindHardwareSupplier(defineHardwareSupplier());
|
bindHardwareSupplier(defineHardwareSupplier());
|
||||||
bindDefaultLocationSupplier(defineDefaultLocationSupplier());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Class<? extends Supplier<Set<? extends Image>>> defineImageSupplier();
|
protected abstract Class<? extends Supplier<Set<? extends Image>>> defineImageSupplier();
|
||||||
|
|
||||||
protected abstract Class<? extends Supplier<Set<? extends Hardware>>> defineHardwareSupplier();
|
protected abstract Class<? extends Supplier<Set<? extends Hardware>>> defineHardwareSupplier();
|
||||||
|
|
||||||
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
|
|
||||||
return SupplierOfLocationSet.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
static class SupplierOfLocationSet implements Supplier<Set<? extends Location>> {
|
|
||||||
private final Set<? extends Location> locations;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
SupplierOfLocationSet(Set<? extends Location> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<? extends Location> get() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
|
|
||||||
return OnlyLocationOrFirstZone.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindImageSupplier(Class<? extends Supplier<Set<? extends Image>>> clazz) {
|
protected void bindImageSupplier(Class<? extends Supplier<Set<? extends Image>>> clazz) {
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Image>>>() {
|
bind(new TypeLiteral<Supplier<Set<? extends Image>>>() {
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
}).to(clazz).in(Scopes.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void bindLocationSupplier(Class<? extends Supplier<Set<? extends Location>>> clazz) {
|
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
|
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindDefaultLocationSupplier(Class<? extends Supplier<Location>> clazz) {
|
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindHardwareSupplier(Class<? extends Supplier<Set<? extends Hardware>>> clazz) {
|
protected void bindHardwareSupplier(Class<? extends Supplier<Set<? extends Hardware>>> clazz) {
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Hardware>>>() {
|
bind(new TypeLiteral<Supplier<Set<? extends Hardware>>>() {
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
}).to(clazz).in(Scopes.SINGLETON);
|
||||||
|
|
|
@ -23,15 +23,12 @@ import static com.google.common.base.Predicates.notNull;
|
||||||
import static com.google.common.collect.Iterables.filter;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
import static com.google.common.collect.Iterables.transform;
|
import static com.google.common.collect.Iterables.transform;
|
||||||
import static com.google.inject.util.Types.newParameterizedType;
|
import static com.google.inject.util.Types.newParameterizedType;
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.collect.Memoized;
|
|
||||||
import org.jclouds.collect.TransformingSetSupplier;
|
import org.jclouds.collect.TransformingSetSupplier;
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
|
@ -50,11 +47,12 @@ import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
|
import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
import org.jclouds.location.suppliers.LocationsSupplier;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
@ -83,24 +81,37 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
|
||||||
asyncClientType))).in(Scopes.SINGLETON);
|
asyncClientType))).in(Scopes.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void configureLocationModule() {
|
* install this, if you want to use your computeservice adapter to handle locations. Note that if
|
||||||
// configuring below
|
* you do this, you'll want to instantiate a subclass to prevent type erasure.
|
||||||
}
|
*
|
||||||
|
* ex.
|
||||||
|
* <pre>
|
||||||
|
* install(new LocationsFromComputeServiceAdapterModule<NodeMetadata, Hardware, Image, Location>(){});
|
||||||
|
* </pre>
|
||||||
|
* not
|
||||||
|
* <pre>
|
||||||
|
* install(new LocationsFromComputeServiceAdapterModule<NodeMetadata, Hardware, Image, Location>());
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static class LocationsFromComputeServiceAdapterModule<N, H, I, L> extends AbstractModule {
|
||||||
|
|
||||||
@Provides
|
@Override
|
||||||
@Singleton
|
protected void configure() {
|
||||||
@Memoized
|
}
|
||||||
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
|
||||||
final ComputeServiceAdapter<N, H, I, L> adapter, final Function<L, Location> transformer) {
|
@Provides
|
||||||
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException,
|
@Singleton
|
||||||
seconds, new Supplier<Set<? extends Location>>() {
|
protected LocationsSupplier supplyLocationsFromComputeServiceAdapter(
|
||||||
@Override
|
final ComputeServiceAdapter<N, H, I, L> adapter, final Function<L, Location> transformer) {
|
||||||
public Set<? extends Location> get() {
|
return new LocationsSupplier() {
|
||||||
return ImmutableSet.<Location> copyOf(transform(filter(adapter.listLocations(), notNull()),
|
@Override
|
||||||
transformer));
|
public Set<? extends Location> get() {
|
||||||
}
|
Iterable<L> locations = filter(adapter.listLocations(), notNull());
|
||||||
});
|
return ImmutableSet.<Location> copyOf(transform(locations, transformer));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -111,7 +122,7 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<H> get() {
|
public Iterable<H> get() {
|
||||||
return filter(adapter.listHardwareProfiles(), notNull());
|
return adapter.listHardwareProfiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
}, transformer);
|
}, transformer);
|
||||||
|
|
|
@ -42,7 +42,7 @@ import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
import org.jclouds.domain.LoginCredentials;
|
||||||
import org.jclouds.location.suppliers.JustProvider;
|
import org.jclouds.location.suppliers.all.JustProvider;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
|
|
@ -25,12 +25,8 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.concurrent.SingleThreaded;
|
import org.jclouds.concurrent.SingleThreaded;
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.TypeLiteral;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -54,8 +50,6 @@ public class StubComputeServiceContextModule extends
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new StubComputeServiceDependenciesModule());
|
install(new StubComputeServiceDependenciesModule());
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
|
||||||
}).to(OnlyLocationOrFirstZone.class);
|
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.concurrent;
|
package org.jclouds.concurrent;
|
||||||
|
|
||||||
|
import static com.google.common.base.Throwables.propagate;
|
||||||
|
import static com.google.common.collect.Iterables.any;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
import static com.google.common.collect.Maps.newHashMap;
|
import static com.google.common.collect.Maps.newHashMap;
|
||||||
|
import static org.jclouds.util.Throwables2.containsThrowable;
|
||||||
|
import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
@ -29,20 +34,18 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
|
||||||
import com.google.common.annotations.Beta;
|
import com.google.common.annotations.Beta;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +85,7 @@ public class FutureIterables {
|
||||||
return transformParallel(fromIterable, function, exec, maxTime, logger, logPrefix, retryHandler, maxRetries);
|
return transformParallel(fromIterable, function, exec, maxTime, logger, logPrefix, retryHandler, maxRetries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static <F, T> Iterable<T> transformParallel(Iterable<F> fromIterable,
|
public static <F, T> Iterable<T> transformParallel(Iterable<F> fromIterable,
|
||||||
Function<? super F, Future<T>> function, ExecutorService exec, @Nullable Long maxTime, Logger logger,
|
Function<? super F, Future<T>> function, ExecutorService exec, @Nullable Long maxTime, Logger logger,
|
||||||
String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) {
|
String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) {
|
||||||
|
@ -93,7 +97,7 @@ public class FutureIterables {
|
||||||
responses.put(from, function.apply(from));
|
responses.put(from, function.apply(from));
|
||||||
}
|
}
|
||||||
exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix);
|
exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix);
|
||||||
if (exceptions.size() > 0) {
|
if (exceptions.size() > 0 && !any(exceptions.values(), containsThrowable(AuthorizationException.class))) {
|
||||||
fromIterable = exceptions.keySet();
|
fromIterable = exceptions.keySet();
|
||||||
retryHandler.imposeBackoffExponentialDelay(delayStart, 2, i + 1, maxRetries,
|
retryHandler.imposeBackoffExponentialDelay(delayStart, 2, i + 1, maxRetries,
|
||||||
String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions));
|
String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions));
|
||||||
|
@ -101,8 +105,10 @@ public class FutureIterables {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//make sure we propagate any authorization exception so that we don't lock out accounts
|
||||||
if (exceptions.size() > 0)
|
if (exceptions.size() > 0)
|
||||||
throw new RuntimeException(String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions));
|
return propagateAuthorizationOrOriginalException(new TransformParallelException((Map) responses, exceptions,
|
||||||
|
logPrefix));
|
||||||
|
|
||||||
return unwrap(responses.values());
|
return unwrap(responses.values());
|
||||||
}
|
}
|
||||||
|
@ -116,7 +122,7 @@ public class FutureIterables {
|
||||||
final AtomicInteger complete = new AtomicInteger(0);
|
final AtomicInteger complete = new AtomicInteger(0);
|
||||||
final AtomicInteger errors = new AtomicInteger(0);
|
final AtomicInteger errors = new AtomicInteger(0);
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
final Map<T, Exception> errorMap = Maps.newHashMap();
|
final Map<T, Exception> errorMap = newHashMap();
|
||||||
for (final java.util.Map.Entry<T, ? extends Future<?>> future : responses.entrySet()) {
|
for (final java.util.Map.Entry<T, ? extends Future<?>> future : responses.entrySet()) {
|
||||||
Futures.makeListenable(future.getValue(), exec).addListener(new Runnable() {
|
Futures.makeListenable(future.getValue(), exec).addListener(new Runnable() {
|
||||||
|
|
||||||
|
@ -157,21 +163,21 @@ public class FutureIterables {
|
||||||
String message = message(logPrefix, total, complete.get(), errors.get(), start);
|
String message = message(logPrefix, total, complete.get(), errors.get(), start);
|
||||||
TimeoutException exception = new TimeoutException(message);
|
TimeoutException exception = new TimeoutException(message);
|
||||||
logger.error(exception, message);
|
logger.error(exception, message);
|
||||||
Throwables.propagate(exception);
|
propagate(exception);
|
||||||
}
|
}
|
||||||
return errorMap;
|
return errorMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> Iterable<T> unwrap(Iterable<Future<T>> values) {
|
public static <T> Iterable<T> unwrap(Iterable<Future<T>> values) {
|
||||||
return Iterables.transform(values, new Function<Future<T>, T>() {
|
return transform(values, new Function<Future<T>, T>() {
|
||||||
@Override
|
@Override
|
||||||
public T apply(Future<T> from) {
|
public T apply(Future<T> from) {
|
||||||
try {
|
try {
|
||||||
return from.get();
|
return from.get();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Throwables.propagate(e);
|
propagate(e);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
Throwables.propagate(e);
|
propagate(e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.concurrent;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A failure occurred while concurrently operating on an Iterable
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public final class TransformParallelException extends RuntimeException {
|
||||||
|
|
||||||
|
/** The serialVersionUID */
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final Map<?, Future<?>> success;
|
||||||
|
private final Map<?, Exception> exceptions;
|
||||||
|
|
||||||
|
public TransformParallelException(Map<?, Future<?>> success, Map<?, Exception> exceptions, String messagePrefix) {
|
||||||
|
super(String.format("error %s: %s", messagePrefix, exceptions));
|
||||||
|
this.success = ImmutableMap.copyOf(success);
|
||||||
|
this.exceptions = ImmutableMap.copyOf(exceptions);
|
||||||
|
initCause(Iterables.get(exceptions.values(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Elements that performed the transform without error
|
||||||
|
*/
|
||||||
|
public Map<?, Future<?>> getSuccessfulToValue() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Elements that failed during the transform
|
||||||
|
*/
|
||||||
|
public Map<?, Exception> getFromToException() {
|
||||||
|
return exceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.functions;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
|
||||||
|
public class JoinOnK2<K, K2, V> implements Function<Map<K, Supplier<Set<K2>>>, Map<K2, Supplier<V>>> {
|
||||||
|
private final Supplier<Map<K2, Supplier<V>>> regionToEndpointSupplier;
|
||||||
|
|
||||||
|
public JoinOnK2(Supplier<Map<K2, Supplier<V>>> regionToEndpointSupplier) {
|
||||||
|
this.regionToEndpointSupplier = regionToEndpointSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<K2, Supplier<V>> apply(Map<K, Supplier<Set<K2>>> regionToZones) {
|
||||||
|
Map<K2, Supplier<V>> regionToEndpoint = regionToEndpointSupplier.get();
|
||||||
|
Builder<K2, Supplier<V>> builder = ImmutableMap.<K2, Supplier<V>> builder();
|
||||||
|
for (Entry<K, Supplier<Set<K2>>> entry : regionToZones.entrySet()) {
|
||||||
|
for (K2 zone : entry.getValue().get()) {
|
||||||
|
builder.put(zone, regionToEndpoint.get(entry.getKey()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,8 @@ package org.jclouds.location.config;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
@ -28,6 +30,20 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.location.Iso3166;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.Region;
|
||||||
|
import org.jclouds.location.Zone;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitRegionIdSupplier;
|
||||||
|
import org.jclouds.location.suppliers.LocationIdToIso3166CodesSupplier;
|
||||||
|
import org.jclouds.location.suppliers.LocationsSupplier;
|
||||||
|
import org.jclouds.location.suppliers.ProviderURISupplier;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdsSupplier;
|
||||||
|
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
||||||
|
import org.jclouds.location.suppliers.ZoneIdsSupplier;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||||
|
|
||||||
|
@ -36,35 +52,100 @@ import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* All of these are memoized as locations do not change often at runtime. Note that we take care to
|
||||||
|
* propagate authorization exceptions. this is so that we do not lock out the account.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class LocationModule extends AbstractModule {
|
public class LocationModule extends AbstractModule {
|
||||||
protected final AtomicReference<AuthorizationException> authException;
|
|
||||||
|
|
||||||
public LocationModule() {
|
|
||||||
this(new AtomicReference<AuthorizationException>());
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocationModule(AtomicReference<AuthorizationException> authException) {
|
|
||||||
this.authException = authException;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Memoized
|
|
||||||
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
|
||||||
final Supplier<Set<? extends Location>> locationSupplier) {
|
|
||||||
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
|
|
||||||
new Supplier<Set<? extends Location>>() {
|
|
||||||
@Override
|
|
||||||
public Set<? extends Location> get() {
|
|
||||||
return locationSupplier.get();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Iso3166
|
||||||
|
protected Supplier<Map<String, Supplier<Set<String>>>> isoCodesSupplier(
|
||||||
|
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
LocationIdToIso3166CodesSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Provider
|
||||||
|
protected Supplier<URI> provideProvider(AtomicReference<AuthorizationException> authException,
|
||||||
|
@Named(PROPERTY_SESSION_INTERVAL) long seconds, ProviderURISupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Supplier<Location> implicitLocationSupplier(AtomicReference<AuthorizationException> authException,
|
||||||
|
@Named(PROPERTY_SESSION_INTERVAL) long seconds, ImplicitLocationSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
// TODO: we should eventually get rid of memoized as an annotation, as it is confusing
|
||||||
|
@Memoized
|
||||||
|
protected Supplier<Set<? extends Location>> memoizedLocationsSupplier(
|
||||||
|
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
LocationsSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Region
|
||||||
|
protected Supplier<Set<String>> regionIdsSupplier(AtomicReference<AuthorizationException> authException,
|
||||||
|
@Named(PROPERTY_SESSION_INTERVAL) long seconds, RegionIdsSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Region
|
||||||
|
protected Supplier<Map<String, Supplier<URI>>> regionIdToURISupplier(
|
||||||
|
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
RegionIdToURISupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Region
|
||||||
|
protected Supplier<String> implicitRegionIdSupplier(AtomicReference<AuthorizationException> authException,
|
||||||
|
@Named(PROPERTY_SESSION_INTERVAL) long seconds, ImplicitRegionIdSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Zone
|
||||||
|
protected Supplier<Set<String>> regionIdsSupplier(
|
||||||
|
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
ZoneIdsSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Zone
|
||||||
|
protected Supplier<Map<String, Supplier<Set<String>>>> regionIdToZoneIdsSupplier(
|
||||||
|
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
RegionIdToZoneIdsSupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Zone
|
||||||
|
protected Supplier<Map<String, Supplier<URI>>> zoneIdToURISupplier(
|
||||||
|
AtomicReference<AuthorizationException> authException, @Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
||||||
|
ZoneIdToURISupplier uncached) {
|
||||||
|
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, seconds, uncached);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,81 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.location.config;
|
|
||||||
|
|
||||||
import static org.jclouds.location.reference.LocationConstants.ENDPOINT;
|
|
||||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
|
|
||||||
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.location.Region;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
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.region.{@code regionId}.endpoint
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class ProvideRegionToURIViaProperties implements javax.inject.Provider<Map<String, URI>> {
|
|
||||||
|
|
||||||
private final Injector injector;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected ProvideRegionToURIViaProperties(Injector injector) {
|
|
||||||
this.injector = injector;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Region
|
|
||||||
@Override
|
|
||||||
public Map<String, URI> get() {
|
|
||||||
try {
|
|
||||||
String regionString = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGIONS)));
|
|
||||||
Builder<String, URI> regions = ImmutableMap.<String, URI> builder();
|
|
||||||
for (String region : Splitter.on(',').split(regionString)) {
|
|
||||||
String regionUri = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGION + "." + region
|
|
||||||
+ "." + ENDPOINT)));
|
|
||||||
regions.put(region, URI.create(regionUri));
|
|
||||||
}
|
|
||||||
return regions.build();
|
|
||||||
} catch (ConfigurationException e) {
|
|
||||||
logger.warn("no region name to endpoint mappings configured!");
|
|
||||||
return ImmutableMap.of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,6 +32,7 @@ import org.jclouds.location.Provider;
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a uri corresponding to the name of the region (passed argument).
|
* Return a uri corresponding to the name of the region (passed argument).
|
||||||
|
@ -41,25 +42,26 @@ import com.google.common.base.Function;
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RegionToEndpointOrProviderIfNull implements Function<Object, URI> {
|
public class RegionToEndpointOrProviderIfNull implements Function<Object, URI> {
|
||||||
private final URI defaultUri;
|
private final Supplier<URI> defaultUri;
|
||||||
private final String defaultProvider;
|
private final String defaultProvider;
|
||||||
private final Map<String, URI> regionToEndpoint;
|
private final Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RegionToEndpointOrProviderIfNull(@Provider String defaultProvider, @Provider URI defaultUri,
|
public RegionToEndpointOrProviderIfNull(@Provider String defaultProvider, @Provider Supplier<URI> defaultUri,
|
||||||
@Region Map<String, URI> regionToEndpoint) {
|
@Region Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier) {
|
||||||
this.defaultProvider = checkNotNull(defaultProvider, "defaultProvider");
|
this.defaultProvider = checkNotNull(defaultProvider, "defaultProvider");
|
||||||
this.defaultUri = checkNotNull(defaultUri, "defaultUri");
|
this.defaultUri = checkNotNull(defaultUri, "defaultUri");
|
||||||
this.regionToEndpoint = checkNotNull(regionToEndpoint, "regionToEndpoint");
|
this.regionToEndpointSupplier = checkNotNull(regionToEndpointSupplier, "regionToEndpointSupplier");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI apply(@Nullable Object from) {
|
public URI apply(@Nullable Object from) {
|
||||||
if (from == null || from.equals(defaultProvider))
|
if (from == null || from.equals(defaultProvider))
|
||||||
return defaultUri;
|
return defaultUri.get();
|
||||||
checkArgument(from instanceof String, "region is a String argument");
|
checkArgument(from instanceof String, "region is a String argument");
|
||||||
|
Map<String, Supplier<URI>> regionToEndpoint = regionToEndpointSupplier.get();
|
||||||
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 in the configured locations: %s", from, regionToEndpoint);
|
||||||
return regionToEndpoint.get(from);
|
return regionToEndpoint.get(from).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,8 +18,8 @@
|
||||||
*/
|
*/
|
||||||
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.checkState;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.*;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -31,6 +31,7 @@ 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -39,17 +40,20 @@ import com.google.common.base.Function;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ZoneToEndpoint implements Function<Object, URI> {
|
public class ZoneToEndpoint implements Function<Object, URI> {
|
||||||
|
|
||||||
private final Map<String, URI> zoneToEndpoint;
|
private final Supplier<Map<String, Supplier<URI>>> zoneToEndpointSupplier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ZoneToEndpoint(@Zone Map<String, URI> zoneToEndpoint) {
|
public ZoneToEndpoint(@Zone Supplier<Map<String, Supplier<URI>>> zoneToEndpointSupplier) {
|
||||||
this.zoneToEndpoint = checkNotNull(zoneToEndpoint, "zoneToEndpoint");
|
this.zoneToEndpointSupplier = checkNotNull(zoneToEndpointSupplier, "zoneToEndpointSupplier");
|
||||||
checkArgument(zoneToEndpoint.size() > 0, "no zone name to endpoint mappings configured!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI apply(@Nullable Object from) {
|
public URI apply(@Nullable Object from) {
|
||||||
checkArgument(from != null && from instanceof String, "you must specify a zone, as a String argument");
|
checkArgument(from != null && from instanceof String, "you must specify a zone, as a String argument");
|
||||||
return zoneToEndpoint.get(from);
|
Map<String, Supplier<URI>> zoneToEndpoint = zoneToEndpointSupplier.get();
|
||||||
|
checkState(zoneToEndpoint.size() > 0, "no zone name to endpoint mappings configured!");
|
||||||
|
checkArgument(zoneToEndpoint.containsKey(from),
|
||||||
|
"requested location %s, which is not in the configured locations: %s", from, zoneToEndpoint);
|
||||||
|
return zoneToEndpoint.get(from).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,6 +33,24 @@ import com.google.common.base.Predicate;
|
||||||
*/
|
*/
|
||||||
public class LocationPredicates {
|
public class LocationPredicates {
|
||||||
|
|
||||||
|
public static Predicate<Location> isProvider() {
|
||||||
|
return IsProvider.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
static enum IsProvider implements Predicate<Location> {
|
||||||
|
INSTANCE;
|
||||||
|
@Override
|
||||||
|
public boolean apply(Location input) {
|
||||||
|
return input.getScope() == LocationScope.PROVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "isProvider()";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Predicate<Location> isZone() {
|
public static Predicate<Location> isZone() {
|
||||||
return IsZone.INSTANCE;
|
return IsZone.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,40 +16,19 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.config;
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.suppliers.JustProvider;
|
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstRegionOptionallyMatchingRegionId;
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
|
||||||
import org.jclouds.rest.AuthorizationException;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class JustProviderLocationModule extends LocationModule {
|
@ImplementedBy(OnlyLocationOrFirstRegionOptionallyMatchingRegionId.class)
|
||||||
public JustProviderLocationModule() {
|
public interface ImplicitLocationSupplier extends Supplier<Location> {
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JustProviderLocationModule(AtomicReference<AuthorizationException> authException) {
|
|
||||||
super(authException);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
|
|
||||||
}).to(JustProvider.class);
|
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
|
||||||
}).to(OnlyLocationOrFirstZone.class);
|
|
||||||
super.configure();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.implicit.GetRegionIdMatchingProviderURIOrNull;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(GetRegionIdMatchingProviderURIOrNull.class)
|
||||||
|
public interface ImplicitRegionIdSupplier extends Supplier<String> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.LocationIdToIso3166CodesFromConfiguration;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(LocationIdToIso3166CodesFromConfiguration.class)
|
||||||
|
public interface LocationIdToIso3166CodesSupplier extends Supplier<Map<String, Supplier<Set<String>>>> {
|
||||||
|
|
||||||
|
}
|
|
@ -16,31 +16,21 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.config;
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstRegionOptionallyMatchingRegionId;
|
import org.jclouds.location.suppliers.all.ZoneToRegionToProviderOrJustProvider;
|
||||||
import org.jclouds.location.suppliers.RegionToProviderOrJustProvider;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class RegionsLocationModule extends LocationModule {
|
@ImplementedBy(ZoneToRegionToProviderOrJustProvider.class)
|
||||||
|
public interface LocationsSupplier extends Supplier<Set<? extends Location>> {
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
|
|
||||||
}).to(RegionToProviderOrJustProvider.class);
|
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
|
||||||
}).to(OnlyLocationOrFirstRegionOptionallyMatchingRegionId.class);
|
|
||||||
super.configure();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.ProviderURIFromConfiguration;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
@ImplementedBy(ProviderURIFromConfiguration.class)
|
||||||
|
public interface ProviderURISupplier extends Supplier<URI> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.RegionIdToURIFromConfigurationOrDefaultToProvider;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(RegionIdToURIFromConfigurationOrDefaultToProvider.class)
|
||||||
|
public interface RegionIdToURISupplier extends Supplier<Map<String, Supplier<URI>>> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.RegionIdToZoneIdsFromConfiguration;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(RegionIdToZoneIdsFromConfiguration.class)
|
||||||
|
public interface RegionIdToZoneIdsSupplier extends Supplier<Map<String, Supplier<Set<String>>>> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.RegionIdsFromConfiguration;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(RegionIdsFromConfiguration.class)
|
||||||
|
public interface RegionIdsSupplier extends Supplier<Set<String>> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.ZoneIdToURIFromConfigurationOrDefaultToProvider;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(ZoneIdToURIFromConfigurationOrDefaultToProvider.class)
|
||||||
|
public interface ZoneIdToURISupplier extends Supplier<Map<String, Supplier<URI>>> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.fromconfig.ZoneIdsFromConfiguration;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.inject.ImplementedBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@ImplementedBy(ZoneIdsFromConfiguration.class)
|
||||||
|
public interface ZoneIdsSupplier extends Supplier<Set<String>> {
|
||||||
|
|
||||||
|
}
|
|
@ -1,89 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.location.suppliers;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static com.google.common.collect.Maps.uniqueIndex;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import org.jclouds.domain.LocationBuilder;
|
|
||||||
import org.jclouds.domain.LocationScope;
|
|
||||||
import org.jclouds.location.Iso3166;
|
|
||||||
import org.jclouds.location.Provider;
|
|
||||||
import org.jclouds.location.Zone;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.ImmutableSet.Builder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class ZoneToRegionToProviderOrJustProvider extends RegionToProviderOrJustProvider {
|
|
||||||
private final Map<String, String> zoneToRegion;
|
|
||||||
private Map<String, Set<String>> isoCodesById;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
ZoneToRegionToProviderOrJustProvider(@Iso3166 Set<String> isoCodes, @Provider String providerName,
|
|
||||||
@Provider URI endpoint, @Iso3166 Map<String, Set<String>> isoCodesById,
|
|
||||||
@Zone Map<String, String> zoneToRegion) {
|
|
||||||
super(isoCodes, providerName, endpoint, ImmutableSet.copyOf(checkNotNull(zoneToRegion, "zoneToRegion").values()),
|
|
||||||
isoCodesById);
|
|
||||||
this.zoneToRegion = zoneToRegion;
|
|
||||||
this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<? extends Location> get() {
|
|
||||||
Builder<Location> locations = buildJustProviderOrRegions();
|
|
||||||
ImmutableMap<String, Location> idToLocation = uniqueIndex(locations.build(), new Function<Location, String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(Location from) {
|
|
||||||
return from.getId();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (zoneToRegion.size() == 1)
|
|
||||||
return locations.build();
|
|
||||||
for (String zone : zoneToRegion.keySet()) {
|
|
||||||
Location parent = idToLocation.get(zoneToRegion.get(zone));
|
|
||||||
LocationBuilder builder = new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent(
|
|
||||||
parent);
|
|
||||||
if (isoCodesById.containsKey(zone))
|
|
||||||
builder.iso3166Codes(isoCodesById.get(zone));
|
|
||||||
// be cautious.. only inherit iso codes if the parent is a region
|
|
||||||
// regions may be added dynamically, and we prefer to inherit an
|
|
||||||
// empty set of codes from a region, then a provider, whose code
|
|
||||||
// are likely hard-coded.
|
|
||||||
else if (parent.getScope() == LocationScope.REGION)
|
|
||||||
builder.iso3166Codes(parent.getIso3166Codes());
|
|
||||||
locations.add(builder.build());
|
|
||||||
}
|
|
||||||
return locations.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.all;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
@ -42,20 +42,20 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class JustProvider implements Supplier<Set<? extends Location>> {
|
public class JustProvider implements Supplier<Set<? extends Location>> {
|
||||||
private final String providerName;
|
private final String providerName;
|
||||||
private final URI endpoint;
|
private final URI endpointSupplier;
|
||||||
private final Set<String> isoCodes;
|
private final Set<String> isoCodesSupplier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public JustProvider(@Provider String providerName, @Provider URI endpoint, @Iso3166 Set<String> isoCodes) {
|
public JustProvider(@Provider String providerName, @Provider URI endpointSupplier, @Iso3166 Set<String> isoCodesSupplier) {
|
||||||
this.providerName = checkNotNull(providerName, "providerName");
|
this.providerName = checkNotNull(providerName, "providerName");
|
||||||
this.endpoint = checkNotNull(endpoint, "endpoint");
|
this.endpointSupplier = checkNotNull(endpointSupplier, "endpoint");
|
||||||
this.isoCodes = checkNotNull(isoCodes, "isoCodes");
|
this.isoCodesSupplier = checkNotNull(isoCodesSupplier, "isoCodes");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends Location> get() {
|
public Set<? extends Location> get() {
|
||||||
return ImmutableSet.of(new LocationBuilder().scope(LocationScope.PROVIDER).id(providerName)
|
return ImmutableSet.of(new LocationBuilder().scope(LocationScope.PROVIDER).id(providerName)
|
||||||
.description(endpoint.toASCIIString()).iso3166Codes(isoCodes).build());
|
.description(endpointSupplier.toASCIIString()).iso3166Codes(isoCodesSupplier).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,11 +16,10 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.all;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -31,9 +30,9 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.location.Iso3166;
|
import org.jclouds.location.Iso3166;
|
||||||
import org.jclouds.location.Provider;
|
|
||||||
import org.jclouds.location.Region;
|
import org.jclouds.location.Region;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.ImmutableSet.Builder;
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
@ -43,37 +42,36 @@ import com.google.common.collect.ImmutableSet.Builder;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class RegionToProviderOrJustProvider extends JustProvider {
|
public class RegionToProviderOrJustProvider implements Supplier<Set<? extends Location>> {
|
||||||
private final Set<String> regions;
|
private final JustProvider justProvider;
|
||||||
private final Map<String, Set<String>> isoCodesById;
|
private final Supplier<Set<String>> regionsSupplier;
|
||||||
|
private final Supplier<Map<String, Supplier<Set<String>>>> isoCodesByIdSupplier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RegionToProviderOrJustProvider(@Iso3166 Set<String> isoCodes, @Provider String providerName,
|
public RegionToProviderOrJustProvider(JustProvider justProvider, @Region Supplier<Set<String>> regionsSupplier,
|
||||||
@Provider URI endpoint, @Region Set<String> regions, @Iso3166 Map<String, Set<String>> isoCodesById) {
|
@Iso3166 Supplier<Map<String, Supplier<Set<String>>>> isoCodesByIdSupplier) {
|
||||||
super(providerName, endpoint, isoCodes);
|
this.justProvider = checkNotNull(justProvider, "justProvider");
|
||||||
this.regions = checkNotNull(regions, "regions");
|
this.regionsSupplier = checkNotNull(regionsSupplier, "regionsSupplier");
|
||||||
this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById");
|
this.isoCodesByIdSupplier = checkNotNull(isoCodesByIdSupplier, "isoCodesByIdSupplier");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<? extends Location> get() {
|
public Set<? extends Location> get() {
|
||||||
return buildJustProviderOrRegions().build();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Builder<Location> buildJustProviderOrRegions() {
|
|
||||||
Builder<Location> locations = ImmutableSet.builder();
|
Builder<Location> locations = ImmutableSet.builder();
|
||||||
Location provider = Iterables.getOnlyElement(super.get());
|
Location provider = Iterables.getOnlyElement(justProvider.get());
|
||||||
|
Set<String> regions = regionsSupplier.get();
|
||||||
|
Map<String, Supplier<Set<String>>> isoCodesById = isoCodesByIdSupplier.get();
|
||||||
if (regions.size() == 0)
|
if (regions.size() == 0)
|
||||||
return locations.add(provider);
|
return locations.add(provider).build();
|
||||||
else
|
else
|
||||||
for (String region : regions) {
|
for (String region : regions) {
|
||||||
LocationBuilder builder = new LocationBuilder().scope(LocationScope.REGION).id(region).description(region)
|
LocationBuilder builder = new LocationBuilder().scope(LocationScope.REGION).id(region).description(region)
|
||||||
.parent(provider);
|
.parent(provider);
|
||||||
if (isoCodesById.containsKey(region))
|
if (isoCodesById.containsKey(region))
|
||||||
builder.iso3166Codes(isoCodesById.get(region));
|
builder.iso3166Codes(isoCodesById.get(region).get());
|
||||||
locations.add(builder.build());
|
locations.add(builder.build());
|
||||||
}
|
}
|
||||||
return locations;
|
return locations.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.all;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LocationBuilder;
|
||||||
|
import org.jclouds.domain.LocationScope;
|
||||||
|
import org.jclouds.location.Iso3166;
|
||||||
|
import org.jclouds.location.Zone;
|
||||||
|
import org.jclouds.location.predicates.LocationPredicates;
|
||||||
|
import org.jclouds.location.suppliers.LocationsSupplier;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
import com.google.common.collect.Sets.SetView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ZoneToRegionToProviderOrJustProvider implements LocationsSupplier {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final RegionToProviderOrJustProvider regionToProviderOrJustProvider;
|
||||||
|
private final Supplier<Set<String>> zoneIdsSupplier;
|
||||||
|
private final Supplier<Map<String, Supplier<Set<String>>>> isoCodesByIdSupplier;
|
||||||
|
private final Supplier<Map<String, Supplier<Set<String>>>> regionIdToZoneIdsSupplier;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ZoneToRegionToProviderOrJustProvider(RegionToProviderOrJustProvider regionToProviderOrJustProvider,
|
||||||
|
@Zone Supplier<Set<String>> zoneIdsSupplier,
|
||||||
|
@Iso3166 Supplier<Map<String, Supplier<Set<String>>>> isoCodesByIdSupplier,
|
||||||
|
@Zone Supplier<Map<String, Supplier<Set<String>>>> regionIdToZoneIdsSupplier) {
|
||||||
|
this.regionToProviderOrJustProvider = checkNotNull(regionToProviderOrJustProvider,
|
||||||
|
"regionToProviderOrJustProvider");
|
||||||
|
this.zoneIdsSupplier = checkNotNull(zoneIdsSupplier, "zoneIdsSupplier");
|
||||||
|
this.regionIdToZoneIdsSupplier = checkNotNull(regionIdToZoneIdsSupplier, "regionIdToZoneIdsSupplier");
|
||||||
|
this.isoCodesByIdSupplier = checkNotNull(isoCodesByIdSupplier, "isoCodesByIdSupplier");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<? extends Location> get() {
|
||||||
|
Set<? extends Location> regionsOrJustProvider = regionToProviderOrJustProvider.get();
|
||||||
|
Set<String> zoneIds = zoneIdsSupplier.get();
|
||||||
|
if (zoneIds.size() == 0)
|
||||||
|
return regionsOrJustProvider;
|
||||||
|
Map<String, Location> zoneIdToParent = setParentOfZoneToRegionOrProvider(zoneIds, regionsOrJustProvider);
|
||||||
|
Map<String, Supplier<Set<String>>> isoCodesById = isoCodesByIdSupplier.get();
|
||||||
|
|
||||||
|
Builder<Location> locations = ImmutableSet.builder();
|
||||||
|
locations.addAll(regionsOrJustProvider);
|
||||||
|
for (String zoneId : zoneIdToParent.keySet()) {
|
||||||
|
Location parent = zoneIdToParent.get(zoneId);
|
||||||
|
LocationBuilder builder = new LocationBuilder().scope(LocationScope.ZONE).id(zoneId).description(zoneId)
|
||||||
|
.parent(parent);
|
||||||
|
if (isoCodesById.containsKey(zoneId))
|
||||||
|
builder.iso3166Codes(isoCodesById.get(zoneId).get());
|
||||||
|
// be cautious.. only inherit iso codes if the parent is a region
|
||||||
|
// regions may be added dynamically, and we prefer to inherit an
|
||||||
|
// empty set of codes from a region, then a provider, whose code
|
||||||
|
// are likely hard-coded.
|
||||||
|
else if (parent.getScope() == LocationScope.REGION)
|
||||||
|
builder.iso3166Codes(parent.getIso3166Codes());
|
||||||
|
locations.add(builder.build());
|
||||||
|
}
|
||||||
|
return locations.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Location> setParentOfZoneToRegionOrProvider(Set<String> zoneIds,
|
||||||
|
Set<? extends Location> locations) {
|
||||||
|
// mutable, so that we can query current state when adding. safe as its temporary
|
||||||
|
Map<String, Location> zoneIdToParent = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
|
Location provider = Iterables.find(locations, LocationPredicates.isProvider(), null);
|
||||||
|
if (locations.size() == 1 && provider != null) {
|
||||||
|
for (String zone : zoneIds)
|
||||||
|
zoneIdToParent.put(zone, provider);
|
||||||
|
} else {
|
||||||
|
// note that we only call regionIdToZoneIdsSupplier if there are region locations present
|
||||||
|
// they cannot be, if the above is true
|
||||||
|
Map<String, Supplier<Set<String>>> regionIdToZoneIds = regionIdToZoneIdsSupplier.get();
|
||||||
|
for (Location region : Iterables.filter(locations, LocationPredicates.isRegion())) {
|
||||||
|
provider = region.getParent();
|
||||||
|
if (regionIdToZoneIds.containsKey(region.getId())) {
|
||||||
|
for (String zoneId : regionIdToZoneIds.get(region.getId()).get())
|
||||||
|
zoneIdToParent.put(zoneId, region);
|
||||||
|
} else {
|
||||||
|
logger.debug("no zones configured for region: %s", region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetView<String> orphans = Sets.difference(zoneIds, zoneIdToParent.keySet());
|
||||||
|
if (orphans.size() > 0) {
|
||||||
|
// any unmatched zones should have their parents set to the provider
|
||||||
|
checkState(
|
||||||
|
provider != null,
|
||||||
|
"cannot configure zones %s as we need a parent, and the only available location [%s] is not a provider",
|
||||||
|
zoneIds, locations);
|
||||||
|
for (String orphanedZoneId : orphans)
|
||||||
|
zoneIdToParent.put(orphanedZoneId, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkState(zoneIdToParent.keySet().containsAll(zoneIds), "orphaned zones: %s ", Sets.difference(zoneIds,
|
||||||
|
zoneIdToParent.keySet()));
|
||||||
|
return zoneIdToParent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.config;
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
|
import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
|
||||||
|
@ -30,45 +30,48 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.location.Iso3166;
|
import org.jclouds.location.Iso3166;
|
||||||
|
import org.jclouds.location.suppliers.LocationIdToIso3166CodesSupplier;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableMap.Builder;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* looks for properties bound to the naming conventions jclouds.region.
|
* looks for properties bound to the naming conventions jclouds.region. {@code regionId}
|
||||||
* {@code regionId} .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes
|
* .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class ProvideIso3166CodesByLocationIdViaProperties implements javax.inject.Provider<Map<String, Set<String>>> {
|
public class LocationIdToIso3166CodesFromConfiguration implements LocationIdToIso3166CodesSupplier {
|
||||||
|
|
||||||
private final Function<Predicate<String>, Map<String, String>> filterStringsBoundByName;
|
private final Function<Predicate<String>, Map<String, String>> filterStringsBoundByName;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ProvideIso3166CodesByLocationIdViaProperties(
|
public LocationIdToIso3166CodesFromConfiguration(
|
||||||
Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
|
Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
|
||||||
this.filterStringsBoundByName = checkNotNull(filterStringsBoundByName, "filterStringsBoundByName");
|
this.filterStringsBoundByName = checkNotNull(filterStringsBoundByName, "filterStringsBoundByName");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Iso3166
|
@Iso3166
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Set<String>> get() {
|
public Map<String, Supplier<Set<String>>> get() {
|
||||||
Map<String, String> stringsBoundWithRegionOrZonePrefix = filterStringsBoundByName.apply(new Predicate<String>() {
|
Map<String, String> stringsBoundWithRegionOrZonePrefix = filterStringsBoundByName.apply(new Predicate<String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(String input) {
|
public boolean apply(String input) {
|
||||||
return input.startsWith(PROPERTY_REGION) || input.startsWith(PROPERTY_ZONE);
|
return (input.startsWith(PROPERTY_REGION) || input.startsWith(PROPERTY_ZONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
Builder<String, Set<String>> codes = ImmutableMap.<String, Set<String>> builder();
|
Builder<String, Supplier<Set<String>>> codes = ImmutableMap.<String, Supplier<Set<String>>> builder();
|
||||||
for (String key : ImmutableSet.of(PROPERTY_REGION, PROPERTY_ZONE)) {
|
for (String key : ImmutableSet.of(PROPERTY_REGION, PROPERTY_ZONE)) {
|
||||||
String regionOrZoneString = stringsBoundWithRegionOrZonePrefix.get(key + "s");
|
String regionOrZoneString = stringsBoundWithRegionOrZonePrefix.get(key + "s");
|
||||||
if (regionOrZoneString == null)
|
if (regionOrZoneString == null)
|
||||||
|
@ -76,7 +79,8 @@ public class ProvideIso3166CodesByLocationIdViaProperties implements javax.injec
|
||||||
for (String region : Splitter.on(',').split(regionOrZoneString)) {
|
for (String region : Splitter.on(',').split(regionOrZoneString)) {
|
||||||
String isoCodes = stringsBoundWithRegionOrZonePrefix.get(key + "." + region + "." + ISO3166_CODES);
|
String isoCodes = stringsBoundWithRegionOrZonePrefix.get(key + "." + region + "." + ISO3166_CODES);
|
||||||
if (isoCodes != null)
|
if (isoCodes != null)
|
||||||
codes.put(region, ImmutableSet.copyOf(Splitter.on(',').split(isoCodes)));
|
codes.put(region, Suppliers.<Set<String>> ofInstance(ImmutableSet.copyOf(Splitter.on(',')
|
||||||
|
.split(isoCodes))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return codes.build();
|
return codes.build();
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.ENDPOINT;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class LocationIdToURIFromConfigurationOrDefaultToProvider implements Supplier<Map<String, Supplier<URI>>>{
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
protected final ValueOfConfigurationKeyOrNull config;
|
||||||
|
protected final Supplier<Set<String>> locationIds;
|
||||||
|
protected final Supplier<URI> providerURI;
|
||||||
|
protected final String configPrefix;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public LocationIdToURIFromConfigurationOrDefaultToProvider(ValueOfConfigurationKeyOrNull config, @Provider Supplier<URI> providerURI, @Assisted Supplier<Set<String>> locationIds,
|
||||||
|
@Assisted String configPrefix) {
|
||||||
|
this.config = config;
|
||||||
|
this.locationIds = locationIds;
|
||||||
|
this.providerURI = providerURI;
|
||||||
|
this.configPrefix = configPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Supplier<URI>> get() {
|
||||||
|
Builder<String, Supplier<URI>> locations = ImmutableMap.<String, Supplier<URI>> builder();
|
||||||
|
for (String location : locationIds.get()) {
|
||||||
|
String configKey = configPrefix + "." + location + "." + ENDPOINT;
|
||||||
|
String locationUri = config.apply(configKey);
|
||||||
|
if (locationUri == null) {
|
||||||
|
logger.debug("config key %s not present, defaulting to %s", configKey, providerURI);
|
||||||
|
locations.put(location, providerURI);
|
||||||
|
} else {
|
||||||
|
locations.put(location, Suppliers.ofInstance(URI.create(locationUri)));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return locations.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.ProviderURISupplier;
|
||||||
|
import org.jclouds.rest.suppliers.URIFromStringSupplier;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ProviderURIFromConfiguration extends URIFromStringSupplier implements
|
||||||
|
ProviderURISupplier {
|
||||||
|
@Inject
|
||||||
|
protected ProviderURIFromConfiguration(@Named(PROPERTY_ENDPOINT) String endpoint) {
|
||||||
|
super(checkNotNull(endpoint, PROPERTY_ENDPOINT));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.Region;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdToURISupplier;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* looks for properties bound to the naming convention jclouds.region.{@code regionId}.endpoint
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class RegionIdToURIFromConfigurationOrDefaultToProvider extends LocationIdToURIFromConfigurationOrDefaultToProvider implements RegionIdToURISupplier {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RegionIdToURIFromConfigurationOrDefaultToProvider(ValueOfConfigurationKeyOrNull config, @Provider Supplier<URI> providerURI,
|
||||||
|
@Region Supplier<Set<String>> regionIds) {
|
||||||
|
super(config, providerURI, regionIds, PROPERTY_REGION);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.Region;
|
||||||
|
import org.jclouds.location.Zone;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* looks for properties bound to the naming convention jclouds.location.region.{@code regionId}
|
||||||
|
* .zones
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class RegionIdToZoneIdsFromConfiguration implements RegionIdToZoneIdsSupplier {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final ValueOfConfigurationKeyOrNull config;
|
||||||
|
private final String provider;
|
||||||
|
private final Supplier<Set<String>> regionsSupplier;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RegionIdToZoneIdsFromConfiguration(ValueOfConfigurationKeyOrNull config, @Provider String provider,
|
||||||
|
@Region Supplier<Set<String>> regionsSupplier) {
|
||||||
|
this.config = config;
|
||||||
|
this.provider = provider;
|
||||||
|
this.regionsSupplier = regionsSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Zone
|
||||||
|
@Override
|
||||||
|
public Map<String, Supplier<Set<String>>> get() {
|
||||||
|
Set<String> regions = regionsSupplier.get();
|
||||||
|
if (regions.size() == 0) {
|
||||||
|
logger.debug("no regions configured for provider %s", provider);
|
||||||
|
return ImmutableMap.of();
|
||||||
|
}
|
||||||
|
Builder<String, Supplier<Set<String>>> regionToZones = ImmutableMap.<String, Supplier<Set<String>>> builder();
|
||||||
|
for (String region : regions) {
|
||||||
|
String configKey = PROPERTY_REGION + "." + region + ".zones";
|
||||||
|
String zones = config.apply(configKey);
|
||||||
|
if (zones == null)
|
||||||
|
logger.debug("config key %s not present", configKey);
|
||||||
|
else
|
||||||
|
regionToZones.put(region, Suppliers.<Set<String>> ofInstance(ImmutableSet.copyOf(Splitter.on(',').split(
|
||||||
|
zones))));
|
||||||
|
}
|
||||||
|
return regionToZones.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.suppliers.RegionIdsSupplier;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* looks for properties bound to the naming convention jclouds.regions
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class RegionIdsFromConfiguration extends SplitConfigurationKey implements RegionIdsSupplier {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected RegionIdsFromConfiguration(ValueOfConfigurationKeyOrNull config, @Provider String provider) {
|
||||||
|
super(config, provider, PROPERTY_REGIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class SplitConfigurationKey implements Supplier<Set<String>> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
protected final ValueOfConfigurationKeyOrNull config;
|
||||||
|
protected final String provider;
|
||||||
|
protected final String configKey;
|
||||||
|
|
||||||
|
public SplitConfigurationKey(ValueOfConfigurationKeyOrNull config, @Provider String provider,
|
||||||
|
@Assisted String configKey) {
|
||||||
|
this.config = config;
|
||||||
|
this.provider = provider;
|
||||||
|
this.configKey = configKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> get() {
|
||||||
|
String regionString = config.apply(configKey);
|
||||||
|
if (regionString == null) {
|
||||||
|
logger.debug("no %s configured for provider %s", configKey, provider);
|
||||||
|
return ImmutableSet.of();
|
||||||
|
} else {
|
||||||
|
return ImmutableSet.copyOf(Splitter.on(',').split(regionString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONE;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.Zone;
|
||||||
|
import org.jclouds.location.suppliers.ZoneIdToURISupplier;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* looks for properties bound to the naming convention jclouds.zone.{@code zoneId}.endpoint
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ZoneIdToURIFromConfigurationOrDefaultToProvider extends LocationIdToURIFromConfigurationOrDefaultToProvider implements ZoneIdToURISupplier {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected ZoneIdToURIFromConfigurationOrDefaultToProvider(ValueOfConfigurationKeyOrNull config, @Provider Supplier<URI> providerURI,
|
||||||
|
@Zone Supplier<Set<String>> zoneIds) {
|
||||||
|
super(config, providerURI, zoneIds, PROPERTY_ZONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.fromconfig;
|
||||||
|
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONES;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.suppliers.ZoneIdsSupplier;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* looks for properties bound to the naming convention jclouds.zones
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class ZoneIdsFromConfiguration extends SplitConfigurationKey implements ZoneIdsSupplier {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected ZoneIdsFromConfiguration(ValueOfConfigurationKeyOrNull config, @Provider String provider) {
|
||||||
|
super(config, provider, PROPERTY_ZONES);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.location.suppliers.implicit;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.location.Region;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitRegionIdSupplier;
|
||||||
|
import org.jclouds.suppliers.SupplyKeyMatchingValueOrNull;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class GetRegionIdMatchingProviderURIOrNull extends SupplyKeyMatchingValueOrNull<String, URI> implements
|
||||||
|
ImplicitRegionIdSupplier {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public GetRegionIdMatchingProviderURIOrNull(@Region Supplier<Map<String, Supplier<URI>>> supplier,
|
||||||
|
@Provider Supplier<URI> providerUri) {
|
||||||
|
super(supplier, providerUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.implicit;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||||
|
@ -34,9 +34,9 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.location.Region;
|
import org.jclouds.location.Region;
|
||||||
import org.jclouds.location.functions.ToIdAndScope;
|
import org.jclouds.location.functions.ToIdAndScope;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
@ -47,22 +47,23 @@ import com.google.common.collect.Iterables;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionId implements Supplier<Location> {
|
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionId implements ImplicitLocationSupplier {
|
||||||
|
private final Supplier<String> regionSupplier;
|
||||||
private final Predicate<Location> locationPredicate;
|
|
||||||
private final Supplier<Set<? extends Location>> locationsSupplier;
|
private final Supplier<Set<? extends Location>> locationsSupplier;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
OnlyLocationOrFirstRegionOptionallyMatchingRegionId(@Nullable @Region String region,
|
OnlyLocationOrFirstRegionOptionallyMatchingRegionId(@Region Supplier<String> regionSupplier,
|
||||||
@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
|
@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
|
||||||
this.locationPredicate = region == null ? Predicates.<Location>or(isZone(), isRegion())
|
this.regionSupplier = checkNotNull(regionSupplier, "regionSupplier");
|
||||||
: isZoneOrRegionWhereRegionIdEquals(region);
|
|
||||||
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier");
|
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Singleton
|
@Singleton
|
||||||
public Location get() {
|
public Location get() {
|
||||||
|
String region = regionSupplier.get();
|
||||||
|
Predicate<Location> locationPredicate = region == null ? Predicates.<Location>or(isZone(), isRegion())
|
||||||
|
: isZoneOrRegionWhereRegionIdEquals(region);
|
||||||
Set<? extends Location> locations = locationsSupplier.get();
|
Set<? extends Location> locations = locationsSupplier.get();
|
||||||
if (locationsSupplier.get().size() == 1)
|
if (locationsSupplier.get().size() == 1)
|
||||||
return getOnlyElement(locationsSupplier.get());
|
return getOnlyElement(locationsSupplier.get());
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.implicit;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.collect.Iterables.find;
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
@ -33,6 +33,7 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.functions.ToIdAndScope;
|
import org.jclouds.location.functions.ToIdAndScope;
|
||||||
|
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ import com.google.common.base.Supplier;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class OnlyLocationOrFirstZone implements Supplier<Location> {
|
public class OnlyLocationOrFirstZone implements ImplicitLocationSupplier {
|
||||||
|
|
||||||
private final Supplier<Set<? extends Location>> locationsSupplier;
|
private final Supplier<Set<? extends Location>> locationsSupplier;
|
||||||
|
|
|
@ -19,78 +19,44 @@
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Predicates.equalTo;
|
|
||||||
import static com.google.common.base.Predicates.instanceOf;
|
import static com.google.common.base.Predicates.instanceOf;
|
||||||
import static com.google.common.base.Predicates.not;
|
|
||||||
import static com.google.common.base.Splitter.on;
|
|
||||||
import static com.google.common.collect.Iterables.addAll;
|
import static com.google.common.collect.Iterables.addAll;
|
||||||
import static com.google.common.collect.Iterables.any;
|
import static com.google.common.collect.Iterables.any;
|
||||||
import static com.google.common.collect.Iterables.filter;
|
|
||||||
import static com.google.inject.Scopes.SINGLETON;
|
import static com.google.inject.Scopes.SINGLETON;
|
||||||
import static com.google.inject.util.Types.newParameterizedType;
|
import static com.google.inject.util.Types.newParameterizedType;
|
||||||
import static org.jclouds.Constants.PROPERTY_API;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_PROVIDER;
|
|
||||||
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.concurrent.MoreExecutors;
|
import org.jclouds.concurrent.MoreExecutors;
|
||||||
import org.jclouds.concurrent.SingleThreaded;
|
import org.jclouds.concurrent.SingleThreaded;
|
||||||
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
import org.jclouds.http.config.ConfiguresHttpCommandExecutorService;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.internal.FilterStringsBoundToInjectorByName;
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.lifecycle.config.LifeCycleModule;
|
import org.jclouds.lifecycle.config.LifeCycleModule;
|
||||||
import org.jclouds.location.Iso3166;
|
|
||||||
import org.jclouds.location.Provider;
|
|
||||||
import org.jclouds.location.config.ProvideIso3166CodesByLocationIdViaProperties;
|
|
||||||
import org.jclouds.logging.config.LoggingModule;
|
import org.jclouds.logging.config.LoggingModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
import org.jclouds.rest.annotations.Api;
|
import org.jclouds.rest.config.BindPropertiesToAnnotations;
|
||||||
import org.jclouds.rest.annotations.ApiVersion;
|
|
||||||
import org.jclouds.rest.annotations.BuildVersion;
|
|
||||||
import org.jclouds.rest.annotations.Credential;
|
|
||||||
import org.jclouds.rest.annotations.Identity;
|
|
||||||
import org.jclouds.rest.config.CredentialStoreModule;
|
import org.jclouds.rest.config.CredentialStoreModule;
|
||||||
import org.jclouds.rest.config.RestClientModule;
|
import org.jclouds.rest.config.RestClientModule;
|
||||||
import org.jclouds.rest.config.RestModule;
|
import org.jclouds.rest.config.RestModule;
|
||||||
import org.jclouds.rest.internal.RestContextImpl;
|
import org.jclouds.rest.internal.RestContextImpl;
|
||||||
import org.jclouds.util.Maps2;
|
|
||||||
import org.nnsoft.guice.rocoto.Rocoto;
|
import org.nnsoft.guice.rocoto.Rocoto;
|
||||||
import org.nnsoft.guice.rocoto.configuration.ConfigurationModule;
|
import org.nnsoft.guice.rocoto.configuration.ConfigurationModule;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.util.concurrent.ExecutionList;
|
import com.google.common.util.concurrent.ExecutionList;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.Provides;
|
|
||||||
import com.google.inject.Stage;
|
import com.google.inject.Stage;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
@ -108,115 +74,6 @@ import com.google.inject.TypeLiteral;
|
||||||
* @see RestContext
|
* @see RestContext
|
||||||
*/
|
*/
|
||||||
public class RestContextBuilder<S, A> {
|
public class RestContextBuilder<S, A> {
|
||||||
|
|
||||||
static class BindPropertiesToAnnotations extends ConfigurationModule {
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Named("TIMEOUTS")
|
|
||||||
protected Map<String, Long> timeouts(Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
|
|
||||||
Map<String, String> stringBoundWithTimeoutPrefix = filterStringsBoundByName.apply(new Predicate<String>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(String input) {
|
|
||||||
return input.startsWith(PROPERTY_TIMEOUTS_PREFIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Map<String, Long> longsByName = Maps.transformValues(stringBoundWithTimeoutPrefix, new Function<String, Long>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long apply(String input) {
|
|
||||||
return Long.valueOf(String.valueOf(input));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return Maps2.transformKeys(longsByName, new Function<String, String>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String apply(String input) {
|
|
||||||
return input.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Provider
|
|
||||||
protected String bindProvider(@Named(PROPERTY_PROVIDER) String in){
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Provider
|
|
||||||
protected URI bindProviderEndpoint(@Named(PROPERTY_ENDPOINT) String in){
|
|
||||||
return URI.create(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Iso3166
|
|
||||||
protected Set<String> bindIsoCodes(@Named(PROPERTY_ISO3166_CODES) String in){
|
|
||||||
return ImmutableSet.copyOf(filter(on(',').split( in),
|
|
||||||
not(equalTo(""))));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Api
|
|
||||||
protected String bindApi(@Named(PROPERTY_API) String in){
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@ApiVersion
|
|
||||||
protected String bindApiVersion(@Named(PROPERTY_API_VERSION) String in){
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@BuildVersion
|
|
||||||
protected String bindBuildVersion(@Named(PROPERTY_BUILD_VERSION) String in){
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Identity
|
|
||||||
protected String bindIdentity(@Named(PROPERTY_IDENTITY) String in){
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Credential
|
|
||||||
@Nullable
|
|
||||||
protected String bindCredential(ValueOfConfigurationKeyOrNull config){
|
|
||||||
return config.apply(PROPERTY_CREDENTIAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Provider
|
|
||||||
protected Credentials bindProviderCredentials(@Identity String identity, @Nullable @Credential String credential){
|
|
||||||
return new Credentials(identity, credential);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void bindConfigurations() {
|
|
||||||
bind(new TypeLiteral<Function<Predicate<String>, Map<String, String>>>() {
|
|
||||||
}).to(FilterStringsBoundToInjectorByName.class);
|
|
||||||
bind(new TypeLiteral<Map<String, Set<String>>>() {
|
|
||||||
}).annotatedWith(Iso3166.class).toProvider(ProvideIso3166CodesByLocationIdViaProperties.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Properties properties;
|
protected Properties properties;
|
||||||
protected List<Module> modules = new ArrayList<Module>(3);
|
protected List<Module> modules = new ArrayList<Module>(3);
|
||||||
protected Class<A> asyncClientType;
|
protected Class<A> asyncClientType;
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.rest.config;
|
||||||
|
|
||||||
|
import static com.google.common.base.Predicates.equalTo;
|
||||||
|
import static com.google.common.base.Predicates.not;
|
||||||
|
import static com.google.common.base.Splitter.on;
|
||||||
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_API;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_BUILD_VERSION;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_CREDENTIAL;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_IDENTITY;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_PROVIDER;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_TIMEOUTS_PREFIX;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.config.ValueOfConfigurationKeyOrNull;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.internal.FilterStringsBoundToInjectorByName;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.location.Iso3166;
|
||||||
|
import org.jclouds.location.Provider;
|
||||||
|
import org.jclouds.rest.annotations.Api;
|
||||||
|
import org.jclouds.rest.annotations.ApiVersion;
|
||||||
|
import org.jclouds.rest.annotations.BuildVersion;
|
||||||
|
import org.jclouds.rest.annotations.Credential;
|
||||||
|
import org.jclouds.rest.annotations.Identity;
|
||||||
|
import org.jclouds.util.Maps2;
|
||||||
|
import org.nnsoft.guice.rocoto.configuration.ConfigurationModule;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
|
public class BindPropertiesToAnnotations extends ConfigurationModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Named("TIMEOUTS")
|
||||||
|
protected Map<String, Long> timeouts(Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
|
||||||
|
Map<String, String> stringBoundWithTimeoutPrefix = filterStringsBoundByName.apply(new Predicate<String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return input.startsWith(PROPERTY_TIMEOUTS_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, Long> longsByName = Maps.transformValues(stringBoundWithTimeoutPrefix, new Function<String, Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long apply(String input) {
|
||||||
|
return Long.valueOf(String.valueOf(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return Maps2.transformKeys(longsByName, new Function<String, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(String input) {
|
||||||
|
return input.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Provider
|
||||||
|
protected String bindProvider(@Named(PROPERTY_PROVIDER) String in){
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Provider
|
||||||
|
protected URI bindProviderEndpoint(@Named(PROPERTY_ENDPOINT) String in){
|
||||||
|
return URI.create(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Iso3166
|
||||||
|
protected Set<String> bindIsoCodes(@Named(PROPERTY_ISO3166_CODES) String in){
|
||||||
|
return ImmutableSet.copyOf(filter(on(',').split( in),
|
||||||
|
not(equalTo(""))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Api
|
||||||
|
protected String bindApi(@Named(PROPERTY_API) String in){
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@ApiVersion
|
||||||
|
protected String bindApiVersion(@Named(PROPERTY_API_VERSION) String in){
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@BuildVersion
|
||||||
|
protected String bindBuildVersion(@Named(PROPERTY_BUILD_VERSION) String in){
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Identity
|
||||||
|
protected String bindIdentity(@Named(PROPERTY_IDENTITY) String in){
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Credential
|
||||||
|
@Nullable
|
||||||
|
protected String bindCredential(ValueOfConfigurationKeyOrNull config){
|
||||||
|
return config.apply(PROPERTY_CREDENTIAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
@Provider
|
||||||
|
protected Credentials bindProviderCredentials(@Identity String identity, @Nullable @Credential String credential){
|
||||||
|
return new Credentials(identity, credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindConfigurations() {
|
||||||
|
bind(new TypeLiteral<Function<Predicate<String>, Map<String, String>>>() {
|
||||||
|
}).to(FilterStringsBoundToInjectorByName.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,21 +18,22 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.rest.config;
|
package org.jclouds.rest.config;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.http.RequiresHttp;
|
import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.internal.ClassMethodArgs;
|
import org.jclouds.internal.ClassMethodArgs;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.location.config.LocationModule;
|
||||||
import org.jclouds.location.Provider;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.jclouds.rest.internal.RestContextImpl;
|
import org.jclouds.rest.internal.RestContextImpl;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
@ -49,10 +50,13 @@ import com.google.inject.util.Types;
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
public class RestClientModule<S, A> extends AbstractModule {
|
public class RestClientModule<S, A> extends AbstractModule {
|
||||||
|
public final static TypeLiteral<Supplier<URI>> URI_SUPPLIER_TYPE = new TypeLiteral<Supplier<URI>>() {
|
||||||
|
};
|
||||||
|
|
||||||
protected final Class<A> asyncClientType;
|
protected final Class<A> asyncClientType;
|
||||||
protected final Class<S> syncClientType;
|
protected final Class<S> syncClientType;
|
||||||
protected final Map<Class<?>, Class<?>> delegates;
|
protected final Map<Class<?>, Class<?>> delegates;
|
||||||
|
protected final AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
|
||||||
|
|
||||||
public RestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
|
public RestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
|
||||||
Map<Class<?>, Class<?>> delegates) {
|
Map<Class<?>, Class<?>> delegates) {
|
||||||
|
@ -66,9 +70,15 @@ public class RestClientModule<S, A> extends AbstractModule {
|
||||||
.<Class<?>, Class<?>> of(syncClientType, asyncClientType));
|
.<Class<?>, Class<?>> of(syncClientType, asyncClientType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void installLocations() {
|
||||||
|
install(new LocationModule());
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
// this will help short circuit scenarios that can otherwise lock out users
|
||||||
|
bind(new TypeLiteral<AtomicReference<AuthorizationException>>(){}).toInstance(authException);
|
||||||
// Ensures the restcontext can be looked up without generic types.
|
// Ensures the restcontext can be looked up without generic types.
|
||||||
bind(new TypeLiteral<RestContext>() {
|
bind(new TypeLiteral<RestContext>() {
|
||||||
}).to(
|
}).to(
|
||||||
|
@ -82,6 +92,7 @@ public class RestClientModule<S, A> extends AbstractModule {
|
||||||
bindClient();
|
bindClient();
|
||||||
bindErrorHandlers();
|
bindErrorHandlers();
|
||||||
bindRetryHandlers();
|
bindRetryHandlers();
|
||||||
|
installLocations();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -139,6 +139,7 @@ import com.google.common.base.Functions;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
|
@ -759,7 +760,10 @@ public class RestAnnotationProcessor<T> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: change to LoadingCache<ClassMethodArgs, URI> and move this logic to the CacheLoader.
|
private final static TypeLiteral<Supplier<URI>> uriSupplierLiteral = new TypeLiteral<Supplier<URI>>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: change to LoadingCache<ClassMethodArgs, URI> and move this logic to the CacheLoader.
|
||||||
public static URI getEndpointFor(Method method, Object[] args, Injector injector) throws ExecutionException {
|
public static URI getEndpointFor(Method method, Object[] args, Injector injector) throws ExecutionException {
|
||||||
URI endpoint = getEndpointInParametersOrNull(method, args, injector);
|
URI endpoint = getEndpointInParametersOrNull(method, args, injector);
|
||||||
if (endpoint == null) {
|
if (endpoint == null) {
|
||||||
|
@ -771,18 +775,22 @@ public class RestAnnotationProcessor<T> {
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("no annotations on class or method: " + method);
|
throw new IllegalStateException("no annotations on class or method: " + method);
|
||||||
}
|
}
|
||||||
endpoint = injector.getInstance(Key.get(URI.class, annotation.value()));
|
endpoint = injector.getInstance(Key.get(uriSupplierLiteral, annotation.value())).get();
|
||||||
}
|
}
|
||||||
return addHostIfMissing(endpoint, injector.getInstance(Key.get(URI.class, org.jclouds.location.Provider.class)));
|
URI providerEndpoint = injector.getInstance(Key.get(uriSupplierLiteral, org.jclouds.location.Provider.class))
|
||||||
|
.get();
|
||||||
|
return addHostIfMissing(endpoint, providerEndpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static URI addHostIfMissing(URI original, URI withHost) {
|
public static URI addHostIfMissing(URI original, URI withHost) {
|
||||||
checkNotNull(withHost,"URI witHost cannot be null");
|
checkNotNull(withHost, "URI witHost cannot be null");
|
||||||
checkArgument(withHost.getHost()!=null, "URI withHost must have host:"+withHost);
|
checkArgument(withHost.getHost() != null, "URI withHost must have host:" + withHost);
|
||||||
|
|
||||||
if(original == null) return null;
|
if (original == null)
|
||||||
if (original.getHost() != null) return original;
|
return null;
|
||||||
return withHost.resolve(original);
|
if (original.getHost() != null)
|
||||||
|
return original;
|
||||||
|
return withHost.resolve(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final TypeLiteral<ListenableFuture<Boolean>> futureBooleanLiteral = new TypeLiteral<ListenableFuture<Boolean>>() {
|
public static final TypeLiteral<ListenableFuture<Boolean>> futureBooleanLiteral = new TypeLiteral<ListenableFuture<Boolean>>() {
|
||||||
|
|
|
@ -47,6 +47,11 @@ public class MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> imp
|
||||||
private final Supplier<T> delegate;
|
private final Supplier<T> delegate;
|
||||||
private final long seconds;
|
private final long seconds;
|
||||||
|
|
||||||
|
public static <T> MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> create(
|
||||||
|
AtomicReference<AuthorizationException> authException, long seconds, Supplier<T> delegate) {
|
||||||
|
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T>(authException, seconds, delegate);
|
||||||
|
}
|
||||||
|
|
||||||
public MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(
|
public MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier(
|
||||||
AtomicReference<AuthorizationException> authException, long seconds, Supplier<T> delegate) {
|
AtomicReference<AuthorizationException> authException, long seconds, Supplier<T> delegate) {
|
||||||
this.delegate = memoizeWithExpirationOnAbsoluteInterval(new RetryOnTimeOutExceptionSupplier<T>(
|
this.delegate = memoizeWithExpirationOnAbsoluteInterval(new RetryOnTimeOutExceptionSupplier<T>(
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.rest.suppliers;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
|
||||||
|
public class URIFromStringSupplier implements Supplier<URI> {
|
||||||
|
|
||||||
|
private final URI endpoint;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected URIFromStringSupplier(String uri) {
|
||||||
|
this.endpoint = URI.create(checkNotNull(uri, "uri"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URI get() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.suppliers;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
|
import com.google.common.collect.ImmutableBiMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows you to lazy discover a key by value. This is useful for example in service discovery,
|
||||||
|
* where you need to see what the "current" service name is based on a map of service names to
|
||||||
|
* endpoints. <h3>note</h3> take care to memoize this using {@link Suppliers#memoize(Supplier)}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class SupplyKeyMatchingValueOrNull<K, V> implements Supplier<K> {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final Supplier<Map<K, Supplier<V>>> supplier;
|
||||||
|
private final Supplier<V> valueSupplier;
|
||||||
|
|
||||||
|
public SupplyKeyMatchingValueOrNull(Supplier<Map<K, Supplier<V>>> supplier, Supplier<V> valueSupplier) {
|
||||||
|
this.valueSupplier = valueSupplier;
|
||||||
|
this.supplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public K get() {
|
||||||
|
V uri = valueSupplier.get();
|
||||||
|
// eagerly get all the values, so we can see which is default
|
||||||
|
Map<K, V> map = Maps.transformValues(supplier.get(), Suppliers.<V> supplierFunction());
|
||||||
|
K region = ImmutableBiMap.copyOf(map).inverse().get(uri);
|
||||||
|
if (region == null && map.size() > 0) {
|
||||||
|
logger.warn("failed to find key for value %s in %s; choosing first: %s", uri, map, region);
|
||||||
|
region = Iterables.get(map.keySet(), 0);
|
||||||
|
}
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,19 @@ import com.google.common.collect.Multimap;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class Maps2 {
|
public class Maps2 {
|
||||||
|
public static <K> Function<Map<K, ?>, Set<K>> keySetFunction() {
|
||||||
|
return new Function<Map<K, ?>, Set<K>>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<K> apply(Map<K, ?> arg0) {
|
||||||
|
return arg0.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "keySet()";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static <K, V> Map<K, V> convertUnsafe(Multimap<K, V> in) {
|
public static <K, V> Map<K, V> convertUnsafe(Multimap<K, V> in) {
|
||||||
LinkedHashMap<K, V> out = Maps.newLinkedHashMap();
|
LinkedHashMap<K, V> out = Maps.newLinkedHashMap();
|
||||||
|
|
|
@ -26,8 +26,10 @@ import java.io.Serializable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.io.OutputSupplier;
|
import com.google.common.io.OutputSupplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +38,21 @@ import com.google.common.io.OutputSupplier;
|
||||||
*/
|
*/
|
||||||
public class Suppliers2 {
|
public class Suppliers2 {
|
||||||
|
|
||||||
|
public static <X> Function<X, Supplier<X>> ofInstanceFunction() {
|
||||||
|
return new Function<X, Supplier<X>>(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<X> apply(X arg0) {
|
||||||
|
return Suppliers.ofInstance(arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return "Suppliers.ofInstance()";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* converts an {@link OutputStream} to an {@link OutputSupplier}
|
* converts an {@link OutputStream} to an {@link OutputSupplier}
|
||||||
*
|
*
|
||||||
|
@ -52,9 +69,11 @@ public class Suppliers2 {
|
||||||
/**
|
/**
|
||||||
* See Supplier.memoizeWithExpiration.
|
* See Supplier.memoizeWithExpiration.
|
||||||
*
|
*
|
||||||
* Difference between this impl and v11.0 is that we fix http://code.google.com/p/guava-libraries/issues/detail?id=857.
|
* Difference between this impl and v11.0 is that we fix
|
||||||
|
* http://code.google.com/p/guava-libraries/issues/detail?id=857.
|
||||||
*/
|
*/
|
||||||
public static <T> Supplier<T> memoizeWithExpirationOnAbsoluteInterval(Supplier<T> delegate, long duration, TimeUnit unit) {
|
public static <T> Supplier<T> memoizeWithExpirationOnAbsoluteInterval(Supplier<T> delegate, long duration,
|
||||||
|
TimeUnit unit) {
|
||||||
return new ExpiringMemoizingSupplier<T>(delegate, duration, unit);
|
return new ExpiringMemoizingSupplier<T>(delegate, duration, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +105,8 @@ public class Suppliers2 {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (nanos == expirationNanos) { // recheck for lost race
|
if (nanos == expirationNanos) { // recheck for lost race
|
||||||
|
|
||||||
// Set value to null prior to retrieving new val, so old and new are not held in memory simultaneously
|
// Set value to null prior to retrieving new val, so old and new are not held in
|
||||||
|
// memory simultaneously
|
||||||
value = null;
|
value = null;
|
||||||
|
|
||||||
T t = delegate.get();
|
T t = delegate.get();
|
||||||
|
|
|
@ -25,11 +25,13 @@ import static com.google.common.collect.Iterables.find;
|
||||||
|
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.TransformParallelException;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.InsufficientResourcesException;
|
import org.jclouds.rest.InsufficientResourcesException;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.inject.CreationException;
|
import com.google.inject.CreationException;
|
||||||
import com.google.inject.ProvisionException;
|
import com.google.inject.ProvisionException;
|
||||||
|
@ -42,10 +44,26 @@ import com.google.inject.spi.Message;
|
||||||
*/
|
*/
|
||||||
public class Throwables2 {
|
public class Throwables2 {
|
||||||
|
|
||||||
|
public static <T extends Throwable> Predicate<Throwable> containsThrowable(final Class<T> throwableType) {
|
||||||
|
return new Predicate<Throwable>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Throwable input) {
|
||||||
|
return getFirstThrowableOfType(input, throwableType) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "containsThrowable()";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T extends Throwable> T getFirstThrowableOfType(Throwable from, Class<T> clazz) {
|
public static <T extends Throwable> T getFirstThrowableOfType(Throwable from, Class<T> clazz) {
|
||||||
if (from instanceof ProvisionException)
|
if (from instanceof ProvisionException)
|
||||||
return getFirstThrowableOfType(ProvisionException.class.cast(from), clazz);
|
return getFirstThrowableOfType(ProvisionException.class.cast(from), clazz);
|
||||||
|
else if (from instanceof TransformParallelException)
|
||||||
|
return getFirstThrowableOfType(TransformParallelException.class.cast(from), clazz);
|
||||||
else if (from instanceof CreationException)
|
else if (from instanceof CreationException)
|
||||||
return getFirstThrowableOfType(CreationException.class.cast(from), clazz);
|
return getFirstThrowableOfType(CreationException.class.cast(from), clazz);
|
||||||
try {
|
try {
|
||||||
|
@ -55,12 +73,23 @@ public class Throwables2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends Throwable> T getFirstThrowableOfType(TransformParallelException e, Class<T> clazz) {
|
||||||
|
for (Exception exception : e.getFromToException().values()) {
|
||||||
|
T cause = getFirstThrowableOfType(exception, clazz);
|
||||||
|
if (cause != null)
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T extends Throwable> T getFirstThrowableOfType(ProvisionException e, Class<T> clazz) {
|
public static <T extends Throwable> T getFirstThrowableOfType(ProvisionException e, Class<T> clazz) {
|
||||||
for (Message message : e.getErrorMessages()) {
|
for (Message message : e.getErrorMessages()) {
|
||||||
if (message.getCause() != null) {
|
if (message.getCause() != null) {
|
||||||
T cause = getFirstThrowableOfType(message.getCause(), clazz);
|
T cause = getFirstThrowableOfType(message.getCause(), clazz);
|
||||||
if (cause instanceof ProvisionException)
|
if (cause instanceof ProvisionException)
|
||||||
return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz);
|
return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz);
|
||||||
|
else if (cause instanceof TransformParallelException)
|
||||||
|
return getFirstThrowableOfType(TransformParallelException.class.cast(cause), clazz);
|
||||||
else if (cause instanceof CreationException)
|
else if (cause instanceof CreationException)
|
||||||
return getFirstThrowableOfType(CreationException.class.cast(cause), clazz);
|
return getFirstThrowableOfType(CreationException.class.cast(cause), clazz);
|
||||||
return cause;
|
return cause;
|
||||||
|
@ -75,6 +104,8 @@ public class Throwables2 {
|
||||||
T cause = getFirstThrowableOfType(message.getCause(), clazz);
|
T cause = getFirstThrowableOfType(message.getCause(), clazz);
|
||||||
if (cause instanceof ProvisionException)
|
if (cause instanceof ProvisionException)
|
||||||
return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz);
|
return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz);
|
||||||
|
else if (cause instanceof TransformParallelException)
|
||||||
|
return getFirstThrowableOfType(TransformParallelException.class.cast(cause), clazz);
|
||||||
else if (cause instanceof CreationException)
|
else if (cause instanceof CreationException)
|
||||||
return getFirstThrowableOfType(CreationException.class.cast(cause), clazz);
|
return getFirstThrowableOfType(CreationException.class.cast(cause), clazz);
|
||||||
return cause;
|
return cause;
|
||||||
|
@ -99,9 +130,10 @@ public class Throwables2 {
|
||||||
return (Exception) throwable;
|
return (Exception) throwable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class, AssertionError.class,
|
for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class,
|
||||||
UnsupportedOperationException.class, IllegalArgumentException.class, AuthorizationException.class,
|
AssertionError.class, UnsupportedOperationException.class, IllegalArgumentException.class,
|
||||||
ResourceNotFoundException.class, InsufficientResourcesException.class, HttpResponseException.class }) {
|
AuthorizationException.class, ResourceNotFoundException.class, InsufficientResourcesException.class,
|
||||||
|
HttpResponseException.class }) {
|
||||||
Throwable throwable = getFirstThrowableOfType(exception, propagatableExceptionType);
|
Throwable throwable = getFirstThrowableOfType(exception, propagatableExceptionType);
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
if (throwable instanceof AssertionError)
|
if (throwable instanceof AssertionError)
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
/**
|
||||||
|
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. jclouds licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.concurrent;
|
||||||
|
|
||||||
|
import static com.google.common.base.Throwables.propagate;
|
||||||
|
import static com.google.common.collect.Maps.newHashMap;
|
||||||
|
import static java.util.concurrent.Executors.newCachedThreadPool;
|
||||||
|
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of FutureIterables
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "performance", enabled = false, sequential = true, testName = "FutureIterablesPerformanceTest")
|
||||||
|
public class FutureIterablesPerformanceTest {
|
||||||
|
ExecutorService ioFunctionExecutor = newCachedThreadPool();
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testMakeListenableDoesntSerializeFutures() throws InterruptedException, ExecutionException {
|
||||||
|
long expectedMax = IO_DURATION;
|
||||||
|
long expectedMin = IO_DURATION;
|
||||||
|
long expectedOverhead = COUNT + FUDGE;
|
||||||
|
|
||||||
|
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
||||||
|
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
Map<String, Future<Long>> responses = runCallables(chainExecutor);
|
||||||
|
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testAwaitCompletionUsingSameThreadExecutorDoesntSerializeFutures() throws InterruptedException,
|
||||||
|
ExecutionException {
|
||||||
|
long expectedMax = IO_DURATION;
|
||||||
|
long expectedMin = IO_DURATION;
|
||||||
|
long expectedOverhead = COUNT + FUDGE;
|
||||||
|
|
||||||
|
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
||||||
|
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
Map<String, Future<Long>> responses = runCallables(chainExecutor);
|
||||||
|
Map<String, Exception> exceptions = awaitCompletion(responses, MoreExecutors.sameThreadExecutor(), null,
|
||||||
|
Logger.CONSOLE, "test same thread");
|
||||||
|
assertEquals(exceptions.size(), 0);
|
||||||
|
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void whenCachedThreadPoolIsUsedForChainAndListenerMaxDurationIsSumOfCallableAndListener()
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
long expectedMax = IO_DURATION + LISTENER_DURATION;
|
||||||
|
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
||||||
|
long expectedOverhead = COUNT * 4 + FUDGE;
|
||||||
|
|
||||||
|
ExecutorService userthreads = newCachedThreadPool();
|
||||||
|
try {
|
||||||
|
ExecutorService chainExecutor = userthreads;
|
||||||
|
ExecutorService listenerExecutor = userthreads;
|
||||||
|
|
||||||
|
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
||||||
|
} finally {
|
||||||
|
userthreads.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void whenCachedThreadPoolIsUsedForChainButSameThreadForListenerMaxDurationIsSumOfCallableAndListener()
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
long expectedMax = IO_DURATION + LISTENER_DURATION;
|
||||||
|
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
||||||
|
long expectedOverhead = COUNT + FUDGE;
|
||||||
|
|
||||||
|
ExecutorService userthreads = newCachedThreadPool();
|
||||||
|
try {
|
||||||
|
ExecutorService chainExecutor = userthreads;
|
||||||
|
ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor();
|
||||||
|
|
||||||
|
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
||||||
|
} finally {
|
||||||
|
userthreads.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void whenSameThreadIsUsedForChainButCachedThreadPoolForListenerMaxDurationIsIOAndSumOfAllListeners()
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
long expectedMax = IO_DURATION + (LISTENER_DURATION * COUNT);
|
||||||
|
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
||||||
|
long expectedOverhead = COUNT + FUDGE;
|
||||||
|
|
||||||
|
ExecutorService userthreads = newCachedThreadPool();
|
||||||
|
try {
|
||||||
|
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
||||||
|
ExecutorService listenerExecutor = userthreads;
|
||||||
|
|
||||||
|
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
||||||
|
} finally {
|
||||||
|
userthreads.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void whenSameThreadIsUsedForChainAndListenerMaxDurationIsIOAndSumOfAllListeners()
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
long expectedMax = IO_DURATION + (LISTENER_DURATION * COUNT);
|
||||||
|
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
||||||
|
long expectedOverhead = COUNT + FUDGE;
|
||||||
|
|
||||||
|
ExecutorService userthreads = newCachedThreadPool();
|
||||||
|
try {
|
||||||
|
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
||||||
|
ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor();
|
||||||
|
|
||||||
|
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
||||||
|
} finally {
|
||||||
|
userthreads.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final int FUDGE = 5;
|
||||||
|
public static final int COUNT = 100;
|
||||||
|
public static final int IO_DURATION = 50;
|
||||||
|
public static final int LISTENER_DURATION = 100;
|
||||||
|
|
||||||
|
private void checkThresholdsUsingCompose(long expectedMin, long expectedMax, long expectedOverhead,
|
||||||
|
ExecutorService chainExecutor, final ExecutorService listenerExecutor) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
Map<String, Future<Long>> responses = newHashMap();
|
||||||
|
for (int i = 0; i < COUNT; i++)
|
||||||
|
responses.put(i + "", org.jclouds.concurrent.Futures.compose(org.jclouds.concurrent.Futures.makeListenable(
|
||||||
|
simultateIO(), chainExecutor), new Function<Long, Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long apply(Long from) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(LISTENER_DURATION);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
propagate(e);
|
||||||
|
}
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
}, listenerExecutor));
|
||||||
|
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Future<Long>> runCallables(ExecutorService chainExecutor) {
|
||||||
|
Map<String, Future<Long>> responses = newHashMap();
|
||||||
|
for (int i = 0; i < COUNT; i++)
|
||||||
|
responses.put(i + "", org.jclouds.concurrent.Futures.makeListenable(simultateIO(), chainExecutor));
|
||||||
|
return responses;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Future<Long> simultateIO() {
|
||||||
|
return ioFunctionExecutor.submit(new Callable<Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long call() throws Exception {
|
||||||
|
Thread.sleep(IO_DURATION);
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getMaxIn(Map<String, Future<Long>> responses) {
|
||||||
|
Iterable<Long> collection = Iterables.transform(responses.values(), new Function<Future<Long>, Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long apply(Future<Long> from) {
|
||||||
|
try {
|
||||||
|
return from.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
long time = Collections.max(Sets.newHashSet(collection));
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getMinIn(Map<String, Future<Long>> responses) {
|
||||||
|
Iterable<Long> collection = Iterables.transform(responses.values(), new Function<Future<Long>, Long>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long apply(Future<Long> from) {
|
||||||
|
try {
|
||||||
|
return from.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
long time = Collections.min(Sets.newHashSet(collection));
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkTimeThresholds(long expectedMin, long expectedMax, long expectedOverhead, long start,
|
||||||
|
Map<String, Future<Long>> responses) {
|
||||||
|
long time = getMaxIn(responses) - start;
|
||||||
|
assert time >= expectedMax && time < expectedMax + expectedOverhead : String.format("expectedMax %d, max %d",
|
||||||
|
expectedMax, time);
|
||||||
|
|
||||||
|
time = getMinIn(responses) - start;
|
||||||
|
assert time >= expectedMin && time < expectedMin + expectedOverhead : String.format("expectedMin %d, min %d",
|
||||||
|
expectedMin, time);
|
||||||
|
|
||||||
|
time = getMaxIn(responses) - start;
|
||||||
|
assert time >= expectedMax && time < expectedMax + expectedOverhead : String.format("expectedMax %d, max %d",
|
||||||
|
expectedMax, time);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,232 +18,66 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.concurrent;
|
package org.jclouds.concurrent;
|
||||||
|
|
||||||
import static com.google.common.base.Throwables.propagate;
|
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
||||||
import static com.google.common.collect.Maps.newHashMap;
|
|
||||||
import static java.util.concurrent.Executors.newCachedThreadPool;
|
|
||||||
import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests behavior of FutureIterables
|
* Tests behavior of FutureIterables
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "performance", enabled = false, sequential = true, testName = "FutureIterablesTest")
|
@Test(groups = "unit", singleThreaded = true, testName = "FutureIterablesTest")
|
||||||
public class FutureIterablesTest {
|
public class FutureIterablesTest {
|
||||||
ExecutorService ioFunctionExecutor = newCachedThreadPool();
|
|
||||||
|
|
||||||
@Test(enabled = false)
|
public void testAuthorizationExceptionPropagatesAndOnlyTriesOncePerElement() {
|
||||||
public void testMakeListenableDoesntSerializeFutures() throws InterruptedException, ExecutionException {
|
final AtomicInteger counter = new AtomicInteger();
|
||||||
long expectedMax = IO_DURATION;
|
|
||||||
long expectedMin = IO_DURATION;
|
|
||||||
long expectedOverhead = COUNT + FUDGE;
|
|
||||||
|
|
||||||
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
Map<String, Future<Long>> responses = runCallables(chainExecutor);
|
|
||||||
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void testAwaitCompletionUsingSameThreadExecutorDoesntSerializeFutures() throws InterruptedException,
|
|
||||||
ExecutionException {
|
|
||||||
long expectedMax = IO_DURATION;
|
|
||||||
long expectedMin = IO_DURATION;
|
|
||||||
long expectedOverhead = COUNT + FUDGE;
|
|
||||||
|
|
||||||
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
|
||||||
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
Map<String, Future<Long>> responses = runCallables(chainExecutor);
|
|
||||||
Map<String, Exception> exceptions = awaitCompletion(responses, MoreExecutors.sameThreadExecutor(), null,
|
|
||||||
Logger.CONSOLE, "test same thread");
|
|
||||||
assertEquals(exceptions.size(), 0);
|
|
||||||
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void whenCachedThreadPoolIsUsedForChainAndListenerMaxDurationIsSumOfCallableAndListener()
|
|
||||||
throws InterruptedException, ExecutionException {
|
|
||||||
long expectedMax = IO_DURATION + LISTENER_DURATION;
|
|
||||||
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
|
||||||
long expectedOverhead = COUNT * 4 + FUDGE;
|
|
||||||
|
|
||||||
ExecutorService userthreads = newCachedThreadPool();
|
|
||||||
try {
|
try {
|
||||||
ExecutorService chainExecutor = userthreads;
|
transformParallel(ImmutableSet.of("hello", "goodbye"), new Function<String, Future<String>>() {
|
||||||
ExecutorService listenerExecutor = userthreads;
|
|
||||||
|
|
||||||
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
|
||||||
} finally {
|
|
||||||
userthreads.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void whenCachedThreadPoolIsUsedForChainButSameThreadForListenerMaxDurationIsSumOfCallableAndListener()
|
|
||||||
throws InterruptedException, ExecutionException {
|
|
||||||
long expectedMax = IO_DURATION + LISTENER_DURATION;
|
|
||||||
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
|
||||||
long expectedOverhead = COUNT + FUDGE;
|
|
||||||
|
|
||||||
ExecutorService userthreads = newCachedThreadPool();
|
|
||||||
try {
|
|
||||||
ExecutorService chainExecutor = userthreads;
|
|
||||||
ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor();
|
|
||||||
|
|
||||||
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
|
||||||
} finally {
|
|
||||||
userthreads.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void whenSameThreadIsUsedForChainButCachedThreadPoolForListenerMaxDurationIsIOAndSumOfAllListeners()
|
|
||||||
throws InterruptedException, ExecutionException {
|
|
||||||
long expectedMax = IO_DURATION + (LISTENER_DURATION * COUNT);
|
|
||||||
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
|
||||||
long expectedOverhead = COUNT + FUDGE;
|
|
||||||
|
|
||||||
ExecutorService userthreads = newCachedThreadPool();
|
|
||||||
try {
|
|
||||||
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
|
||||||
ExecutorService listenerExecutor = userthreads;
|
|
||||||
|
|
||||||
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
|
||||||
} finally {
|
|
||||||
userthreads.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = false)
|
|
||||||
public void whenSameThreadIsUsedForChainAndListenerMaxDurationIsIOAndSumOfAllListeners()
|
|
||||||
throws InterruptedException, ExecutionException {
|
|
||||||
|
|
||||||
long expectedMax = IO_DURATION + (LISTENER_DURATION * COUNT);
|
|
||||||
long expectedMin = IO_DURATION + LISTENER_DURATION;
|
|
||||||
long expectedOverhead = COUNT + FUDGE;
|
|
||||||
|
|
||||||
ExecutorService userthreads = newCachedThreadPool();
|
|
||||||
try {
|
|
||||||
ExecutorService chainExecutor = MoreExecutors.sameThreadExecutor();
|
|
||||||
ExecutorService listenerExecutor = MoreExecutors.sameThreadExecutor();
|
|
||||||
|
|
||||||
checkThresholdsUsingCompose(expectedMin, expectedMax, expectedOverhead, chainExecutor, listenerExecutor);
|
|
||||||
} finally {
|
|
||||||
userthreads.shutdownNow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final int FUDGE = 5;
|
|
||||||
public static final int COUNT = 100;
|
|
||||||
public static final int IO_DURATION = 50;
|
|
||||||
public static final int LISTENER_DURATION = 100;
|
|
||||||
|
|
||||||
private void checkThresholdsUsingCompose(long expectedMin, long expectedMax, long expectedOverhead,
|
|
||||||
ExecutorService chainExecutor, final ExecutorService listenerExecutor) {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
Map<String, Future<Long>> responses = newHashMap();
|
|
||||||
for (int i = 0; i < COUNT; i++)
|
|
||||||
responses.put(i + "", org.jclouds.concurrent.Futures.compose(org.jclouds.concurrent.Futures.makeListenable(
|
|
||||||
simultateIO(), chainExecutor), new Function<Long, Long>() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long apply(Long from) {
|
public Future<String> apply(String input) {
|
||||||
try {
|
counter.incrementAndGet();
|
||||||
Thread.sleep(LISTENER_DURATION);
|
return com.google.common.util.concurrent.Futures.immediateFailedFuture(new AuthorizationException());
|
||||||
} catch (InterruptedException e) {
|
|
||||||
propagate(e);
|
|
||||||
}
|
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, listenerExecutor));
|
}, MoreExecutors.sameThreadExecutor(), null, Logger.CONSOLE, "");
|
||||||
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
|
assert false;
|
||||||
|
} catch (AuthorizationException e) {
|
||||||
|
assertEquals(counter.get(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Future<Long>> runCallables(ExecutorService chainExecutor) {
|
public void testNormalExceptionPropagatesAsTransformParallelExceptionAndTries5XPerElement() {
|
||||||
Map<String, Future<Long>> responses = newHashMap();
|
final AtomicInteger counter = new AtomicInteger();
|
||||||
for (int i = 0; i < COUNT; i++)
|
|
||||||
responses.put(i + "", org.jclouds.concurrent.Futures.makeListenable(simultateIO(), chainExecutor));
|
|
||||||
return responses;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Future<Long> simultateIO() {
|
try {
|
||||||
return ioFunctionExecutor.submit(new Callable<Long>() {
|
transformParallel(ImmutableSet.of("hello", "goodbye"), new Function<String, Future<String>>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long call() throws Exception {
|
public Future<String> apply(String input) {
|
||||||
Thread.sleep(IO_DURATION);
|
counter.incrementAndGet();
|
||||||
return System.currentTimeMillis();
|
return com.google.common.util.concurrent.Futures.immediateFailedFuture(new RuntimeException());
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getMaxIn(Map<String, Future<Long>> responses) {
|
|
||||||
Iterable<Long> collection = Iterables.transform(responses.values(), new Function<Future<Long>, Long>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long apply(Future<Long> from) {
|
|
||||||
try {
|
|
||||||
return from.get();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
}, MoreExecutors.sameThreadExecutor(), null, Logger.CONSOLE, "");
|
||||||
long time = Collections.max(Sets.newHashSet(collection));
|
assert false;
|
||||||
return time;
|
} catch (TransformParallelException e) {
|
||||||
|
assertEquals(e.getFromToException().size(), 2);
|
||||||
|
assertEquals(counter.get(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getMinIn(Map<String, Future<Long>> responses) {
|
|
||||||
Iterable<Long> collection = Iterables.transform(responses.values(), new Function<Future<Long>, Long>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long apply(Future<Long> from) {
|
|
||||||
try {
|
|
||||||
return from.get();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
long time = Collections.min(Sets.newHashSet(collection));
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkTimeThresholds(long expectedMin, long expectedMax, long expectedOverhead, long start,
|
|
||||||
Map<String, Future<Long>> responses) {
|
|
||||||
long time = getMaxIn(responses) - start;
|
|
||||||
assert time >= expectedMax && time < expectedMax + expectedOverhead : String.format("expectedMax %d, max %d",
|
|
||||||
expectedMax, time);
|
|
||||||
|
|
||||||
time = getMinIn(responses) - start;
|
|
||||||
assert time >= expectedMin && time < expectedMin + expectedOverhead : String.format("expectedMin %d, min %d",
|
|
||||||
expectedMin, time);
|
|
||||||
|
|
||||||
time = getMaxIn(responses) - start;
|
|
||||||
assert time >= expectedMax && time < expectedMax + expectedOverhead : String.format("expectedMax %d, max %d",
|
|
||||||
expectedMax, time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,13 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.location.suppliers.LocationIdToIso3166CodesSupplier;
|
||||||
|
import org.jclouds.util.Suppliers2;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
@ -42,14 +45,14 @@ import com.google.inject.Provides;
|
||||||
public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
|
public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
|
||||||
|
|
||||||
public void testEmptyWhenNoLocationsBound() {
|
public void testEmptyWhenNoLocationsBound() {
|
||||||
ProvideIso3166CodesByLocationIdViaProperties fn = createWithValue(ImmutableMap.<String, String> of());
|
LocationIdToIso3166CodesSupplier fn = createWithValue(ImmutableMap.<String, String> of());
|
||||||
|
|
||||||
assertEquals(fn.get(), ImmutableMap.<String, Set<String>> of());
|
assertEquals(fn.get(), ImmutableMap.<String, Set<String>> of());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEmptyWhenRegionsAndZonesBoundButNoIsoCodes() {
|
public void testEmptyWhenRegionsAndZonesBoundButNoIsoCodes() {
|
||||||
|
|
||||||
ProvideIso3166CodesByLocationIdViaProperties fn = createWithValue(ImmutableMap.<String, String> of(
|
LocationIdToIso3166CodesSupplier fn = createWithValue(ImmutableMap.<String, String> of(
|
||||||
"jclouds.regions", "us-east", "jclouds.zones", "us-easta"));
|
"jclouds.regions", "us-east", "jclouds.zones", "us-easta"));
|
||||||
|
|
||||||
assertEquals(fn.get(), ImmutableMap.<String, Set<String>> of());
|
assertEquals(fn.get(), ImmutableMap.<String, Set<String>> of());
|
||||||
|
@ -57,20 +60,18 @@ public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
|
||||||
|
|
||||||
public void testIsoCodesWhenRegionsAndZonesBoundWithIsoCodes() {
|
public void testIsoCodesWhenRegionsAndZonesBoundWithIsoCodes() {
|
||||||
|
|
||||||
ProvideIso3166CodesByLocationIdViaProperties fn = createWithValue(ImmutableMap.<String, String> of(
|
LocationIdToIso3166CodesSupplier fn = createWithValue(ImmutableMap.<String, String> of(
|
||||||
"jclouds.regions", "us-east", "jclouds.region.us-east.iso3166-codes", "US", "jclouds.zones", "us-easta",
|
"jclouds.regions", "us-east", "jclouds.region.us-east.iso3166-codes", "US", "jclouds.zones", "us-easta",
|
||||||
"jclouds.zone.us-easta.iso3166-codes", "US-CA"));
|
"jclouds.zone.us-easta.iso3166-codes", "US-CA"));
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(Maps.transformValues(fn.get(), Suppliers.<Set<String>> supplierFunction()), ImmutableMap
|
||||||
fn.get(),
|
.<String, Set<String>> of("us-east", ImmutableSet.of("US"), "us-easta", ImmutableSet.of("US-CA")));
|
||||||
ImmutableMap.<String, Set<String>> of("us-east", ImmutableSet.of("US"), "us-easta",
|
|
||||||
ImmutableSet.of("US-CA")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
private ProvideIso3166CodesByLocationIdViaProperties createWithValue(final ImmutableMap<String, String> value) {
|
private LocationIdToIso3166CodesSupplier createWithValue(final ImmutableMap<String, String> value) {
|
||||||
ProvideIso3166CodesByLocationIdViaProperties fn = Guice.createInjector(new AbstractModule() {
|
LocationIdToIso3166CodesSupplier fn = Guice.createInjector(new AbstractModule() {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Provides
|
@Provides
|
||||||
Function<Predicate<String>, Map<String, String>> provide() {
|
Function<Predicate<String>, Map<String, String>> provide() {
|
||||||
|
@ -87,7 +88,7 @@ public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}).getInstance(ProvideIso3166CodesByLocationIdViaProperties.class);
|
}).getInstance(LocationIdToIso3166CodesSupplier.class);
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,9 +22,12 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,33 +40,34 @@ public class RegionToEndpointOrProviderIfNullTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWhenFindsRegion() throws SecurityException, NoSuchMethodException {
|
public void testWhenFindsRegion() throws SecurityException, NoSuchMethodException {
|
||||||
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
|
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
|
||||||
ImmutableMap.of("1", URI.create("http://1")));
|
.create("http://leader")), Suppliers.<Map<String, Supplier<URI>>>ofInstance(ImmutableMap.of("1", Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
assertEquals(fn.apply("1"), URI.create("http://1"));
|
assertEquals(fn.apply("1"), URI.create("http://1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNullReturnsProvider() {
|
public void testNullReturnsProvider() {
|
||||||
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
|
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
|
||||||
ImmutableMap.of("1", URI.create("http://1")));
|
.create("http://leader")), Suppliers.<Map<String, Supplier<URI>>>ofInstance(ImmutableMap.of("1", Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
assertEquals(fn.apply("leader"), URI.create("http://leader"));
|
assertEquals(fn.apply("leader"), URI.create("http://leader"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMustBeString() {
|
public void testMustBeString() {
|
||||||
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
|
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
|
||||||
ImmutableMap.of("1", URI.create("http://1")));
|
.create("http://leader")), Suppliers.<Map<String, Supplier<URI>>>ofInstance(ImmutableMap.of("1", Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
fn.apply(new File("foo"));
|
fn.apply(new File("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMustBeInRegionMapIfSpecified() {
|
public void testMustBeInRegionMapIfSpecified() {
|
||||||
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
|
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
|
||||||
ImmutableMap.of("1", URI.create("http://1")));
|
.create("http://leader")), Suppliers.<Map<String, Supplier<URI>>>ofInstance(ImmutableMap.of("1", Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
fn.apply("2");
|
fn.apply("2");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testOkIfNoRegionMappings() {
|
public void testOkIfNoRegionMappings() {
|
||||||
new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"), ImmutableMap.<String, URI> of());
|
new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI.create("http://leader")), Suppliers
|
||||||
|
.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap.<String, Supplier<URI>> of()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,12 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,25 +39,30 @@ import com.google.common.collect.ImmutableMap;
|
||||||
public class ZoneToEndpointTest {
|
public class ZoneToEndpointTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCorrect() throws SecurityException, NoSuchMethodException {
|
public void testCorrect() {
|
||||||
ZoneToEndpoint fn = new ZoneToEndpoint(ImmutableMap.of("1", URI.create("http://1")));
|
ZoneToEndpoint fn = new ZoneToEndpoint(Suppliers.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap.of("1",
|
||||||
|
Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
assertEquals(fn.apply("1"), URI.create("http://1"));
|
assertEquals(fn.apply("1"), URI.create("http://1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testMustBeString() {
|
public void testMustBeString() {
|
||||||
ZoneToEndpoint fn = new ZoneToEndpoint(ImmutableMap.of("1", URI.create("http://1")));
|
ZoneToEndpoint fn = new ZoneToEndpoint(Suppliers.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap.of("1",
|
||||||
|
Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
fn.apply(new File("foo"));
|
fn.apply(new File("foo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalStateException.class)
|
||||||
public void testMustHaveEndpoints() {
|
public void testMustHaveEndpoints() {
|
||||||
new ZoneToEndpoint(ImmutableMap.<String, URI> of());
|
ZoneToEndpoint fn = new ZoneToEndpoint(Suppliers.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap
|
||||||
|
.<String, Supplier<URI>> of()));
|
||||||
|
fn.apply("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
public void testNullIsIllegal() {
|
public void testNullIsIllegal() {
|
||||||
ZoneToEndpoint fn = new ZoneToEndpoint(ImmutableMap.of("1", URI.create("http://1")));
|
ZoneToEndpoint fn = new ZoneToEndpoint(Suppliers.<Map<String, Supplier<URI>>> ofInstance(ImmutableMap.of("1",
|
||||||
|
Suppliers.ofInstance(URI.create("http://1")))));
|
||||||
fn.apply(null);
|
fn.apply(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.all;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import java.net.URI;
|
||||||
|
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
|
import org.jclouds.location.suppliers.all.JustProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.implicit;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -40,55 +40,55 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Test(groups = "unit", testName = "OnlyLocationOrFirstRegionOptionallyMatchingRegionIdTest")
|
@Test(groups = "unit", testName = "OnlyLocationOrFirstRegionOptionallyMatchingRegionIdTest")
|
||||||
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionIdTest {
|
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionIdTest {
|
||||||
Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo")
|
Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo")
|
||||||
.build();
|
.build();
|
||||||
Location region = new LocationBuilder().scope(LocationScope.REGION).id("servo-r1").description("http://r1.servo")
|
Location region = new LocationBuilder().scope(LocationScope.REGION).id("servo-r1").description("http://r1.servo")
|
||||||
.parent(provider).build();
|
.parent(provider).build();
|
||||||
Location region2 = new LocationBuilder().scope(LocationScope.REGION).id("servo-r2").description("http://r2.servo")
|
Location region2 = new LocationBuilder().scope(LocationScope.REGION).id("servo-r2").description("http://r2.servo")
|
||||||
.parent(provider).build();
|
.parent(provider).build();
|
||||||
Location zone = new LocationBuilder().scope(LocationScope.ZONE).id("servo-z").description("http://z.r.servo")
|
Location zone = new LocationBuilder().scope(LocationScope.ZONE).id("servo-z").description("http://z.r.servo")
|
||||||
.parent(region).build();
|
.parent(region).build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDidntMatchRegionIdThrowsNSEEWithReasonableMessage() {
|
public void testDidntMatchRegionIdThrowsNSEEWithReasonableMessage() {
|
||||||
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
||||||
.<Location> of(provider, region, region2, zone));
|
.<Location> of(provider, region, region2, zone));
|
||||||
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
||||||
"foo", supplier);
|
Suppliers.ofInstance("foo"), supplier);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fn.get();
|
fn.get();
|
||||||
assert false;
|
assert false;
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
e.getMessage(),
|
e.getMessage(),
|
||||||
"couldn't find region matching isRegionAndIdEqualsOrIsZoneParentIdEquals(foo) in [servo:PROVIDER, servo-r1:REGION, servo-r2:REGION, servo-z:ZONE]");
|
"couldn't find region matching isRegionAndIdEqualsOrIsZoneParentIdEquals(foo) in [servo:PROVIDER, servo-r1:REGION, servo-r2:REGION, servo-z:ZONE]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoRegionUsesProvider() {
|
public void testNoRegionUsesProvider() {
|
||||||
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
||||||
.<Location> of(provider));
|
.<Location> of(provider));
|
||||||
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
||||||
null, supplier);
|
Suppliers.<String>ofInstance(null), supplier);
|
||||||
assertEquals(fn.get(), provider);
|
assertEquals(fn.get(), provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFirstRegion() {
|
public void testFirstRegion() {
|
||||||
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
||||||
.<Location> of(provider, region, region2, zone));
|
.<Location> of(provider, region, region2, zone));
|
||||||
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
||||||
null, supplier);
|
Suppliers.<String>ofInstance(null), supplier);
|
||||||
assertEquals(fn.get(), region);
|
assertEquals(fn.get(), region);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindRegion() {
|
public void testFindRegion() {
|
||||||
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
|
||||||
.<Location> of(provider, region, region2, zone));
|
.<Location> of(provider, region, region2, zone));
|
||||||
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
|
||||||
region2.getId(), supplier);
|
Suppliers.ofInstance(region2.getId()), supplier);
|
||||||
assertEquals(fn.get(), region2);
|
assertEquals(fn.get(), region2);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.location.suppliers;
|
package org.jclouds.location.suppliers.implicit;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import java.util.Set;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
|
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
|
@ -144,6 +144,8 @@ import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.base.Suppliers;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
@ -181,7 +183,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(URI.class).annotatedWith(Localhost2.class).toInstance(URI.create("http://localhost:1111"));
|
bind(new TypeLiteral<Supplier<URI>>() {
|
||||||
|
}).annotatedWith(Localhost2.class).toInstance(
|
||||||
|
Suppliers.ofInstance(URI.create("http://localhost:1111")));
|
||||||
bind(IOExceptionRetryHandler.class).toInstance(IOExceptionRetryHandler.NEVER_RETRY);
|
bind(IOExceptionRetryHandler.class).toInstance(IOExceptionRetryHandler.NEVER_RETRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2436,7 +2440,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
||||||
}).toInstance(ImmutableSet.of("foo"));
|
}).toInstance(ImmutableSet.of("foo"));
|
||||||
bind(new TypeLiteral<Set<String>>() {
|
bind(new TypeLiteral<Set<String>>() {
|
||||||
}).annotatedWith(Names.named("bar")).toInstance(ImmutableSet.of("bar"));
|
}).annotatedWith(Names.named("bar")).toInstance(ImmutableSet.of("bar"));
|
||||||
bind(URI.class).annotatedWith(Localhost2.class).toInstance(URI.create("http://localhost:1111"));
|
bind(new TypeLiteral<Supplier<URI>>() {
|
||||||
|
}).annotatedWith(Localhost2.class).toInstance(
|
||||||
|
Suppliers.ofInstance(URI.create("http://localhost:1111")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
|
@ -26,8 +26,11 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.concurrent.TransformParallelException;
|
||||||
import org.jclouds.http.HttpCommand;
|
import org.jclouds.http.HttpCommand;
|
||||||
import org.jclouds.http.HttpResponseException;
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
|
@ -36,6 +39,7 @@ import org.jclouds.rest.ResourceNotFoundException;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.CreationException;
|
import com.google.inject.CreationException;
|
||||||
import com.google.inject.ProvisionException;
|
import com.google.inject.ProvisionException;
|
||||||
|
@ -113,6 +117,38 @@ public class Throwables2Test {
|
||||||
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), null);
|
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testGetCauseTransformParallel() {
|
||||||
|
Exception aex = createMock(AuthorizationException.class);
|
||||||
|
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
|
||||||
|
aex), "test");
|
||||||
|
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), aex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testGetFirstThrowableOfTypeInnerTransformParallel() {
|
||||||
|
Exception aex = createMock(AuthorizationException.class);
|
||||||
|
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
|
||||||
|
(Exception) new ExecutionException(aex)), "test");
|
||||||
|
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), aex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testGetFirstThrowableOfTypeOuterTransformParallel() {
|
||||||
|
Exception aex = createMock(AuthorizationException.class);
|
||||||
|
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
|
||||||
|
(Exception) aex), "test");
|
||||||
|
assertEquals(getFirstThrowableOfType(new ExecutionException(pex), AuthorizationException.class), aex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void testGetFirstThrowableOfTypeFailTransformParallel() {
|
||||||
|
Exception aex = createMock(TimeoutException.class);
|
||||||
|
TransformParallelException pex = new TransformParallelException((Map) ImmutableMap.of(), ImmutableMap.of("bad",
|
||||||
|
aex), "test");
|
||||||
|
assertEquals(getFirstThrowableOfType(pex, AuthorizationException.class), null);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReturnExceptionThatsInList() throws Exception {
|
public void testReturnExceptionThatsInList() throws Exception {
|
||||||
Exception e = new TestException();
|
Exception e = new TestException();
|
||||||
|
|
|
@ -18,22 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.loadbalancer.config;
|
package org.jclouds.loadbalancer.config;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.collect.Memoized;
|
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import org.jclouds.rest.AuthorizationException;
|
|
||||||
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -41,25 +26,8 @@ import com.google.inject.Provides;
|
||||||
*/
|
*/
|
||||||
public abstract class BaseLoadBalancerServiceContextModule extends AbstractModule {
|
public abstract class BaseLoadBalancerServiceContextModule extends AbstractModule {
|
||||||
|
|
||||||
protected AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
@Singleton
|
|
||||||
@Memoized
|
|
||||||
protected Supplier<Set<? extends Location>> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds,
|
|
||||||
final Supplier<Set<? extends Location>> locationSupplier) {
|
|
||||||
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException, seconds,
|
|
||||||
new Supplier<Set<? extends Location>>() {
|
|
||||||
@Override
|
|
||||||
public Set<? extends Location> get() {
|
|
||||||
return locationSupplier.get();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,92 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.loadbalancer.config;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
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.OnlyLocationOrFirstRegionOptionallyMatchingRegionId;
|
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.inject.AbstractModule;
|
|
||||||
import com.google.inject.Scopes;
|
|
||||||
import com.google.inject.TypeLiteral;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Adrian Cole
|
|
||||||
*/
|
|
||||||
public abstract class BindLoadBalancerSuppliersByClass extends AbstractModule {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure() {
|
|
||||||
bindLocationSupplier(defineLocationSupplier());
|
|
||||||
bindDefaultLocationSupplier(defineDefaultLocationSupplier());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected Class<? extends Supplier<Set<? extends Location>>> defineLocationSupplier() {
|
|
||||||
return SupplierOfLocationSet.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
static class SupplierOfLocationSet implements Supplier<Set<? extends Location>> {
|
|
||||||
private final Set<? extends Location> locations;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
SupplierOfLocationSet(Set<? extends Location> locations) {
|
|
||||||
this.locations = locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<? extends Location> get() {
|
|
||||||
return locations;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Class<? extends Supplier<Location>> defineDefaultLocationSupplier() {
|
|
||||||
return OnlyLocationOrFirstRegionOptionallyMatchingRegionId.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindImageSupplier(Class<? extends Supplier<Set<? extends Image>>> clazz) {
|
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Image>>>() {
|
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindLocationSupplier(Class<? extends Supplier<Set<? extends Location>>> clazz) {
|
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
|
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindDefaultLocationSupplier(Class<? extends Supplier<Location>> clazz) {
|
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void bindHardwareSupplier(Class<? extends Supplier<Set<? extends Hardware>>> clazz) {
|
|
||||||
bind(new TypeLiteral<Supplier<Set<? extends Hardware>>>() {
|
|
||||||
}).to(clazz).in(Scopes.SINGLETON);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -22,7 +22,6 @@ import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
|
|
||||||
import org.jclouds.servermanager.Datacenter;
|
import org.jclouds.servermanager.Datacenter;
|
||||||
import org.jclouds.servermanager.Hardware;
|
import org.jclouds.servermanager.Hardware;
|
||||||
import org.jclouds.servermanager.Image;
|
import org.jclouds.servermanager.Image;
|
||||||
|
@ -35,7 +34,6 @@ import org.jclouds.servermanager.compute.functions.ServerToNodeMetadata;
|
||||||
import org.jclouds.servermanager.compute.strategy.ServerManagerComputeServiceAdapter;
|
import org.jclouds.servermanager.compute.strategy.ServerManagerComputeServiceAdapter;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,7 +60,7 @@ public class ServerManagerComputeServiceContextModule extends
|
||||||
}).to(ServerManagerHardwareToHardware.class);
|
}).to(ServerManagerHardwareToHardware.class);
|
||||||
bind(new TypeLiteral<Function<Datacenter, Location>>() {
|
bind(new TypeLiteral<Function<Datacenter, Location>>() {
|
||||||
}).to(DatacenterToLocation.class);
|
}).to(DatacenterToLocation.class);
|
||||||
bind(new TypeLiteral<Supplier<Location>>() {
|
// to have the compute service adapter override default locations
|
||||||
}).to(OnlyLocationOrFirstZone.class);
|
install(new LocationsFromComputeServiceAdapterModule<Server, Hardware, Image, Datacenter>(){});
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue