mirror of https://github.com/apache/jclouds.git
Make the OpenStack extension lists accessible for all APIs. Copied the Nova extension related code to the shared keystone package and added providers for extensions and aliases to all modules
This commit is contained in:
parent
f9a550529d
commit
0da2616737
|
@ -21,12 +21,16 @@ package org.jclouds.openstack.keystone.v2_0;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.functions.ZoneToEndpoint;
|
||||
import org.jclouds.openstack.keystone.v2_0.domain.ApiMetadata;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.ServiceApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.TenantApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.TokenApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.UserApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
|
@ -54,6 +58,12 @@ public interface KeystoneApi {
|
|||
@Delegate
|
||||
ServiceApi getServiceApi();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionApi getExtensionApi();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Token features
|
||||
*/
|
||||
|
@ -66,7 +76,6 @@ public interface KeystoneApi {
|
|||
@Delegate
|
||||
Optional<UserApi> getUserApi();
|
||||
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Tenant features
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.jclouds.openstack.keystone.v2_0.features.ServiceAsyncApi;
|
|||
import org.jclouds.openstack.keystone.v2_0.features.TenantAsyncApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.TokenAsyncApi;
|
||||
import org.jclouds.openstack.keystone.v2_0.features.UserAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
|
@ -60,6 +61,12 @@ public interface KeystoneAsyncApi {
|
|||
@Delegate
|
||||
ServiceAsyncApi getServiceApi();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionAsyncApi getExtensionApi();
|
||||
|
||||
/**
|
||||
* @see KeystoneApi#getTokenApi()
|
||||
*/
|
||||
|
@ -71,7 +78,6 @@ public interface KeystoneAsyncApi {
|
|||
*/
|
||||
@Delegate
|
||||
Optional<UserAsyncApi> getUserApi();
|
||||
|
||||
|
||||
/**
|
||||
* @see KeystoneApi#getTenantApi()
|
||||
|
|
|
@ -23,6 +23,8 @@ import static org.jclouds.util.Suppliers2.getLastValueInMap;
|
|||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
|
@ -46,6 +48,9 @@ import org.jclouds.openstack.keystone.v2_0.handlers.KeystoneErrorHandler;
|
|||
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAccessForTypeAndVersion;
|
||||
import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURISupplier;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.services.Identity;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
|
@ -54,7 +59,13 @@ import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
|||
import org.jclouds.util.Suppliers2;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -70,17 +81,18 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
|
|||
RestClientModule<S, A> {
|
||||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||
.put(ServiceApi.class, ServiceAsyncApi.class).put(TokenApi.class, TokenAsyncApi.class)
|
||||
.put(UserApi.class, UserAsyncApi.class).put(TenantApi.class, TenantAsyncApi.class).build();
|
||||
.put(ServiceApi.class, ServiceAsyncApi.class)
|
||||
.put(ExtensionApi.class, ExtensionAsyncApi.class)
|
||||
.put(TokenApi.class, TokenAsyncApi.class)
|
||||
.put(UserApi.class, UserAsyncApi.class)
|
||||
.put(TenantApi.class, TenantAsyncApi.class)
|
||||
.build();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KeystoneRestClientModule() {
|
||||
super(TypeToken.class.cast(TypeToken.of(KeystoneApi.class)), TypeToken.class.cast(TypeToken
|
||||
.of(KeystoneAsyncApi.class)), DELEGATE_MAP);
|
||||
super(TypeToken.class.cast(TypeToken.of(KeystoneApi.class)), TypeToken.class.cast(TypeToken.of(KeystoneAsyncApi.class)), DELEGATE_MAP);
|
||||
}
|
||||
|
||||
protected KeystoneRestClientModule(TypeToken<S> syncApiType, TypeToken<A> asyncApiType,
|
||||
Map<Class<?>, Class<?>> sync2Async) {
|
||||
protected KeystoneRestClientModule(TypeToken<S> syncApiType, TypeToken<A> asyncApiType, Map<Class<?>, Class<?>> sync2Async) {
|
||||
super(syncApiType, asyncApiType, sync2Async);
|
||||
}
|
||||
|
||||
|
@ -111,6 +123,25 @@ public class KeystoneRestClientModule<S extends KeystoneApi, A extends KeystoneA
|
|||
return whenIdentityServiceHasNoAdminURLFallbackToProviderURI;
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Multimap<URI, URI> aliases() {
|
||||
return ImmutableMultimap.<URI, URI>builder()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final javax.inject.Provider<KeystoneApi> keystoneApi) {
|
||||
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
|
||||
.build(CacheLoader.from(Suppliers.memoize(new Supplier<Set<? extends Extension>>() {
|
||||
@Override
|
||||
public Set<? extends Extension> get() {
|
||||
return keystoneApi.get().getExtensionApi().listExtensions();
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.domain;
|
||||
package org.jclouds.openstack.v2_0.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -26,8 +26,6 @@ import java.util.Date;
|
|||
import java.util.Set;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
|
@ -16,13 +16,13 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
package org.jclouds.openstack.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extensions via their REST API.
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.features;
|
||||
package org.jclouds.openstack.v2_0.features;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -27,7 +27,7 @@ import javax.ws.rs.PathParam;
|
|||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.functions;
|
||||
package org.jclouds.openstack.v2_0.functions;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
|
@ -25,7 +25,7 @@ import javax.inject.Provider;
|
|||
import javax.inject.Singleton;
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* 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.openstack.v2_0.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.predicates.ExtensionPredicates;
|
||||
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* We use the annotation {@link org.jclouds.openstack.services.Extension} to
|
||||
* bind a class that iimplements an extension API to an {@link Extension}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet implements
|
||||
ImplicitOptionalConverter {
|
||||
private final LoadingCache<String, Set<? extends Extension>> extensions;
|
||||
private final Multimap<URI, URI> aliases;
|
||||
|
||||
@Inject
|
||||
public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet(
|
||||
LoadingCache<String, Set<? extends Extension>> extensions,
|
||||
Multimap<URI, URI> aliases) {
|
||||
this.extensions = checkNotNull(extensions, "extensions");
|
||||
this.aliases = aliases == null ? ImmutableMultimap.<URI, URI>of() : ImmutableMultimap.copyOf(aliases);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Object> apply(ClassMethodArgsAndReturnVal input) {
|
||||
Optional<org.jclouds.openstack.v2_0.services.Extension> ext = Optional.fromNullable(input.getClazz().getAnnotation(
|
||||
org.jclouds.openstack.v2_0.services.Extension.class));
|
||||
if (ext.isPresent()) {
|
||||
URI namespace = URI.create(ext.get().namespace());
|
||||
if (input.getArgs() == null || input.getArgs().length == 0) {
|
||||
if (Iterables.any(extensions.getUnchecked(""),
|
||||
ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace))))
|
||||
return Optional.of(input.getReturnVal());
|
||||
} else if (input.getArgs() != null && input.getArgs().length == 1) {
|
||||
if (Iterables.any(extensions.getUnchecked(checkNotNull(input.getArgs()[0], "arg[0] in %s", input).toString()),
|
||||
ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace))))
|
||||
return Optional.of(input.getReturnVal());
|
||||
} else {
|
||||
throw new RuntimeException(String.format("expecting zero or one args %s", input));
|
||||
}
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "presentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet()";
|
||||
}
|
||||
|
||||
}
|
|
@ -16,14 +16,14 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.predicates;
|
||||
package org.jclouds.openstack.v2_0.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package org.jclouds.openstack.nova.v2_0.functions;
|
||||
package org.jclouds.openstack.v2_0.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
|
@ -8,8 +8,7 @@ import javax.inject.Provider;
|
|||
import javax.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.sun.jersey.api.uri.UriBuilderImpl;
|
||||
|
@ -39,6 +38,6 @@ public class ExtensionToNameSpaceTest {
|
|||
assertEquals(fn.apply(Extension.builder().alias("security_groups").name("SecurityGroups").namespace(
|
||||
URI.create("https://docs.openstack.org/ext/securitygroups/api/v1.1")).updated(
|
||||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-07-21T00:00:00+00:00")).description(
|
||||
"Security group support").build()), URI.create(ExtensionNamespaces.SECURITY_GROUPS));
|
||||
"Security group support").build()), URI.create("http://docs.openstack.org/ext/securitygroups/api/v1.1"));
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package org.jclouds.openstack.nova.v2_0.functions;
|
||||
package org.jclouds.openstack.v2_0.functions;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
|
@ -9,10 +9,9 @@ import javax.inject.Named;
|
|||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -40,8 +39,8 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description(
|
||||
"Keypair Support").build();
|
||||
|
||||
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.KEYPAIRS)
|
||||
static interface KeyPairIPAsyncApi {
|
||||
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = "http://docs.openstack.org/ext/keypairs/api/v1.1")
|
||||
static interface KeyPairAsyncApi {
|
||||
|
||||
}
|
||||
|
||||
|
@ -50,7 +49,7 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-06-16T00:00:00+00:00")).description(
|
||||
"Floating IPs support").build();
|
||||
|
||||
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IPS)
|
||||
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, namespace = "http://docs.openstack.org/ext/floating_ips/api/v1.1")
|
||||
static interface FloatingIPAsyncApi {
|
||||
|
||||
}
|
||||
|
@ -68,27 +67,27 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
ClassMethodArgsAndReturnVal getFloatingIPExtension() throws SecurityException, NoSuchMethodException {
|
||||
return ClassMethodArgsAndReturnVal.builder().clazz(FloatingIPAsyncApi.class).method(
|
||||
NovaAsyncApi.class.getDeclaredMethod("getFloatingIPExtensionForZone", String.class)).args(
|
||||
new Object[] { "expectedzone" }).returnVal("foo").build();
|
||||
new Object[] { "zone" }).returnVal("foo").build();
|
||||
}
|
||||
|
||||
ClassMethodArgsAndReturnVal getKeyPairExtension() throws SecurityException, NoSuchMethodException {
|
||||
return ClassMethodArgsAndReturnVal.builder().clazz(KeyPairAsyncApi.class).method(
|
||||
NovaAsyncApi.class.getDeclaredMethod("getKeyPairExtensionForZone", String.class)).args(
|
||||
new Object[] { "expectedzone" }).returnVal("foo").build();
|
||||
new Object[] { "zone" }).returnVal("foo").build();
|
||||
}
|
||||
|
||||
public void testPresentWhenExtensionsIncludeNamespaceFromAnnotationAbsentWhenNot() throws SecurityException, NoSuchMethodException {
|
||||
|
||||
assertEquals(whenExtensionsInclude(keypairs, floatingIps).apply(getFloatingIPExtension()), Optional.of("foo"));
|
||||
assertEquals(whenExtensionsInclude(keypairs, floatingIps).apply(getKeyPairExtension()), Optional.of("foo"));
|
||||
assertEquals(whenExtensionsInclude(keypairs).apply(getFloatingIPExtension()), Optional.absent());
|
||||
assertEquals(whenExtensionsInclude(floatingIps).apply(getKeyPairExtension()), Optional.absent());
|
||||
assertEquals(whenExtensionsInZoneInclude("zone", keypairs, floatingIps).apply(getFloatingIPExtension()), Optional.of("foo"));
|
||||
assertEquals(whenExtensionsInZoneInclude("zone", keypairs, floatingIps).apply(getKeyPairExtension()), Optional.of("foo"));
|
||||
assertEquals(whenExtensionsInZoneInclude("zone", keypairs).apply(getFloatingIPExtension()), Optional.absent());
|
||||
assertEquals(whenExtensionsInZoneInclude("zone", floatingIps).apply(getKeyPairExtension()), Optional.absent());
|
||||
}
|
||||
|
||||
public void testZoneWithoutExtensionsReturnsAbsent() throws SecurityException, NoSuchMethodException {
|
||||
assertEquals(whenExtensionsInclude(floatingIps).apply(
|
||||
assertEquals(whenExtensionsInZoneInclude("zone", floatingIps).apply(
|
||||
getFloatingIPExtension().toBuilder().args(new Object[] { "differentzone" }).build()), Optional.absent());
|
||||
assertEquals(whenExtensionsInclude(keypairs).apply(
|
||||
assertEquals(whenExtensionsInZoneInclude("zone", keypairs).apply(
|
||||
getKeyPairExtension().toBuilder().args(new Object[] { "differentzone" }).build()), Optional.absent());
|
||||
}
|
||||
|
||||
|
@ -105,22 +104,22 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
Multimap<URI, URI> aliases = ImmutableMultimap.of(keypairs.getNamespace(), keypairsWithDifferentNamespace
|
||||
.getNamespace());
|
||||
|
||||
assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply(
|
||||
assertEquals(whenExtensionsAndAliasesInZoneInclude("zone", ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply(
|
||||
getKeyPairExtension()), Optional.of("foo"));
|
||||
assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply(
|
||||
assertEquals(whenExtensionsAndAliasesInZoneInclude("zone", ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply(
|
||||
getFloatingIPExtension()), Optional.absent());
|
||||
|
||||
}
|
||||
|
||||
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInclude(
|
||||
Extension... extensions) {
|
||||
return whenExtensionsAndAliasesInclude(ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of());
|
||||
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInZoneInclude(
|
||||
String zone, Extension... extensions) {
|
||||
return whenExtensionsAndAliasesInZoneInclude(zone, ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of());
|
||||
}
|
||||
|
||||
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInclude(
|
||||
final Set<Extension> extensions, final Multimap<URI, URI> aliases) {
|
||||
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInZoneInclude(
|
||||
String zone, final Set<Extension> extensions, final Multimap<URI, URI> aliases) {
|
||||
final LoadingCache<String, Set<? extends Extension>> extensionsForZone = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.forMap(ImmutableMap.<String, Set<? extends Extension>>of("expectedzone", extensions, "differentzone",
|
||||
CacheLoader.from(Functions.forMap(ImmutableMap.<String, Set<? extends Extension>>of(zone, extensions, "differentzone",
|
||||
ImmutableSet.<Extension> of()))));
|
||||
|
||||
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector(
|
||||
|
@ -135,7 +134,6 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
}
|
||||
|
||||
@Provides
|
||||
@Named("openstack.nova.extensions")
|
||||
Multimap<URI, URI> getAliases() {
|
||||
return aliases;
|
||||
}
|
|
@ -16,15 +16,15 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.predicates;
|
||||
package org.jclouds.openstack.v2_0.predicates;
|
||||
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.ExtensionPredicates.aliasEquals;
|
||||
import static org.jclouds.openstack.nova.v2_0.predicates.ExtensionPredicates.namespaceEquals;
|
||||
import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.aliasEquals;
|
||||
import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.namespaceEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
|
@ -39,10 +39,10 @@ import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageApi;
|
|||
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
|
|
@ -37,10 +37,10 @@ import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageAsyncApi;
|
|||
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v2_0.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -29,47 +30,48 @@ import org.jclouds.http.HttpErrorHandler;
|
|||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.AdminActionsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.KeyPairAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.QuotaClassAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SecurityGroupAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ServerWithSecurityGroupsAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.SimpleTenantUsageAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VirtualInterfaceAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.VolumeTypeAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.FlavorAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
|
||||
import org.jclouds.openstack.nova.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerAsyncApi;
|
||||
import org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||
|
@ -78,6 +80,8 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
|
@ -126,18 +130,51 @@ public class NovaRestClientModule<S extends NovaApi, A extends NovaAsyncApi> ext
|
|||
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Multimap<URI, URI> aliases() {
|
||||
return ImmutableMultimap.<URI, URI>builder()
|
||||
.put(URI.create(ExtensionNamespaces.SECURITY_GROUPS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/securitygroups/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.FLOATING_IPS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.KEYPAIRS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/keypairs/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.SIMPLE_TENANT_USAGE),
|
||||
URI.create("http://docs.openstack.org/compute/ext/os-simple-tenant-usage/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.HOSTS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/hosts/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.VOLUMES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.CREATESERVEREXT),
|
||||
URI.create("http://docs.openstack.org/compute/ext/createserverext/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.ADMIN_ACTIONS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/admin-actions/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.AGGREGATES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/aggregates/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.FLAVOR_EXTRA_SPECS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/flavor_extra_specs/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.QUOTAS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.QUOTA_CLASSES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.VOLUME_TYPES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/volume_types/api/v1.1"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<NovaApi> novaApi) {
|
||||
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
|
||||
.build(new CacheLoader<String, Set<? extends Extension>>() {
|
||||
|
||||
@Override
|
||||
public Set<? extends Extension> load(String key) throws Exception {
|
||||
return novaApi.get().getExtensionApiForZone(key).listExtensions();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
|
|
|
@ -32,8 +32,8 @@ import javax.ws.rs.core.MediaType;
|
|||
|
||||
import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.ServiceType;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.services.Extension;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
|
|
|
@ -1,113 +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.openstack.nova.v2_0.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.internal.ClassMethodArgsAndReturnVal;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||
import org.jclouds.openstack.nova.v2_0.predicates.ExtensionPredicates;
|
||||
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* We use the annotation {@link org.jclouds.openstack.services.Extension} to
|
||||
* bind a class that is an extension to an extension found in the
|
||||
* {@link org.jclouds.openstack.nova.v2_0.features.ExtensionApi#listExtensions} call.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Singleton
|
||||
public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet implements
|
||||
ImplicitOptionalConverter {
|
||||
private final LoadingCache<String, Set<? extends Extension>> extensions;
|
||||
|
||||
@com.google.inject.Inject(optional=true)
|
||||
@Named("openstack.nova.extensions")
|
||||
Multimap<URI, URI> aliases = ImmutableMultimap.<URI, URI>builder()
|
||||
.put(URI.create(ExtensionNamespaces.SECURITY_GROUPS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/securitygroups/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.FLOATING_IPS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/floating_ips/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.KEYPAIRS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/keypairs/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.SIMPLE_TENANT_USAGE),
|
||||
URI.create("http://docs.openstack.org/compute/ext/os-simple-tenant-usage/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.HOSTS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/hosts/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.VOLUMES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/volumes/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.VIRTUAL_INTERFACES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/virtual_interfaces/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.CREATESERVEREXT),
|
||||
URI.create("http://docs.openstack.org/compute/ext/createserverext/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.ADMIN_ACTIONS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/admin-actions/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.AGGREGATES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/aggregates/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.FLAVOR_EXTRA_SPECS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/flavor_extra_specs/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.QUOTAS),
|
||||
URI.create("http://docs.openstack.org/compute/ext/quotas-sets/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.QUOTA_CLASSES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/quota-classes-sets/api/v1.1"))
|
||||
.put(URI.create(ExtensionNamespaces.VOLUME_TYPES),
|
||||
URI.create("http://docs.openstack.org/compute/ext/volume_types/api/v1.1"))
|
||||
.build();
|
||||
|
||||
@Inject
|
||||
public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet(
|
||||
LoadingCache<String, Set<? extends Extension>> extensions) {
|
||||
this.extensions = checkNotNull(extensions, "extensions");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Object> apply(ClassMethodArgsAndReturnVal input) {
|
||||
Optional<org.jclouds.openstack.v2_0.services.Extension> ext = Optional.fromNullable(input.getClazz().getAnnotation(
|
||||
org.jclouds.openstack.v2_0.services.Extension.class));
|
||||
if (ext.isPresent()) {
|
||||
checkState(input.getArgs() != null && input.getArgs().length == 1, "expecting an arg %s", input);
|
||||
URI namespace = URI.create(ext.get().namespace());
|
||||
if (Iterables.any(extensions.getUnchecked(checkNotNull(input.getArgs()[0], "arg[0] in %s", input).toString()),
|
||||
ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace))))
|
||||
return Optional.of(input.getReturnVal());
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "presentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet()";
|
||||
}
|
||||
|
||||
}
|
|
@ -27,11 +27,11 @@ import org.jclouds.http.HttpResponseException;
|
|||
import org.jclouds.openstack.nova.v2_0.domain.BackupType;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Image;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Server.Status;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ImageApi;
|
||||
import org.jclouds.openstack.nova.v2_0.features.ServerApi;
|
||||
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
|
||||
import org.jclouds.openstack.nova.v2_0.options.CreateBackupOfServerOptions;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.testng.annotations.AfterGroups;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeGroups;
|
||||
|
|
|
@ -23,8 +23,9 @@ import static org.testng.Assert.assertTrue;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|||
import org.jclouds.json.BaseSetParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|||
import org.jclouds.json.BaseSetParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
import org.jclouds.openstack.v2_0.domain.Link.Relation;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
|
|
|
@ -27,7 +27,7 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.domain.Link;
|
||||
import org.jclouds.openstack.v2_0.domain.Link.Relation;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.jclouds.javax.annotation.Nullable;
|
|||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.functions.RegionToEndpoint;
|
||||
import org.jclouds.openstack.glance.v1_0.features.ImageApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -49,6 +50,13 @@ public interface GlanceApi {
|
|||
@Region
|
||||
Set<String> getConfiguredRegions();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionApi getExtensionApiForRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Image features.
|
||||
*/
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.jclouds.javax.annotation.Nullable;
|
|||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.functions.RegionToEndpoint;
|
||||
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -46,6 +47,13 @@ public interface GlanceAsyncApi {
|
|||
@Region
|
||||
Set<String> getConfiguredRegions();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionAsyncApi getExtensionApiForRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Image features.
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.openstack.glance.v1_0.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
|
@ -31,11 +37,20 @@ import org.jclouds.openstack.glance.v1_0.GlanceAsyncApi;
|
|||
import org.jclouds.openstack.glance.v1_0.features.ImageApi;
|
||||
import org.jclouds.openstack.glance.v1_0.features.ImageAsyncApi;
|
||||
import org.jclouds.openstack.glance.v1_0.handlers.GlanceErrorHandler;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the Glance connection.
|
||||
|
@ -46,6 +61,7 @@ import com.google.common.reflect.TypeToken;
|
|||
public class GlanceRestClientModule<S extends GlanceApi, A extends GlanceAsyncApi> extends RestClientModule<S, A> {
|
||||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||
.put(ExtensionApi.class, ExtensionAsyncApi.class)
|
||||
.put(ImageApi.class, ImageAsyncApi.class)
|
||||
.build();
|
||||
|
||||
|
@ -63,6 +79,25 @@ public class GlanceRestClientModule<S extends GlanceApi, A extends GlanceAsyncAp
|
|||
super.configure();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Multimap<URI, URI> aliases() {
|
||||
return ImmutableMultimap.<URI, URI>builder()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<GlanceApi> glanceApi) {
|
||||
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
|
||||
.build(new CacheLoader<String, Set<? extends Extension>>() {
|
||||
@Override
|
||||
public Set<? extends Extension> load(String key) throws Exception {
|
||||
return glanceApi.get().getExtensionApiForRegion(key).listExtensions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GlanceErrorHandler.class);
|
||||
|
|
|
@ -28,8 +28,10 @@ import org.jclouds.concurrent.Timeout;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.functions.RegionToEndpoint;
|
||||
import org.jclouds.location.functions.ZoneToEndpoint;
|
||||
import org.jclouds.openstack.quantum.v1_0.features.NetworkApi;
|
||||
import org.jclouds.openstack.quantum.v1_0.features.PortApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -52,6 +54,13 @@ public interface QuantumApi {
|
|||
@Region
|
||||
Set<String> getConfiguredRegions();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionApi getExtensionApiForRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Network features.
|
||||
*/
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.jclouds.location.Region;
|
|||
import org.jclouds.location.functions.RegionToEndpoint;
|
||||
import org.jclouds.openstack.quantum.v1_0.features.NetworkAsyncApi;
|
||||
import org.jclouds.openstack.quantum.v1_0.features.PortAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -50,6 +51,13 @@ public interface QuantumAsyncApi {
|
|||
@Region
|
||||
Set<String> getConfiguredRegions();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionAsyncApi getExtensionApiForRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Network features.
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.openstack.quantum.v1_0.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
|
@ -33,11 +39,20 @@ import org.jclouds.openstack.quantum.v1_0.features.NetworkAsyncApi;
|
|||
import org.jclouds.openstack.quantum.v1_0.features.PortApi;
|
||||
import org.jclouds.openstack.quantum.v1_0.features.PortAsyncApi;
|
||||
import org.jclouds.openstack.quantum.v1_0.handlers.QuantumErrorHandler;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the Quantum connection.
|
||||
|
@ -48,6 +63,7 @@ import com.google.common.reflect.TypeToken;
|
|||
public class QuantumRestClientModule<S extends QuantumApi, A extends QuantumAsyncApi> extends RestClientModule<S, A> {
|
||||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||
.put(ExtensionApi.class, ExtensionAsyncApi.class)
|
||||
.put(NetworkApi.class, NetworkAsyncApi.class)
|
||||
.put(PortApi.class, PortAsyncApi.class)
|
||||
.build();
|
||||
|
@ -66,6 +82,25 @@ public class QuantumRestClientModule<S extends QuantumApi, A extends QuantumAsyn
|
|||
super.configure();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Multimap<URI, URI> aliases() {
|
||||
return ImmutableMultimap.<URI, URI>builder()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<QuantumApi> quantumApi) {
|
||||
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
|
||||
.build(new CacheLoader<String, Set<? extends Extension>>() {
|
||||
@Override
|
||||
public Set<? extends Extension> load(String key) throws Exception {
|
||||
return quantumApi.get().getExtensionApiForRegion(key).listExtensions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(QuantumErrorHandler.class);
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.jclouds.location.functions.RegionToEndpoint;
|
|||
import org.jclouds.openstack.swift.v1.features.AccountApi;
|
||||
import org.jclouds.openstack.swift.v1.features.ContainerApi;
|
||||
import org.jclouds.openstack.swift.v1.features.ObjectApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -51,6 +52,13 @@ public interface SwiftApi {
|
|||
@Region
|
||||
Set<String> getConfiguredRegions();
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionApi getExtensionApiForRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Account features.
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.jclouds.location.functions.RegionToEndpoint;
|
|||
import org.jclouds.openstack.swift.v1.features.AccountAsyncApi;
|
||||
import org.jclouds.openstack.swift.v1.features.ContainerAsyncApi;
|
||||
import org.jclouds.openstack.swift.v1.features.ObjectAsyncApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -48,6 +49,13 @@ public interface SwiftAsyncApi {
|
|||
@Region
|
||||
Set<String> getConfiguredRegions();
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Extension features.
|
||||
*/
|
||||
@Delegate
|
||||
ExtensionAsyncApi getExtensionApiForRegion(
|
||||
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Account features.
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.openstack.swift.v1.config;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
|
@ -35,11 +41,20 @@ import org.jclouds.openstack.swift.v1.features.ContainerAsyncApi;
|
|||
import org.jclouds.openstack.swift.v1.features.ObjectApi;
|
||||
import org.jclouds.openstack.swift.v1.features.ObjectAsyncApi;
|
||||
import org.jclouds.openstack.swift.v1.handlers.SwiftErrorHandler;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionApi;
|
||||
import org.jclouds.openstack.v2_0.features.ExtensionAsyncApi;
|
||||
import org.jclouds.rest.ConfiguresRestClient;
|
||||
import org.jclouds.rest.config.RestClientModule;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
/**
|
||||
* Configures the Swift connection.
|
||||
|
@ -50,6 +65,7 @@ import com.google.common.reflect.TypeToken;
|
|||
public class SwiftRestClientModule<S extends SwiftApi, A extends SwiftAsyncApi> extends RestClientModule<S, A> {
|
||||
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
|
||||
.put(ExtensionApi.class, ExtensionAsyncApi.class)
|
||||
.put(AccountApi.class, AccountAsyncApi.class)
|
||||
.put(ContainerApi.class, ContainerAsyncApi.class)
|
||||
.put(ObjectApi.class, ObjectAsyncApi.class)
|
||||
|
@ -68,6 +84,25 @@ public class SwiftRestClientModule<S extends SwiftApi, A extends SwiftAsyncApi>
|
|||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Multimap<URI, URI> aliases() {
|
||||
return ImmutableMultimap.<URI, URI>builder()
|
||||
.build();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<SwiftApi> swiftApi) {
|
||||
return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
|
||||
.build(new CacheLoader<String, Set<? extends Extension>>() {
|
||||
@Override
|
||||
public Set<? extends Extension> load(String key) throws Exception {
|
||||
return swiftApi.get().getExtensionApiForRegion(key).listExtensions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
|
|
Loading…
Reference in New Issue