Issue 826:support api-generated location metadata across service types, note this ensures authenticationexceptions propagate even after context creation

This commit is contained in:
Adrian Cole 2012-02-02 07:22:46 -08:00
parent d4fb6bb802
commit bdd739ad04
66 changed files with 2081 additions and 1015 deletions

View File

@ -27,10 +27,12 @@ import org.jclouds.byon.Node;
import org.jclouds.byon.internal.BYONComputeServiceAdapter;
import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty;
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.domain.Location;
import org.jclouds.location.Provider;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
@ -45,7 +47,7 @@ import com.google.inject.TypeLiteral;
@SuppressWarnings("unchecked")
@SingleThreaded
public class BYONComputeServiceContextModule extends
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
JCloudsNativeComputeServiceAdapterContextModule<Supplier, Supplier> {
public BYONComputeServiceContextModule() {
super(Supplier.class, Supplier.class, BYONComputeServiceAdapter.class);
@ -60,14 +62,12 @@ public class BYONComputeServiceContextModule extends
@Override
protected void configure() {
super.configure();
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
bind(new TypeLiteral<Function<URI, InputStream>>() {
}).to(SupplyFromProviderURIOrNodesProperty.class);
bind(new TypeLiteral<Supplier<InputStream>>() {
}).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class);
bind(new TypeLiteral<Function<URI, InputStream>>() {
}).to(SupplyFromProviderURIOrNodesProperty.class);
install(new LocationsFromComputeServiceAdapterModule<NodeMetadata, Hardware, Image, Location>(){});
}
}

View File

@ -35,7 +35,7 @@ import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
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.Predicates;

View File

@ -31,7 +31,6 @@ import org.jclouds.blobstore.attr.ConsistencyModel;
import org.jclouds.blobstore.domain.Blob;
import org.jclouds.blobstore.internal.BlobStoreContextImpl;
import org.jclouds.domain.Location;
import org.jclouds.location.config.JustProviderLocationModule;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
@ -59,7 +58,6 @@ public class TransientBlobStoreContextModule extends AbstractModule {
}).toInstance(containerToLocation);
install(new BlobStoreObjectModule());
install(new BlobStoreMapModule());
install(new JustProviderLocationModule());
bind(BlobStore.class).to(TransientBlobStore.class);
bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT);
bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class);

View File

