add aliases for extension namespaces

This commit is contained in:
Dirk Hogan 2012-04-09 08:44:22 -07:00
parent 03028338df
commit 411b14eddc
3 changed files with 65 additions and 13 deletions

View File

@ -25,16 +25,20 @@ import java.net.URI;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.internal.ClassMethodArgsAndReturnVal; import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.openstack.nova.v1_1.domain.Extension; 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.openstack.nova.v1_1.predicates.ExtensionPredicates;
import org.jclouds.rest.functions.ImplicitOptionalConverter; import org.jclouds.rest.functions.ImplicitOptionalConverter;
import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
/** /**
* We use the annotation {@link org.jclouds.openstack.services.Extension} to * We use the annotation {@link org.jclouds.openstack.services.Extension} to
@ -49,6 +53,17 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
ImplicitOptionalConverter { ImplicitOptionalConverter {
private final LoadingCache<String, Set<Extension>> extensions; private final LoadingCache<String, Set<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"))
.build();
@Inject @Inject
public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet( public PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet(
LoadingCache<String, Set<Extension>> extensions) { LoadingCache<String, Set<Extension>> extensions) {
@ -63,7 +78,7 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
checkState(input.getArgs() != null && input.getArgs().length == 1, "expecting an arg %s", input); checkState(input.getArgs() != null && input.getArgs().length == 1, "expecting an arg %s", input);
URI namespace = URI.create(ext.get().namespace()); URI namespace = URI.create(ext.get().namespace());
if (Iterables.any(extensions.getUnchecked(checkNotNull(input.getArgs()[0], "arg[0] in %s", input).toString()), 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.of(input.getReturnVal());
} }
return Optional.absent(); return Optional.absent();

View File

@ -21,6 +21,7 @@ package org.jclouds.openstack.nova.v1_1.predicates;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI; import java.net.URI;
import java.util.Collection;
import org.jclouds.openstack.nova.v1_1.domain.Extension; import org.jclouds.openstack.nova.v1_1.domain.Extension;
@ -79,4 +80,30 @@ public class ExtensionPredicates {
} }
}; };
} }
/**
* 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<Extension> namespaceOrAliasEquals(final URI namespace, final Collection<URI> namespaceAliases) {
checkNotNull(namespace, "namespace must be defined");
checkNotNull(namespaceAliases, "namespace aliases must be defined");
return new Predicate<Extension>() {
@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 + ")";
}
};
}
} }

View File

@ -5,6 +5,8 @@ import static org.testng.Assert.assertEquals;
import java.net.URI; import java.net.URI;
import java.util.Set; import java.util.Set;
import javax.inject.Named;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.internal.ClassMethodArgsAndReturnVal; import org.jclouds.internal.ClassMethodArgsAndReturnVal;
import org.jclouds.openstack.nova.v1_1.domain.Extension; 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.ImmutableMultimap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Provides;
/** /**
* @author Adrian Cole * @author Adrian Cole
@ -93,7 +98,6 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
* of the authoritative namespace to alternate onces, which could be wired up with guice * of the authoritative namespace to alternate onces, which could be wired up with guice
* *
*/ */
@Test(enabled = false)
public void testPresentWhenAliasForExtensionMapsToNamespace() throws SecurityException, NoSuchMethodException { public void testPresentWhenAliasForExtensionMapsToNamespace() throws SecurityException, NoSuchMethodException {
Extension keypairsWithDifferentNamespace = keypairs.toBuilder().namespace( Extension keypairsWithDifferentNamespace = keypairs.toBuilder().namespace(
URI.create("http://docs.openstack.org/ext/arbitrarilydifferent/keypairs/api/v1.1")).build(); URI.create("http://docs.openstack.org/ext/arbitrarilydifferent/keypairs/api/v1.1")).build();
@ -102,29 +106,35 @@ public class PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensio
.getNamespace()); .getNamespace());
assertEquals(whenExtensionsAndAliasesInclude(ImmutableSet.of(keypairsWithDifferentNamespace), aliases).apply( 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( private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsInclude(
Extension... extensions) { Extension... extensions) {
return whenExtensionsAndAliasesInclude(ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of()); return whenExtensionsAndAliasesInclude(ImmutableSet.copyOf(extensions), ImmutableMultimap.<URI, URI> of());
} }
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInclude( private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInclude(
Set<Extension> extensions, Multimap<URI, URI> aliases) { final Set<Extension> extensions, final Multimap<URI, URI> aliases) {
LoadingCache<String, Set<Extension>> extensionsForZone = CacheBuilder.newBuilder().build( final LoadingCache<String, Set<Extension>> extensionsForZone = CacheBuilder.newBuilder().build(
CacheLoader.from(Functions.forMap(ImmutableMap.of("expectedzone", extensions, "differentzone", CacheLoader.from(Functions.forMap(ImmutableMap.of("expectedzone", extensions, "differentzone",
ImmutableSet.<Extension> of())))); ImmutableSet.<Extension> of()))));
PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = new PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet( PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = Guice.createInjector(new AbstractModule() {
extensionsForZone); @Override
// TODO: change the constructor to accept aliases, or add an @Inject(optional=true) field inside the class protected void configure() {}
// PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet fn = new
// PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet( @Provides
// extensionsForZone, aliases); LoadingCache<String, Set<Extension>> getExtensions() { return extensionsForZone;}
@Provides
@Named("openstack.nova.extensions")
Multimap<URI, URI> getAliases() { return aliases;}
}).getInstance(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
return fn; return fn;
} }
} }