Merge pull request #546 from dhogan/extensions-alias

add aliases for extension namespaces
This commit is contained in:
Adrian Cole 2012-04-09 09:54:45 -07:00
commit 049688efcd
3 changed files with 65 additions and 13 deletions

View File

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

View File

@ -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<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.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.<URI, URI> of());
}
private PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet whenExtensionsAndAliasesInclude(
Set<Extension> extensions, Multimap<URI, URI> aliases) {
LoadingCache<String, Set<Extension>> extensionsForZone = CacheBuilder.newBuilder().build(
final Set<Extension> extensions, final Multimap<URI, URI> aliases) {
final LoadingCache<String, Set<Extension>> extensionsForZone = CacheBuilder.newBuilder().build(
CacheLoader.from(Functions.forMap(ImmutableMap.of("expectedzone", extensions, "differentzone",
ImmutableSet.<Extension> 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<String, Set<Extension>> getExtensions() { return extensionsForZone;}
@Provides
@Named("openstack.nova.extensions")
Multimap<URI, URI> getAliases() { return aliases;}
}).getInstance(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
return fn;
}
}