diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java index 16aab0b7b7..30d365d278 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.java @@ -25,16 +25,20 @@ 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.v1_1.domain.Extension; +import org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces; import org.jclouds.openstack.nova.v1_1.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 @@ -49,6 +53,17 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio ImplicitOptionalConverter { private final LoadingCache> extensions; + @com.google.inject.Inject(optional=true) + @Named("openstack.nova.extensions") + Multimap aliases = ImmutableMultimap.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")) + .build(); + @Inject public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet( LoadingCache> extensions) { @@ -63,7 +78,7 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio 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.namespaceEquals(namespace))) + ExtensionPredicates.namespaceOrAliasEquals(namespace, aliases.get(namespace)))) return Optional.of(input.getReturnVal()); } return Optional.absent(); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java index aac9bbfe90..74f14fae2b 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java @@ -21,6 +21,7 @@ package org.jclouds.openstack.nova.v1_1.predicates; import static com.google.common.base.Preconditions.checkNotNull; import java.net.URI; +import java.util.Collection; import org.jclouds.openstack.nova.v1_1.domain.Extension; @@ -78,5 +79,31 @@ public class ExtensionPredicates { return "aliasEquals(" + alias + ")"; } }; + } + /** + * matches namespace of the given extension + * + * @param namespace + * ex {@code http://docs.openstack.org/ext/keypairs/api/v1.1} + * @param namespacesAliases + * Collection of ex {@code http://docs.openstack.org/compute/ext/keypairs/api/v1.1} + * @return predicate that will match namespace of the given extension + */ + public static Predicate namespaceOrAliasEquals(final URI namespace, final Collection namespaceAliases) { + checkNotNull(namespace, "namespace must be defined"); + checkNotNull(namespaceAliases, "namespace aliases must be defined"); + + return new Predicate() { + @Override + public boolean apply(Extension ext) { + return namespace.toASCIIString().equals(ext.getNamespace().toASCIIString().replace("https", "http")) || + namespaceAliases.contains(ext.getNamespace()); + } + + @Override + public String toString() { + return "namespaceOrAliasEquals(" + namespace + ")"; + } + }; } } diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java index d4b973ba4f..73f1db16d0 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSetTest.java @@ -5,6 +5,8 @@ import static org.testng.Assert.assertEquals; import java.net.URI; import java.util.Set; +import javax.inject.Named; + import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.internal.ClassMethodArgsAndReturnVal; import org.jclouds.openstack.nova.v1_1.domain.Extension; @@ -23,6 +25,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Provides; /** * @author Adrian Cole @@ -93,7 +98,6 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio * of the authoritative namespace to alternate onces, which could be wired up with guice * */ - @Test(enabled = false) public void testPresentWhenAliasForExtensionMapsToNamespace() throws SecurityException, NoSuchMethodException { Extension keypairsWithDifferentNamespace = keypairs.toBuilder().namespace( URI.create("http://docs.openstack.org/ext/arbitrarilydifferent/keypairs/api/v1.1")).build(); @@ -102,29 +106,35 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio .getNamespace()); assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply( - getFloatingIPExtension()), Optional.of("foo")); + getKeyPairExtension()), Optional.of("foo")); + assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply( + getFloatingIPExtension()), Optional.absent()); } - // - private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInclude( Extension... extensions) { return whenExtensionsAndAliasesInclude(ImmutableSet.copyOf(extensions), ImmutableMultimap. of()); } private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInclude( - Set extensions, Multimap aliases) { - LoadingCache> extensionsForZone = CacheBuilder.newBuilder().build( + final Set extensions, final Multimap aliases) { + final LoadingCache> extensionsForZone = CacheBuilder.newBuilder().build( CacheLoader.from(Functions.forMap(ImmutableMap.of("expectedzone", extensions, "differentzone", ImmutableSet. of())))); - PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = new PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet( - extensionsForZone); - // TODO: change the constructor to accept aliases, or add an @Inject(optional=true) field inside the class - // PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = new - // PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet( - // extensionsForZone, aliases); + PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() {} + + @Provides + LoadingCache> getExtensions() { return extensionsForZone;} + + @Provides + @Named("openstack.nova.extensions") + Multimap getAliases() { return aliases;} + }).getInstance(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class); + return fn; } }