mirror of https://github.com/apache/jclouds.git
Enhance the way openstack extensions are resolved. Needed for new openstack versions.
This commit is contained in:
parent
27b3a844f8
commit
c8bbb44f37
|
@ -36,7 +36,7 @@ import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToAdminURIFromAcces
|
|||
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.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationMatchesExtensionSet;
|
||||
import org.jclouds.openstack.v2_0.services.Identity;
|
||||
import org.jclouds.rest.ConfiguresHttpApi;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
|
@ -98,7 +98,7 @@ public class KeystoneHttpApiModule extends HttpApiModule<KeystoneApi> {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
|
||||
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationMatchesExtensionSet.class);
|
||||
super.configure();
|
||||
namespaceAliasBinder(binder());
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.jclouds.openstack.v2_0.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.aliasEquals;
|
||||
import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.nameEquals;
|
||||
import static org.jclouds.openstack.v2_0.predicates.ExtensionPredicates.namespaceOrAliasEquals;
|
||||
import static org.jclouds.util.Optionals2.unwrapIfOptional;
|
||||
|
@ -42,19 +43,46 @@ import com.google.common.collect.Sets;
|
|||
/**
|
||||
* We use the annotation {@link Extension} to bind a class that implements an extension
|
||||
* API to an {@link Extension}.
|
||||
*
|
||||
* Match in the following order:
|
||||
*
|
||||
* 1. Match by namespace
|
||||
* 2. Match by namespace aliases
|
||||
* 3. Match by alias
|
||||
* 4. Match by name
|
||||
*
|
||||
* New versions of openstack have no namespaces anymore.
|
||||
* Alias is different than a namespace alias - it's an alternative namespace URL to match against.
|
||||
*/
|
||||
public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet implements
|
||||
public class PresentWhenExtensionAnnotationMatchesExtensionSet implements
|
||||
ImplicitOptionalConverter {
|
||||
private final LoadingCache<String, Set<? extends Extension>> extensions;
|
||||
private final Map<URI, Set<URI>> aliases;
|
||||
|
||||
@Inject
|
||||
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet(
|
||||
PresentWhenExtensionAnnotationMatchesExtensionSet(
|
||||
LoadingCache<String, Set<? extends Extension>> extensions, @NamespaceAliases Map<URI, Set<URI>> aliases) {
|
||||
this.extensions = extensions;
|
||||
this.aliases = aliases == null ? ImmutableMap.<URI, Set<URI>> of() : ImmutableMap.copyOf(aliases);
|
||||
}
|
||||
|
||||
private boolean checkExtension(String invocationArg, URI namespace,
|
||||
Set<URI> aliasesForNamespace, String alias, String name) {
|
||||
if (any(extensions.getUnchecked(invocationArg), namespaceOrAliasEquals(namespace, aliasesForNamespace)))
|
||||
return true;
|
||||
// Could not find extension by namespace or namespace alias. Try to find it by alias next:
|
||||
if ( !"".equals(alias)) {
|
||||
if (any(extensions.getUnchecked(invocationArg), aliasEquals(alias)))
|
||||
return true;
|
||||
}
|
||||
// Could not find extension by namespace or namespace alias or alias. Try to find it by name next:
|
||||
if ( !"".equals(name)) {
|
||||
if (any(extensions.getUnchecked(invocationArg), nameEquals(name)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Object> apply(InvocationSuccess input) {
|
||||
Class<?> target = unwrapIfOptional(input.getInvocation().getInvokable().getReturnType());
|
||||
|
@ -65,23 +93,16 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
List<Object> args = input.getInvocation().getArgs();
|
||||
Set<URI> aliasesForNamespace = aliases.containsKey(namespace) ? aliases.get(namespace) : Sets.<URI> newHashSet();
|
||||
String name = ext.get().name();
|
||||
String alias = ext.get().alias();
|
||||
|
||||
if (args.isEmpty()) {
|
||||
if (any(extensions.getUnchecked(""), namespaceOrAliasEquals(namespace, aliasesForNamespace)))
|
||||
if (checkExtension("", namespace, aliasesForNamespace, alias, name)) {
|
||||
return input.getResult();
|
||||
// Could not find extension by namespace or namespace alias. Try to find it by name next:
|
||||
if ( !"".equals(name)) {
|
||||
if (any(extensions.getUnchecked(""), nameEquals(name)))
|
||||
return input.getResult();
|
||||
}
|
||||
} else if (args.size() == 1) {
|
||||
String arg0 = checkNotNull(args.get(0), "arg[0] in %s", input).toString();
|
||||
if (any(extensions.getUnchecked(arg0), namespaceOrAliasEquals(namespace, aliasesForNamespace)))
|
||||
if (checkExtension(arg0, namespace, aliasesForNamespace, alias, name)) {
|
||||
return input.getResult();
|
||||
// Could not find extension by namespace or namespace alias. Try to find it by name next:
|
||||
if (!"".equals(name)) {
|
||||
if (any(extensions.getUnchecked(arg0), nameEquals(name)))
|
||||
return input.getResult();
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(String.format("expecting zero or one args %s", input));
|
||||
|
@ -96,7 +117,7 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "presentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet()";
|
||||
return "PresentWhenExtensionAnnotationMatchesExtensionSet()";
|
||||
}
|
||||
|
||||
}
|
|
@ -65,24 +65,16 @@ 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 = "http://docs.openstack.org/ext/floating_ips/api/v1.1")
|
||||
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, name = "Floating_ips", alias = "os-floating-ips", namespace = "http://docs.openstack.org/ext/floating_ips/api/v1.1")
|
||||
interface FloatingIPApi {
|
||||
|
||||
}
|
||||
|
||||
@org.jclouds.openstack.v2_0.services.Extension(of = ServiceType.COMPUTE, name = "Floating_ips", namespace = "http://docs.openstack.org/fake")
|
||||
interface FloatingIPNamedApi {
|
||||
|
||||
}
|
||||
|
||||
interface NovaApi {
|
||||
|
||||
@Delegate
|
||||
Optional<FloatingIPApi> getFloatingIPExtensionApi(String region);
|
||||
|
||||
@Delegate
|
||||
Optional<FloatingIPNamedApi> getFloatingIPNamedExtensionApi(String region);
|
||||
|
||||
@Delegate
|
||||
Optional<KeyPairApi> getKeyPairExtensionApi(String region);
|
||||
|
||||
|
@ -93,11 +85,6 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
Invocation.create(method(NovaApi.class, "getFloatingIPExtensionApi", String.class), args), "foo");
|
||||
}
|
||||
|
||||
InvocationSuccess getFloatingIPNamedExtension(List<Object> args) throws SecurityException, NoSuchMethodException {
|
||||
return InvocationSuccess.create(
|
||||
Invocation.create(method(NovaApi.class, "getFloatingIPNamedExtensionApi", String.class), args), "foo");
|
||||
}
|
||||
|
||||
InvocationSuccess getKeyPairExtension(List<Object> args) throws SecurityException, NoSuchMethodException {
|
||||
return InvocationSuccess.create(
|
||||
Invocation.create(method(NovaApi.class, "getKeyPairExtensionApi", String.class), args), "foo");
|
||||
|
@ -144,28 +131,38 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
*
|
||||
*/
|
||||
public void testPresentWhenNameSpaceIsMissingAndMatchByNameOrAlias() throws SecurityException, NoSuchMethodException {
|
||||
Extension floatingIpsWithFakeNamespace = floatingIps.toBuilder()
|
||||
// Revert to alias
|
||||
Extension floatingIpsWithMissingNamespace = floatingIps.toBuilder()
|
||||
.namespace(URI.create("http://docs.openstack.org/ext/fake"))
|
||||
.build();
|
||||
|
||||
// Revert to name
|
||||
Extension floatingIpsWithMissingNamespaceAndAlias = floatingIps.toBuilder()
|
||||
.namespace(URI.create("http://docs.openstack.org/ext/fake"))
|
||||
.alias("fake")
|
||||
.build();
|
||||
|
||||
Multimap<URI, URI> aliases = ImmutableMultimap.of();
|
||||
|
||||
assertEquals(whenExtensionsAndAliasesInRegionInclude("region", ImmutableSet.of(floatingIpsWithFakeNamespace), aliases).apply(
|
||||
getFloatingIPNamedExtension(ImmutableList.<Object> of("region"))), Optional.of("foo"));
|
||||
assertEquals(whenExtensionsAndAliasesInRegionInclude("region", ImmutableSet.of(floatingIpsWithMissingNamespace), aliases).apply(
|
||||
getFloatingIPExtension(ImmutableList.<Object> of("region"))), Optional.of("foo"));
|
||||
|
||||
assertEquals(whenExtensionsAndAliasesInRegionInclude("region", ImmutableSet.of(floatingIpsWithMissingNamespaceAndAlias), aliases).apply(
|
||||
getFloatingIPExtension(ImmutableList.<Object> of("region"))), Optional.of("foo"));
|
||||
}
|
||||
|
||||
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInRegionInclude(
|
||||
private PresentWhenExtensionAnnotationMatchesExtensionSet whenExtensionsInRegionInclude(
|
||||
String region, Extension... extensions) {
|
||||
return whenExtensionsAndAliasesInRegionInclude(region, ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of());
|
||||
}
|
||||
|
||||
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInRegionInclude(
|
||||
private PresentWhenExtensionAnnotationMatchesExtensionSet whenExtensionsAndAliasesInRegionInclude(
|
||||
String region, final Set<Extension> extensions, final Multimap<URI, URI> aliases) {
|
||||
final LoadingCache<String, Set<? extends Extension>> extensionsForRegion = CacheBuilder.newBuilder().build(
|
||||
CacheLoader.from(Functions.forMap(ImmutableMap.<String, Set<? extends Extension>>of(region, extensions, "differentregion",
|
||||
ImmutableSet.<Extension> of()))));
|
||||
|
||||
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector(
|
||||
PresentWhenExtensionAnnotationMatchesExtensionSet fn = Guice.createInjector(
|
||||
new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
@ -183,7 +180,7 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
|
|||
return extensionsForRegion;
|
||||
}
|
||||
|
||||
}).getInstance(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
|
||||
}).getInstance(PresentWhenExtensionAnnotationMatchesExtensionSet.class);
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.jclouds.openstack.nova.v2_0.NovaApi;
|
|||
import org.jclouds.openstack.nova.v2_0.extensions.ExtensionNamespaces;
|
||||
import org.jclouds.openstack.nova.v2_0.handlers.NovaErrorHandler;
|
||||
import org.jclouds.openstack.v2_0.domain.Extension;
|
||||
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
|
||||
import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationMatchesExtensionSet;
|
||||
import org.jclouds.rest.ConfiguresHttpApi;
|
||||
import org.jclouds.rest.config.HttpApiModule;
|
||||
import org.jclouds.rest.functions.ImplicitOptionalConverter;
|
||||
|
@ -54,7 +54,7 @@ public class NovaHttpApiModule extends HttpApiModule<NovaApi> {
|
|||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
|
||||
bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationMatchesExtensionSet.class);
|
||||
super.configure();
|
||||
bindDefaultAliases();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue