Repository: brooklyn-server Updated Branches: refs/heads/master e224f80b6 -> 04082527d
jcloudsLocation.imageChooser: support config as classname Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/511845f8 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/511845f8 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/511845f8 Branch: refs/heads/master Commit: 511845f81bb1bbaf69dc47912948c3d042cfa2f8 Parents: e224f80 Author: Aled Sage <aled.s...@gmail.com> Authored: Thu Apr 28 16:27:59 2016 +0100 Committer: Aled Sage <aled.s...@gmail.com> Committed: Thu Apr 28 16:27:59 2016 +0100 ---------------------------------------------------------------------- .../location/jclouds/JcloudsLocation.java | 28 ++++++++++++++++++-- .../jclouds/JcloudsLocationResolverTest.java | 25 ++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/511845f8/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java index 504d808..93a7583 100644 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java @@ -1464,6 +1464,31 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } } + /** + * If the ImageChooser is a string, then try instantiating a class with that name (in the same + * way as we do for {@link #getCloudMachineNamer(ConfigBag)}, for example). Otherwise, assume + * that convention TypeCoercions will work. + */ + @SuppressWarnings("unchecked") + protected Function<Iterable<? extends Image>, Image> getImageChooser(ComputeService computeService, ConfigBag config) { + Function<Iterable<? extends Image>, Image> chooser; + Object rawVal = config.getStringKey(JcloudsLocationConfig.IMAGE_CHOOSER.getName()); + if (rawVal instanceof String && Strings.isNonBlank((String)rawVal)) { + // Configured with a string: it could be a class that we need to instantiate + Optional<?> instance = Reflections.invokeConstructorWithArgs(getManagementContext().getCatalogClassLoader(), (String)rawVal); + if (!instance.isPresent()) { + throw new IllegalStateException("Failed to create ImageChooser "+rawVal+" for location "+this); + } else if (!(instance.get() instanceof Function)) { + throw new IllegalStateException("Failed to create ImageChooser "+rawVal+" for location "+this+"; expected type Function but got "+instance.get().getClass()); + } else { + chooser = (Function<Iterable<? extends Image>, Image>) instance.get(); + } + } else { + chooser = config.get(JcloudsLocationConfig.IMAGE_CHOOSER); + } + return BrooklynImageChooser.cloneFor(chooser, computeService, config); + } + /** returns the jclouds Template which describes the image to be built, for the given config and compute service */ public Template buildTemplate(ComputeService computeService, ConfigBag config) { TemplateBuilder templateBuilder = (TemplateBuilder) config.get(TEMPLATE_BUILDER); @@ -1475,8 +1500,7 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } if (templateBuilder instanceof PortableTemplateBuilder<?>) { if (((PortableTemplateBuilder<?>)templateBuilder).imageChooser()==null) { - Function<Iterable<? extends Image>, Image> chooser = config.get(JcloudsLocationConfig.IMAGE_CHOOSER); - chooser = BrooklynImageChooser.cloneFor(chooser, computeService, config); + Function<Iterable<? extends Image>, Image> chooser = getImageChooser(computeService, config); templateBuilder.imageChooser(chooser); } else { // an image chooser is already set, so do nothing http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/511845f8/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java index 03c7ab6..6b568de 100644 --- a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java +++ b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/JcloudsLocationResolverTest.java @@ -19,9 +19,9 @@ package org.apache.brooklyn.location.jclouds; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; -import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; @@ -36,6 +36,8 @@ import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.MutableSet; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.domain.Image; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; @@ -43,6 +45,9 @@ import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import com.google.common.base.Function; +import com.google.common.collect.Iterables; + public class JcloudsLocationResolverTest { private static final Logger log = LoggerFactory.getLogger(JcloudsLocationResolverTest.class); @@ -237,6 +242,24 @@ public class JcloudsLocationResolverTest { } @Test + public void testJcloudsImageChooserConfiguredFromBrooklynProperties() { + brooklynProperties.put("brooklyn.location.named.myloc", "jclouds:aws-ec2"); + brooklynProperties.put("brooklyn.location.named.myloc.imageChooser", JcloudsLocationResolverTest.class.getName()+"$"+MyFunction.class.getSimpleName()); + brooklynProperties.put("brooklyn.location.jclouds.openstack-nova.foo", "bar"); + JcloudsLocation loc = resolve("myloc"); + + // Test relies on the computeService not being used! Not great, but good enough. + Function<Iterable<? extends Image>, Image> chooser = loc.getImageChooser((ComputeService)null, loc.getLocalConfigBag()); + assertTrue(chooser instanceof MyFunction, "chooser="+chooser); + } + public static class MyFunction implements Function<Iterable<? extends Image>, Image> { + @Override + public Image apply(Iterable<? extends Image> input) { + return Iterables.getFirst(input, null); + } + } + + @Test public void testThrowsOnInvalid() throws Exception { // Tries to treat "wrongprefix" as a cloud provider assertThrows("wrongprefix:aws-ec2:us-east-1", NoSuchElementException.class);