Issue 978:image location ignored in templateBuilder

This commit is contained in:
Adrian Cole 2012-06-15 20:45:38 -04:00
parent 6eec5d5c24
commit 0ab86744cf
2 changed files with 180 additions and 91 deletions

View File

@ -24,6 +24,7 @@ import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.size;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Iterables.tryFind;
import static com.google.common.collect.Lists.newArrayList;
import static java.lang.String.format;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
@ -401,9 +402,6 @@ public class TemplateBuilderImpl implements TemplateBuilder {
private Predicate<Hardware> buildHardwarePredicate() {
List<Predicate<Hardware>> predicates = newArrayList();
if (hardwareId != null) {
predicates.add(hardwareIdPredicate);
} else {
if (location != null)
predicates.add(new Predicate<Hardware>() {
@ -421,7 +419,6 @@ public class TemplateBuilderImpl implements TemplateBuilder {
predicates.add(hypervisorPredicate);
predicates.add(hardwareCoresPredicate);
predicates.add(hardwareRamPredicate);
}
// looks verbose, but explicit <Hardware> type needed for this to compile
// properly
@ -610,35 +607,87 @@ public class TemplateBuilderImpl implements TemplateBuilder {
options = optionsProvider.get();
logger.debug(">> searching params(%s)", this);
Set<? extends Image> images = getImages();
Set<? extends Hardware> hardwaresToSearch = hardwares.get();
Image image = null;
if (imageId != null) {
image = findImageWithId(images);
if (currentLocationWiderThan(image.getLocation()))
this.location = image.getLocation();
}
Hardware hardware = null;
if (hardwareId != null) {
hardware = findHardwareWithId(hardwaresToSearch);
if (currentLocationWiderThan(hardware.getLocation()))
this.location = hardware.getLocation();
}
// if the user hasn't specified a location id, or an image or hardware
// with location, let's search scoped to the implicit one
if (location == null)
location = defaultLocation.get();
Predicate<Image> imagePredicate = buildImagePredicate();
Iterable<? extends Image> supportedImages = filter(images, imagePredicate);
if (size(supportedImages) == 0) {
if (imagePredicate == idPredicate) {
throwNoSuchElementExceptionAfterLoggingImageIds(format("%s not found", idPredicate), images);
if (image == null) {
Iterable<? extends Image> supportedImages = findSupportedImages(images);
if (hardware == null)
hardware = resolveHardware(hardwaresToSearch, supportedImages);
image = resolveImage(hardware, supportedImages);
} else {
throwNoSuchElementExceptionAfterLoggingImageIds(format("no image matched predicate: %s", imagePredicate),
images);
}
if (hardware == null)
hardware = resolveHardware(hardwaresToSearch, ImmutableSet.of(image));
}
Hardware hardware = resolveHardware(hardwareSorter(), supportedImages);
Image image = resolveImage(hardware, supportedImages);
logger.debug("<< matched image(%s)", image.getId());
logger.debug("<< matched image(%s) hardware(%s) location(%s)", image.getId(), hardware.getId(),
location.getId());
return new TemplateImpl(image, hardware, location, options);
}
protected void throwNoSuchElementExceptionAfterLoggingImageIds(String message, Iterable<? extends Image> images) {
private Iterable<? extends Image> findSupportedImages(Set<? extends Image> images) {
Predicate<Image> imagePredicate = buildImagePredicate();
Iterable<? extends Image> supportedImages = filter(images, imagePredicate);
if (size(supportedImages) == 0) {
throw throwNoSuchElementExceptionAfterLoggingImageIds(
format("no image matched predicate: %s", imagePredicate), images);
}
return supportedImages;
}
private Image findImageWithId(Set<? extends Image> images) {
Image image;
// TODO: switch to GetImageStrategy in version 1.5
image = tryFind(images, idPredicate).orNull();
if (image == null)
throwNoSuchElementExceptionAfterLoggingImageIds(format("%s not found", idPredicate), images);
return image;
}
private Hardware findHardwareWithId(Set<? extends Hardware> hardwaresToSearch) {
Hardware hardware;
// TODO: switch to GetHardwareStrategy in version 1.5
hardware = tryFind(hardwaresToSearch, hardwareIdPredicate).orNull();
if (hardware == null)
throw throwNoSuchElementExceptionAfterLoggingHardwareIds(format("%s not found", hardwareIdPredicate),
hardwaresToSearch);
return hardware;
}
protected NoSuchElementException throwNoSuchElementExceptionAfterLoggingImageIds(String message, Iterable<? extends Image> images) {
NoSuchElementException exception = new NoSuchElementException(message);
if (logger.isTraceEnabled())
logger.warn(exception, "image ids that didn't match: %s", transform(images, imageToId));
throw exception;
}
protected Hardware resolveHardware(Ordering<Hardware> hardwareOrdering, final Iterable<? extends Image> images) {
Set<? extends Hardware> hardwarel = hardwares.get();
protected NoSuchElementException throwNoSuchElementExceptionAfterLoggingHardwareIds(String message, Iterable<? extends Hardware> hardwares) {
NoSuchElementException exception = new NoSuchElementException(message);
if (logger.isTraceEnabled())
logger.warn(exception, "hardware ids that didn't match: %s", transform(hardwares, hardwareToId));
throw exception;
}
protected Hardware resolveHardware(Set<? extends Hardware> hardwarel, final Iterable<? extends Image> images) {
Ordering<Hardware> hardwareOrdering = hardwareSorter();
Iterable<? extends Hardware> hardwaresThatAreCompatibleWithOurImages = ImmutableSet.of();
try {
hardwaresThatAreCompatibleWithOurImages = filter(hardwarel, new Predicate<Hardware>() {
@ -665,11 +714,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
}
if (size(hardwaresThatAreCompatibleWithOurImages) == 0) {
String message = format("no hardware profiles support images matching params: %s", toString());
NoSuchElementException exception = new NoSuchElementException(message);
if (logger.isTraceEnabled())
logger.warn(exception, "hardware profiles %s\nimage ids %s", transform(hardwarel, hardwareToId), transform(
images, imageToId));
throw exception;
throw throwNoSuchElementExceptionAfterLoggingHardwareIds(message, hardwaresThatAreCompatibleWithOurImages);
}
Predicate<Hardware> hardwarePredicate = buildHardwarePredicate();
Hardware hardware;
@ -677,11 +722,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
hardware = hardwareOrdering.max(filter(hardwaresThatAreCompatibleWithOurImages, hardwarePredicate));
} catch (NoSuchElementException exception) {
String message = format("no hardware profiles match params: %s", hardwarePredicate);
exception = new NoSuchElementException(message);
if (logger.isTraceEnabled())
logger.warn(exception, "hardware profiles %s", transform(hardwaresThatAreCompatibleWithOurImages,
hardwareToId));
throw exception;
throw throwNoSuchElementExceptionAfterLoggingHardwareIds(message, hardwaresThatAreCompatibleWithOurImages);
}
logger.debug("<< matched hardware(%s)", hardware.getId());
return hardware;
@ -739,9 +780,6 @@ public class TemplateBuilderImpl implements TemplateBuilder {
private Predicate<Image> buildImagePredicate() {
List<Predicate<Image>> predicates = newArrayList();
if (imageId != null) {
predicates.add(idPredicate);
} else {
if (location != null)
predicates.add(new Predicate<Image>() {
@ -791,7 +829,6 @@ public class TemplateBuilderImpl implements TemplateBuilder {
predicates.add(imageDescriptionPredicate);
if (imagePredicate != null)
predicates.add(imagePredicate);
}
// looks verbose, but explicit <Image> type needed for this to compile
// properly

View File

@ -62,6 +62,9 @@ public class TemplateBuilderImplTest {
protected Location region = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1").description("us-east-1")
.parent(provider).build();
protected Location region2 = new LocationBuilder().scope(LocationScope.REGION).id("us-east-2").description("us-east-2")
.parent(provider).build();
@SuppressWarnings("unchecked")
public void testLocationPredicateWhenComputeMetadataIsNotLocationBound() {
Image image = createMock(Image.class);
@ -851,4 +854,53 @@ public class TemplateBuilderImplTest {
assertEquals(template.getImage().getId(), "Ubuntu 11.04 64-bit");
}
@Test
public void testImageLocationNonDefault() {
final Supplier<Set<? extends Location>> locations = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(region));
final Supplier<Set<? extends Image>> images = Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet
.<Image> of(
new ImageBuilder()
.id("us-east-2/ami-ffff")
.providerId("ami-ffff")
.name("Ubuntu 11.04 x64")
.description("Ubuntu 11.04 x64")
.location(region2)
.operatingSystem(
OperatingSystem.builder().name("Ubuntu 11.04 x64").description("Ubuntu 11.04 x64")
.is64Bit(true).version("11.04").family(OsFamily.UBUNTU).build()).build()));
final Supplier<Set<? extends Hardware>> hardwares = Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet
.<Hardware> of(
new HardwareBuilder()
.ids("m1.small").ram(512)
.processors(ImmutableList.of(new Processor(1, 1.0)))
.volumes(ImmutableList.<Volume> of(new VolumeImpl((float) 5, true, true))).build()));
final Provider<TemplateOptions> optionsProvider = new Provider<TemplateOptions>() {
@Override
public TemplateOptions get() {
return new TemplateOptions();
}
};
Provider<TemplateBuilder> templateBuilderProvider = new Provider<TemplateBuilder>() {
@Override
public TemplateBuilder get() {
return createTemplateBuilder(null, locations, images, hardwares, region, optionsProvider, this);
}
};
TemplateBuilder templateBuilder = templateBuilderProvider.get().hardwareId("m1.small").imageId("us-east-2/ami-ffff");
Template template = templateBuilder.build();
assertEquals(template.getLocation().getId(), "us-east-2");
}
}