@ -55,7 +55,6 @@ import org.jclouds.config.ValueOfConfigurationKeyOrNull;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.json.Json;
import org.jclouds.location.Provider;
import org.jclouds.location.config.LocationModule;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
import org.jclouds.scriptbuilder.domain.Statement;
@ -81,7 +80,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
@Override
protected void configure() {
configureLocationModule();
install(new ComputeServiceTimeoutsModule());
bind(new TypeLiteral<Function<NodeMetadata, SshClient>>() {
}).to(CreateSshClientOncePortIsListeningOnNode.class);
@ -115,10 +113,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
install(new FactoryModuleBuilder().build(BlockUntilInitScriptStatusIsZeroThenReturnOutput.Factory.class));
}
protected void configureLocationModule() {
install(new LocationModule(authException));
}
@Singleton
static class RunScriptOnNodeFactoryImpl implements RunScriptOnNode.Factory {
@ -210,8 +204,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
return "%s-%s";
}
protected AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
@Provides
@Singleton
protected Supplier<Map<String, ? extends Image>> provideImageMap(@Memoized Supplier<Set<? extends Image>> images) {
@ -235,12 +227,12 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
@Provides
@Singleton
@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) {
if (shouldParseImagesOnDemand(injector)) {
return supplyImageCache(seconds, imageSupplier);
return supplyImageCache(authException, seconds, imageSupplier);
} else {
return supplyNonParsingImageCache(seconds, imageSupplier, injector);
return supplyNonParsingImageCache(authException, seconds, imageSupplier, injector);
}
}
@ -248,7 +240,7 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
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) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Image>>(authException,
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)}
*/
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) {
return supplyImageCache(seconds, imageSupplier);
return supplyImageCache(authException, seconds, imageSupplier);
}
@Provides
@ -290,7 +282,7 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
@Provides
@Singleton
@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) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Hardware>>(authException,
seconds, new Supplier<Set<? extends Hardware>>() {

View File

@ -20,13 +20,8 @@ package org.jclouds.compute.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.OnlyLocationOrFirstZone;
import com.google.common.base.Supplier;
import com.google.inject.AbstractModule;
@ -41,54 +36,18 @@ public abstract class BindComputeSuppliersByClass extends AbstractModule {
@Override
protected void configure() {
bindImageSupplier(defineImageSupplier());
bindLocationSupplier(defineLocationSupplier());
bindHardwareSupplier(defineHardwareSupplier());
bindDefaultLocationSupplier(defineDefaultLocationSupplier());
}
protected abstract Class<? extends Supplier<Set<? extends Image>>> defineImageSupplier();
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) {
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);

View File

@ -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.transform;
import static com.google.inject.util.Types.newParameterizedType;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.collect.TransformingSetSupplier;
import org.jclouds.compute.ComputeServiceAdapter;
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.domain.Location;
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.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
@ -82,25 +80,38 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
(TypeLiteral) TypeLiteral.get(newParameterizedType(ComputeServiceContextImpl.class, syncClientType,
asyncClientType))).in(Scopes.SINGLETON);
}
/**
* install this, if you want to use your computeservice adapter to handle locations. Note that if
* 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 {
@Override
protected void configureLocationModule() {
// configuring below
}
@Override
protected void configure() {
}
@Provides
@Singleton
@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) {
return new MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<Set<? extends Location>>(authException,
seconds, new Supplier<Set<? extends Location>>() {
@Override
public Set<? extends Location> get() {
return ImmutableSet.<Location> copyOf(transform(filter(adapter.listLocations(), notNull()),
transformer));
}
});
@Provides
@Singleton
protected LocationsSupplier supplyLocationsFromComputeServiceAdapter(
final ComputeServiceAdapter<N, H, I, L> adapter, final Function<L, Location> transformer) {
return new LocationsSupplier() {
@Override
public Set<? extends Location> get() {
Iterable<L> locations = filter(adapter.listLocations(), notNull());
return ImmutableSet.<Location> copyOf(transform(locations, transformer));
}
};
}
}
@Provides
@ -111,7 +122,7 @@ public class ComputeServiceAdapterContextModule<S, A, N, H, I, L> extends BaseCo
@Override
public Iterable<H> get() {
return filter(adapter.listHardwareProfiles(), notNull());
return adapter.listHardwareProfiles();
}
}, transformer);

View File

@ -42,7 +42,7 @@ import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.location.suppliers.JustProvider;
import org.jclouds.location.suppliers.all.JustProvider;
import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Supplier;

View File

@ -25,12 +25,8 @@ import javax.inject.Singleton;
import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.NodeMetadata;
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.TypeLiteral;
/**
*
@ -54,8 +50,6 @@ public class StubComputeServiceContextModule extends
@Override
protected void configure() {
install(new StubComputeServiceDependenciesModule());
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
super.configure();
}
}

View File

@ -18,7 +18,12 @@
*/
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 org.jclouds.util.Throwables2.containsThrowable;
import static org.jclouds.util.Throwables2.propagateAuthorizationOrOriginalException;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@ -29,20 +34,18 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.javax.annotation.Nullable;
import javax.annotation.Resource;
import javax.inject.Named;
import org.jclouds.Constants;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.logging.Logger;
import org.jclouds.rest.AuthorizationException;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
/**
@ -82,6 +85,7 @@ public class FutureIterables {
return transformParallel(fromIterable, function, exec, maxTime, logger, logPrefix, retryHandler, maxRetries);
}
@SuppressWarnings("unchecked")
public static <F, T> Iterable<T> transformParallel(Iterable<F> fromIterable,
Function<? super F, Future<T>> function, ExecutorService exec, @Nullable Long maxTime, Logger logger,
String logPrefix, BackoffLimitedRetryHandler retryHandler, int maxRetries) {
@ -93,7 +97,7 @@ public class FutureIterables {
responses.put(from, function.apply(from));
}
exceptions = awaitCompletion(responses, exec, maxTime, logger, logPrefix);
if (exceptions.size() > 0) {
if (exceptions.size() > 0 && !any(exceptions.values(), containsThrowable(AuthorizationException.class))) {
fromIterable = exceptions.keySet();
retryHandler.imposeBackoffExponentialDelay(delayStart, 2, i + 1, maxRetries,
String.format("error %s: %s: %s", logPrefix, fromIterable, exceptions));
@ -101,8 +105,10 @@ public class FutureIterables {
break;
}
}
//make sure we propagate any authorization exception so that we don't lock out accounts
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());
}
@ -116,7 +122,7 @@ public class FutureIterables {
final AtomicInteger complete = new AtomicInteger(0);
final AtomicInteger errors = new AtomicInteger(0);
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()) {
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);
TimeoutException exception = new TimeoutException(message);
logger.error(exception, message);
Throwables.propagate(exception);
propagate(exception);
}
return errorMap;
}
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
public T apply(Future<T> from) {
try {
return from.get();
} catch (InterruptedException e) {
Throwables.propagate(e);
propagate(e);
} catch (ExecutionException e) {
Throwables.propagate(e);
propagate(e);
}
return null;
}

View File

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

View File

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

View File

@ -20,6 +20,8 @@ package org.jclouds.location.config;
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
@ -28,6 +30,20 @@ import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
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.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
@ -36,35 +52,100 @@ import com.google.inject.AbstractModule;
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
*/
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
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);
}
}

View File

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

View File

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

View File

@ -32,6 +32,7 @@ import org.jclouds.location.Provider;
import org.jclouds.location.Region;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
* Return a uri corresponding to the name of the region (passed argument).
@ -41,25 +42,26 @@ import com.google.common.base.Function;
*/
@Singleton
public class RegionToEndpointOrProviderIfNull implements Function<Object, URI> {
private final URI defaultUri;
private final Supplier<URI> defaultUri;
private final String defaultProvider;
private final Map<String, URI> regionToEndpoint;
private final Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier;
@Inject
public RegionToEndpointOrProviderIfNull(@Provider String defaultProvider, @Provider URI defaultUri,
@Region Map<String, URI> regionToEndpoint) {
public RegionToEndpointOrProviderIfNull(@Provider String defaultProvider, @Provider Supplier<URI> defaultUri,
@Region Supplier<Map<String, Supplier<URI>>> regionToEndpointSupplier) {
this.defaultProvider = checkNotNull(defaultProvider, "defaultProvider");
this.defaultUri = checkNotNull(defaultUri, "defaultUri");
this.regionToEndpoint = checkNotNull(regionToEndpoint, "regionToEndpoint");
this.regionToEndpointSupplier = checkNotNull(regionToEndpointSupplier, "regionToEndpointSupplier");
}
@Override
public URI apply(@Nullable Object from) {
if (from == null || from.equals(defaultProvider))
return defaultUri;
return defaultUri.get();
checkArgument(from instanceof String, "region is a String argument");
Map<String, Supplier<URI>> regionToEndpoint = regionToEndpointSupplier.get();
checkArgument(regionToEndpoint.containsKey(from),
"requested location %s, which is not in the configured locations: %s", from, regionToEndpoint);
return regionToEndpoint.get(from);
return regionToEndpoint.get(from).get();
}
}

View File

@ -18,8 +18,8 @@
*/
package org.jclouds.location.functions;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Preconditions.*;
import java.net.URI;
import java.util.Map;
@ -31,6 +31,7 @@ import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Zone;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
*
@ -39,17 +40,20 @@ import com.google.common.base.Function;
@Singleton
public class ZoneToEndpoint implements Function<Object, URI> {
private final Map<String, URI> zoneToEndpoint;
private final Supplier<Map<String, Supplier<URI>>> zoneToEndpointSupplier;
@Inject
public ZoneToEndpoint(@Zone Map<String, URI> zoneToEndpoint) {
this.zoneToEndpoint = checkNotNull(zoneToEndpoint, "zoneToEndpoint");
checkArgument(zoneToEndpoint.size() > 0, "no zone name to endpoint mappings configured!");
public ZoneToEndpoint(@Zone Supplier<Map<String, Supplier<URI>>> zoneToEndpointSupplier) {
this.zoneToEndpointSupplier = checkNotNull(zoneToEndpointSupplier, "zoneToEndpointSupplier");
}
@Override
public URI apply(@Nullable Object from) {
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();
}
}

View File

@ -33,6 +33,24 @@ import com.google.common.base.Predicate;
*/
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() {
return IsZone.INSTANCE;
}

View File

@ -16,40 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.config;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
package org.jclouds.location.suppliers;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.JustProvider;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstRegionOptionallyMatchingRegionId;
import com.google.common.base.Supplier;
import com.google.inject.TypeLiteral;
import com.google.inject.ImplementedBy;
/**
*
* @author Adrian Cole
*
*/
public class JustProviderLocationModule extends LocationModule {
public JustProviderLocationModule() {
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();
}
@ImplementedBy(OnlyLocationOrFirstRegionOptionallyMatchingRegionId.class)
public interface ImplicitLocationSupplier extends Supplier<Location> {
}

View File

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

View File

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

View File

@ -16,31 +16,21 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.config;
package org.jclouds.location.suppliers;
import java.util.Set;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.OnlyLocationOrFirstRegionOptionallyMatchingRegionId;
import org.jclouds.location.suppliers.RegionToProviderOrJustProvider;
import org.jclouds.location.suppliers.all.ZoneToRegionToProviderOrJustProvider;
import com.google.common.base.Supplier;
import com.google.inject.TypeLiteral;
import com.google.inject.ImplementedBy;
/**
*
* @author Adrian Cole
*
*/
public class RegionsLocationModule extends LocationModule {
@Override
protected void configure() {
bind(new TypeLiteral<Supplier<Set<? extends Location>>>() {
}).to(RegionToProviderOrJustProvider.class);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstRegionOptionallyMatchingRegionId.class);
super.configure();
}
@ImplementedBy(ZoneToRegionToProviderOrJustProvider.class)
public interface LocationsSupplier extends Supplier<Set<? extends Location>> {
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers;
package org.jclouds.location.suppliers.all;
import static com.google.common.base.Preconditions.checkNotNull;
@ -42,20 +42,20 @@ import com.google.common.collect.ImmutableSet;
@Singleton
public class JustProvider implements Supplier<Set<? extends Location>> {
private final String providerName;
private final URI endpoint;
private final Set<String> isoCodes;
private final URI endpointSupplier;
private final Set<String> isoCodesSupplier;
@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.endpoint = checkNotNull(endpoint, "endpoint");
this.isoCodes = checkNotNull(isoCodes, "isoCodes");
this.endpointSupplier = checkNotNull(endpointSupplier, "endpoint");
this.isoCodesSupplier = checkNotNull(isoCodesSupplier, "isoCodes");
}
@Override
public Set<? extends Location> get() {
return ImmutableSet.of(new LocationBuilder().scope(LocationScope.PROVIDER).id(providerName)
.description(endpoint.toASCIIString()).iso3166Codes(isoCodes).build());
.description(endpointSupplier.toASCIIString()).iso3166Codes(isoCodesSupplier).build());
}
}

View File

@ -16,11 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers;
package org.jclouds.location.suppliers.all;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import java.util.Set;
@ -31,9 +30,9 @@ 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.Region;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.ImmutableSet.Builder;
@ -43,37 +42,36 @@ import com.google.common.collect.ImmutableSet.Builder;
* @author Adrian Cole
*/
@Singleton
public class RegionToProviderOrJustProvider extends JustProvider {
private final Set<String> regions;
private final Map<String, Set<String>> isoCodesById;
public class RegionToProviderOrJustProvider implements Supplier<Set<? extends Location>> {
private final JustProvider justProvider;
private final Supplier<Set<String>> regionsSupplier;
private final Supplier<Map<String, Supplier<Set<String>>>> isoCodesByIdSupplier;
@Inject
public RegionToProviderOrJustProvider(@Iso3166 Set<String> isoCodes, @Provider String providerName,
@Provider URI endpoint, @Region Set<String> regions, @Iso3166 Map<String, Set<String>> isoCodesById) {
super(providerName, endpoint, isoCodes);
this.regions = checkNotNull(regions, "regions");
this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById");
public RegionToProviderOrJustProvider(JustProvider justProvider, @Region Supplier<Set<String>> regionsSupplier,
@Iso3166 Supplier<Map<String, Supplier<Set<String>>>> isoCodesByIdSupplier) {
this.justProvider = checkNotNull(justProvider, "justProvider");
this.regionsSupplier = checkNotNull(regionsSupplier, "regionsSupplier");
this.isoCodesByIdSupplier = checkNotNull(isoCodesByIdSupplier, "isoCodesByIdSupplier");
}
@Override
public Set<? extends Location> get() {
return buildJustProviderOrRegions().build();
}
protected Builder<Location> buildJustProviderOrRegions() {
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)
return locations.add(provider);
return locations.add(provider).build();
else
for (String region : regions) {
LocationBuilder builder = new LocationBuilder().scope(LocationScope.REGION).id(region).description(region)
.parent(provider);
if (isoCodesById.containsKey(region))
builder.iso3166Codes(isoCodesById.get(region));
builder.iso3166Codes(isoCodesById.get(region).get());
locations.add(builder.build());
}
return locations;
return locations.build();
}
}

View File

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

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.config;
package org.jclouds.location.suppliers.fromconfig;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES;
@ -30,45 +30,48 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.location.Iso3166;
import org.jclouds.location.suppliers.LocationIdToIso3166CodesSupplier;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
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.Builder;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableMap.Builder;
/**
*
* looks for properties bound to the naming conventions jclouds.region.
* {@code regionId} .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes
* looks for properties bound to the naming conventions jclouds.region. {@code regionId}
* .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes
*
* @author Adrian Cole
*/
@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;
@Inject
ProvideIso3166CodesByLocationIdViaProperties(
Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
public LocationIdToIso3166CodesFromConfiguration(
Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
this.filterStringsBoundByName = checkNotNull(filterStringsBoundByName, "filterStringsBoundByName");
}
@Singleton
@Iso3166
@Override
public Map<String, Set<String>> get() {
public Map<String, Supplier<Set<String>>> get() {
Map<String, String> stringsBoundWithRegionOrZonePrefix = filterStringsBoundByName.apply(new Predicate<String>() {
@Override
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)) {
String regionOrZoneString = stringsBoundWithRegionOrZonePrefix.get(key + "s");
if (regionOrZoneString == null)
@ -76,7 +79,8 @@ public class ProvideIso3166CodesByLocationIdViaProperties implements javax.injec
for (String region : Splitter.on(',').split(regionOrZoneString)) {
String isoCodes = stringsBoundWithRegionOrZonePrefix.get(key + "." + region + "." + ISO3166_CODES);
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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* 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.collect.Iterables.getOnlyElement;
@ -34,9 +34,9 @@ import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Region;
import org.jclouds.location.functions.ToIdAndScope;
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
@ -47,22 +47,23 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole
*/
@Singleton
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionId implements Supplier<Location> {
private final Predicate<Location> locationPredicate;
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionId implements ImplicitLocationSupplier {
private final Supplier<String> regionSupplier;
private final Supplier<Set<? extends Location>> locationsSupplier;
@Inject
OnlyLocationOrFirstRegionOptionallyMatchingRegionId(@Nullable @Region String region,
@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
this.locationPredicate = region == null ? Predicates.<Location>or(isZone(), isRegion())
: isZoneOrRegionWhereRegionIdEquals(region);
OnlyLocationOrFirstRegionOptionallyMatchingRegionId(@Region Supplier<String> regionSupplier,
@Memoized Supplier<Set<? extends Location>> locationsSupplier) {
this.regionSupplier = checkNotNull(regionSupplier, "regionSupplier");
this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier");
}
@Override
@Singleton
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();
if (locationsSupplier.get().size() == 1)
return getOnlyElement(locationsSupplier.get());

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* 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.collect.Iterables.find;
@ -33,6 +33,7 @@ import javax.inject.Singleton;
import org.jclouds.collect.Memoized;
import org.jclouds.domain.Location;
import org.jclouds.location.functions.ToIdAndScope;
import org.jclouds.location.suppliers.ImplicitLocationSupplier;
import com.google.common.base.Supplier;
@ -42,7 +43,7 @@ import com.google.common.base.Supplier;
*
*/
@Singleton
public class OnlyLocationOrFirstZone implements Supplier<Location> {
public class OnlyLocationOrFirstZone implements ImplicitLocationSupplier {
private final Supplier<Set<? extends Location>> locationsSupplier;

View File

@ -19,78 +19,44 @@
package org.jclouds.rest;
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.not;
import static com.google.common.base.Splitter.on;
import static com.google.common.collect.Iterables.addAll;
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.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.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.concurrent.MoreExecutors;
import org.jclouds.concurrent.SingleThreaded;
import org.jclouds.concurrent.config.ConfiguresExecutorService;
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.config.ConfiguresHttpCommandExecutorService;
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.location.Iso3166;
import org.jclouds.location.Provider;
import org.jclouds.location.config.ProvideIso3166CodesByLocationIdViaProperties;
import org.jclouds.logging.config.LoggingModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
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.rest.config.BindPropertiesToAnnotations;
import org.jclouds.rest.config.CredentialStoreModule;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.rest.config.RestModule;
import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.util.Maps2;
import org.nnsoft.guice.rocoto.Rocoto;
import org.nnsoft.guice.rocoto.configuration.ConfigurationModule;
import com.google.common.annotations.VisibleForTesting;
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.common.util.concurrent.ExecutionList;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provides;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
@ -108,115 +74,6 @@ import com.google.inject.TypeLiteral;
* @see RestContext
*/
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 List<Module> modules = new ArrayList<Module>(3);
protected Class<A> asyncClientType;

View File

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

View File

@ -18,21 +18,22 @@
*/
package org.jclouds.rest.config;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.domain.Credentials;
import org.jclouds.http.RequiresHttp;
import org.jclouds.internal.ClassMethodArgs;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.location.Provider;
import org.jclouds.location.config.LocationModule;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.internal.RestContextImpl;
import com.google.common.base.Supplier;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
@ -49,10 +50,13 @@ import com.google.inject.util.Types;
@ConfiguresRestClient
@RequiresHttp
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<S> syncClientType;
protected final Map<Class<?>, Class<?>> delegates;
protected final AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
public RestClientModule(Class<S> syncClientType, Class<A> asyncClientType,
Map<Class<?>, Class<?>> delegates) {
@ -65,10 +69,16 @@ public class RestClientModule<S, A> extends AbstractModule {
this(syncClientType, asyncClientType, ImmutableMap
.<Class<?>, Class<?>> of(syncClientType, asyncClientType));
}
protected void installLocations() {
install(new LocationModule());
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
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.
bind(new TypeLiteral<RestContext>() {
}).to(
@ -82,6 +92,7 @@ public class RestClientModule<S, A> extends AbstractModule {
bindClient();
bindErrorHandlers();
bindRetryHandlers();
installLocations();
}
/**

View File

@ -139,6 +139,7 @@ import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.base.Throwables;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@ -759,7 +760,10 @@ public class RestAnnotationProcessor<T> {
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 {
URI endpoint = getEndpointInParametersOrNull(method, args, injector);
if (endpoint == null) {
@ -771,18 +775,22 @@ public class RestAnnotationProcessor<T> {
} else {
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) {
checkNotNull(withHost,"URI witHost cannot be null");
checkArgument(withHost.getHost()!=null, "URI withHost must have host:"+withHost);
checkNotNull(withHost, "URI witHost cannot be null");
checkArgument(withHost.getHost() != null, "URI withHost must have host:" + withHost);
if(original == null) return null;
if (original.getHost() != null) return original;
return withHost.resolve(original);
if (original == null)
return null;
if (original.getHost() != null)
return original;
return withHost.resolve(original);
}
public static final TypeLiteral<ListenableFuture<Boolean>> futureBooleanLiteral = new TypeLiteral<ListenableFuture<Boolean>>() {

View File

@ -47,6 +47,11 @@ public class MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier<T> imp
private final Supplier<T> delegate;
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(
AtomicReference<AuthorizationException> authException, long seconds, Supplier<T> delegate) {
this.delegate = memoizeWithExpirationOnAbsoluteInterval(new RetryOnTimeOutExceptionSupplier<T>(

View File

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

View File

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

View File

@ -41,6 +41,19 @@ import com.google.common.collect.Multimap;
* @author Adrian Cole
*/
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) {
LinkedHashMap<K, V> out = Maps.newLinkedHashMap();

View File

@ -26,8 +26,10 @@ import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.io.OutputSupplier;
/**
@ -36,6 +38,21 @@ import com.google.common.io.OutputSupplier;
*/
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}
*
@ -52,9 +69,11 @@ public class Suppliers2 {
/**
* 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);
}
@ -85,16 +104,17 @@ public class Suppliers2 {
if (nanos == 0 || now - nanos >= 0) {
synchronized (this) {
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;
T t = delegate.get();
value = t;
// Update now so that, if call was expensive, we keep value for the full duration
now = System.nanoTime();
nanos = now + durationNanos;
// In the very unlikely event that nanos is 0, set it to 1;
// no one will notice 1 ns of tardiness.

View File

@ -25,11 +25,13 @@ import static com.google.common.collect.Iterables.find;
import java.util.NoSuchElementException;
import org.jclouds.concurrent.TransformParallelException;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.InsufficientResourcesException;
import org.jclouds.rest.ResourceNotFoundException;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.inject.CreationException;
import com.google.inject.ProvisionException;
@ -42,10 +44,26 @@ import com.google.inject.spi.Message;
*/
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")
public static <T extends Throwable> T getFirstThrowableOfType(Throwable from, Class<T> clazz) {
if (from instanceof ProvisionException)
return getFirstThrowableOfType(ProvisionException.class.cast(from), clazz);
else if (from instanceof TransformParallelException)
return getFirstThrowableOfType(TransformParallelException.class.cast(from), clazz);
else if (from instanceof CreationException)
return getFirstThrowableOfType(CreationException.class.cast(from), clazz);
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) {
for (Message message : e.getErrorMessages()) {
if (message.getCause() != null) {
T cause = getFirstThrowableOfType(message.getCause(), clazz);
if (cause instanceof ProvisionException)
return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz);
else if (cause instanceof TransformParallelException)
return getFirstThrowableOfType(TransformParallelException.class.cast(cause), clazz);
else if (cause instanceof CreationException)
return getFirstThrowableOfType(CreationException.class.cast(cause), clazz);
return cause;
@ -75,6 +104,8 @@ public class Throwables2 {
T cause = getFirstThrowableOfType(message.getCause(), clazz);
if (cause instanceof ProvisionException)
return getFirstThrowableOfType(ProvisionException.class.cast(cause), clazz);
else if (cause instanceof TransformParallelException)
return getFirstThrowableOfType(TransformParallelException.class.cast(cause), clazz);
else if (cause instanceof CreationException)
return getFirstThrowableOfType(CreationException.class.cast(cause), clazz);
return cause;
@ -99,9 +130,10 @@ public class Throwables2 {
return (Exception) throwable;
}
}
for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class, AssertionError.class,
UnsupportedOperationException.class, IllegalArgumentException.class, AuthorizationException.class,
ResourceNotFoundException.class, InsufficientResourcesException.class, HttpResponseException.class }) {
for (Class<Exception> propagatableExceptionType : new Class[] { IllegalStateException.class,
AssertionError.class, UnsupportedOperationException.class, IllegalArgumentException.class,
AuthorizationException.class, ResourceNotFoundException.class, InsufficientResourcesException.class,
HttpResponseException.class }) {
Throwable throwable = getFirstThrowableOfType(exception, propagatableExceptionType);
if (throwable != null) {
if (throwable instanceof AssertionError)

View File

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

View File

@ -18,232 +18,66 @@
*/
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.jclouds.concurrent.FutureIterables.transformParallel;
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.atomic.AtomicInteger;
import org.jclouds.logging.Logger;
import org.jclouds.rest.AuthorizationException;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of FutureIterables
*
* @author Adrian Cole
*/
@Test(groups = "performance", enabled = false, sequential = true, testName = "FutureIterablesTest")
@Test(groups = "unit", singleThreaded = true, testName = "FutureIterablesTest")
public class FutureIterablesTest {
ExecutorService ioFunctionExecutor = newCachedThreadPool();
@Test(enabled = false)
public void testMakeListenableDoesntSerializeFutures() throws InterruptedException, ExecutionException {
long expectedMax = IO_DURATION;
long expectedMin = IO_DURATION;
long expectedOverhead = COUNT + FUDGE;
public void testAuthorizationExceptionPropagatesAndOnlyTriesOncePerElement() {
final AtomicInteger counter = new AtomicInteger();
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>() {
transformParallel(ImmutableSet.of("hello", "goodbye"), new Function<String, Future<String>>() {
@Override
public Long apply(Long from) {
try {
Thread.sleep(LISTENER_DURATION);
} catch (InterruptedException e) {
propagate(e);
}
return System.currentTimeMillis();
public Future<String> apply(String input) {
counter.incrementAndGet();
return com.google.common.util.concurrent.Futures.immediateFailedFuture(new AuthorizationException());
}
}, listenerExecutor));
checkTimeThresholds(expectedMin, expectedMax, expectedOverhead, start, responses);
}, MoreExecutors.sameThreadExecutor(), null, Logger.CONSOLE, "");
assert false;
} catch (AuthorizationException e) {
assertEquals(counter.get(), 2);
}
}
public void testNormalExceptionPropagatesAsTransformParallelExceptionAndTries5XPerElement() {
final AtomicInteger counter = new AtomicInteger();
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;
}
try {
transformParallel(ImmutableSet.of("hello", "goodbye"), new Function<String, Future<String>>() {
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) {
@Override
public Future<String> apply(String input) {
counter.incrementAndGet();
return com.google.common.util.concurrent.Futures.immediateFailedFuture(new RuntimeException());
}
return null;
}
});
long time = Collections.max(Sets.newHashSet(collection));
return time;
}, MoreExecutors.sameThreadExecutor(), null, Logger.CONSOLE, "");
assert false;
} 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);
}
}

View File

@ -23,10 +23,13 @@ import static org.testng.Assert.assertEquals;
import java.util.Map;
import java.util.Set;
import org.jclouds.location.suppliers.LocationIdToIso3166CodesSupplier;
import org.jclouds.util.Suppliers2;
import org.testng.annotations.Test;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
@ -42,14 +45,14 @@ import com.google.inject.Provides;
public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
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());
}
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"));
assertEquals(fn.get(), ImmutableMap.<String, Set<String>> of());
@ -57,20 +60,18 @@ public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
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.zone.us-easta.iso3166-codes", "US-CA"));
assertEquals(
fn.get(),
ImmutableMap.<String, Set<String>> of("us-east", ImmutableSet.of("US"), "us-easta",
ImmutableSet.of("US-CA")));
assertEquals(Maps.transformValues(fn.get(), Suppliers.<Set<String>> supplierFunction()), ImmutableMap
.<String, Set<String>> of("us-east", ImmutableSet.of("US"), "us-easta", ImmutableSet.of("US-CA")));
}
//
private ProvideIso3166CodesByLocationIdViaProperties createWithValue(final ImmutableMap<String, String> value) {
ProvideIso3166CodesByLocationIdViaProperties fn = Guice.createInjector(new AbstractModule() {
private LocationIdToIso3166CodesSupplier createWithValue(final ImmutableMap<String, String> value) {
LocationIdToIso3166CodesSupplier fn = Guice.createInjector(new AbstractModule() {
@SuppressWarnings("unused")
@Provides
Function<Predicate<String>, Map<String, String>> provide() {
@ -87,7 +88,7 @@ public class ProvideIso3166CodesByLocationIdViaPropertiesTest {
protected void configure() {
}
}).getInstance(ProvideIso3166CodesByLocationIdViaProperties.class);
}).getInstance(LocationIdToIso3166CodesSupplier.class);
return fn;
}

View File

@ -22,9 +22,12 @@ import static org.testng.Assert.assertEquals;
import java.io.File;
import java.net.URI;
import java.util.Map;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
/**
@ -37,33 +40,34 @@ public class RegionToEndpointOrProviderIfNullTest {
@Test
public void testWhenFindsRegion() throws SecurityException, NoSuchMethodException {
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
ImmutableMap.of("1", URI.create("http://1")));
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
.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"));
}
public void testNullReturnsProvider() {
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
ImmutableMap.of("1", URI.create("http://1")));
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
.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"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMustBeString() {
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
ImmutableMap.of("1", URI.create("http://1")));
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
.create("http://leader")), Suppliers.<Map<String, Supplier<URI>>>ofInstance(ImmutableMap.of("1", Suppliers.ofInstance(URI.create("http://1")))));
fn.apply(new File("foo"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testMustBeInRegionMapIfSpecified() {
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", URI.create("http://leader"),
ImmutableMap.of("1", URI.create("http://1")));
RegionToEndpointOrProviderIfNull fn = new RegionToEndpointOrProviderIfNull("leader", Suppliers.ofInstance(URI
.create("http://leader")), Suppliers.<Map<String, Supplier<URI>>>ofInstance(ImmutableMap.of("1", Suppliers.ofInstance(URI.create("http://1")))));
fn.apply("2");
}
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()));
}
}

View File

@ -22,9 +22,12 @@ import static org.testng.Assert.assertEquals;
import java.io.File;
import java.net.URI;
import java.util.Map;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
/**
@ -36,25 +39,30 @@ import com.google.common.collect.ImmutableMap;
public class ZoneToEndpointTest {
@Test
public void testCorrect() throws SecurityException, NoSuchMethodException {
ZoneToEndpoint fn = new ZoneToEndpoint(ImmutableMap.of("1", URI.create("http://1")));
public void testCorrect() {
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"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
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"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
@Test(expectedExceptions = IllegalStateException.class)
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)
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);
}
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers;
package org.jclouds.location.suppliers.all;
import static org.testng.Assert.assertEquals;
@ -24,6 +24,7 @@ import java.net.URI;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.all.JustProvider;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers;
package org.jclouds.location.suppliers.implicit;
import static org.testng.Assert.assertEquals;
@ -40,55 +40,55 @@ import com.google.common.collect.ImmutableSet;
@Test(groups = "unit", testName = "OnlyLocationOrFirstRegionOptionallyMatchingRegionIdTest")
public class OnlyLocationOrFirstRegionOptionallyMatchingRegionIdTest {
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")
.parent(provider).build();
.parent(provider).build();
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")
.parent(region).build();
.parent(region).build();
@Test
public void testDidntMatchRegionIdThrowsNSEEWithReasonableMessage() {
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(
"foo", supplier);
Suppliers.ofInstance("foo"), supplier);
try {
fn.get();
assert false;
} catch (NoSuchElementException e) {
assertEquals(
e.getMessage(),
"couldn't find region matching isRegionAndIdEqualsOrIsZoneParentIdEquals(foo) in [servo:PROVIDER, servo-r1:REGION, servo-r2:REGION, servo-z:ZONE]");
e.getMessage(),
"couldn't find region matching isRegionAndIdEqualsOrIsZoneParentIdEquals(foo) in [servo:PROVIDER, servo-r1:REGION, servo-r2:REGION, servo-z:ZONE]");
}
}
@Test
public void testNoRegionUsesProvider() {
Supplier<Set<? extends Location>> supplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(provider));
.<Location> of(provider));
OnlyLocationOrFirstRegionOptionallyMatchingRegionId fn = new OnlyLocationOrFirstRegionOptionallyMatchingRegionId(
null, supplier);
Suppliers.<String>ofInstance(null), supplier);
assertEquals(fn.get(), provider);
}
@Test
public void testFirstRegion() {
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(
null, supplier);
Suppliers.<String>ofInstance(null), supplier);
assertEquals(fn.get(), region);
}
@Test
public void testFindRegion() {
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(
region2.getId(), supplier);
Suppliers.ofInstance(region2.getId()), supplier);
assertEquals(fn.get(), region2);
}
}

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.location.suppliers;
package org.jclouds.location.suppliers.implicit;
import static org.testng.Assert.assertEquals;
@ -26,6 +26,7 @@ import java.util.Set;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationBuilder;
import org.jclouds.domain.LocationScope;
import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;

View File

@ -144,6 +144,8 @@ import org.testng.annotations.Test;
import com.google.common.base.Function;
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.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
@ -181,7 +183,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@Override
protected void 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);
}
@ -2436,7 +2440,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
}).toInstance(ImmutableSet.of("foo"));
bind(new TypeLiteral<Set<String>>() {
}).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")

View File

@ -26,8 +26,11 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.SocketException;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.concurrent.TransformParallelException;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
@ -36,6 +39,7 @@ import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.CreationException;
import com.google.inject.ProvisionException;
@ -113,6 +117,38 @@ public class Throwables2Test {
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
public void testReturnExceptionThatsInList() throws Exception {
Exception e = new TestException();

View File

@ -18,22 +18,7 @@
*/
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.Provides;
/**
*
@ -41,25 +26,8 @@ import com.google.inject.Provides;
*/
public abstract class BaseLoadBalancerServiceContextModule extends AbstractModule {
protected AtomicReference<AuthorizationException> authException = new AtomicReference<AuthorizationException>();
@Override
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();
}
});
}
}

View File

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

View File

@ -22,7 +22,6 @@ import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.OnlyLocationOrFirstZone;
import org.jclouds.servermanager.Datacenter;
import org.jclouds.servermanager.Hardware;
import org.jclouds.servermanager.Image;
@ -35,7 +34,6 @@ import org.jclouds.servermanager.compute.functions.ServerToNodeMetadata;
import org.jclouds.servermanager.compute.strategy.ServerManagerComputeServiceAdapter;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.inject.TypeLiteral;
/**
@ -62,7 +60,7 @@ public class ServerManagerComputeServiceContextModule extends
}).to(ServerManagerHardwareToHardware.class);
bind(new TypeLiteral<Function<Datacenter, Location>>() {
}).to(DatacenterToLocation.class);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
// to have the compute service adapter override default locations
install(new LocationsFromComputeServiceAdapterModule<Server, Hardware, Image, Datacenter>(){});
}
}