mirror of https://github.com/apache/jclouds.git
Issue 978:image location ignored in templateBuilder
This commit is contained in:
parent
6eec5d5c24
commit
0ab86744cf
|
@ -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,27 +402,23 @@ 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>() {
|
||||
if (location != null)
|
||||
predicates.add(new Predicate<Hardware>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Hardware input) {
|
||||
return locationPredicate.apply(input);
|
||||
}
|
||||
@Override
|
||||
public boolean apply(Hardware input) {
|
||||
return locationPredicate.apply(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return locationPredicate.toString();
|
||||
}
|
||||
});
|
||||
if (hypervisor != null)
|
||||
predicates.add(hypervisorPredicate);
|
||||
predicates.add(hardwareCoresPredicate);
|
||||
predicates.add(hardwareRamPredicate);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return locationPredicate.toString();
|
||||
}
|
||||
});
|
||||
if (hypervisor != null)
|
||||
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);
|
||||
} else {
|
||||
throwNoSuchElementExceptionAfterLoggingImageIds(format("no image matched predicate: %s", imagePredicate),
|
||||
images);
|
||||
}
|
||||
if (image == null) {
|
||||
Iterable<? extends Image> supportedImages = findSupportedImages(images);
|
||||
if (hardware == null)
|
||||
hardware = resolveHardware(hardwaresToSearch, supportedImages);
|
||||
image = resolveImage(hardware, supportedImages);
|
||||
} else {
|
||||
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,59 +780,55 @@ 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>() {
|
||||
if (location != null)
|
||||
predicates.add(new Predicate<Image>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return locationPredicate.apply(input);
|
||||
}
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return locationPredicate.apply(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return locationPredicate.toString();
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public String toString() {
|
||||
return locationPredicate.toString();
|
||||
}
|
||||
});
|
||||
|
||||
final List<Predicate<OperatingSystem>> osPredicates = newArrayList();
|
||||
if (osFamily != null)
|
||||
osPredicates.add(osFamilyPredicate);
|
||||
if (osName != null)
|
||||
osPredicates.add(osNamePredicate);
|
||||
if (osDescription != null)
|
||||
osPredicates.add(osDescriptionPredicate);
|
||||
if (osVersion != null)
|
||||
osPredicates.add(osVersionPredicate);
|
||||
if (os64Bit != null)
|
||||
osPredicates.add(os64BitPredicate);
|
||||
if (osArch != null)
|
||||
osPredicates.add(osArchPredicate);
|
||||
if (osPredicates.size() > 0)
|
||||
predicates.add(new Predicate<Image>() {
|
||||
final List<Predicate<OperatingSystem>> osPredicates = newArrayList();
|
||||
if (osFamily != null)
|
||||
osPredicates.add(osFamilyPredicate);
|
||||
if (osName != null)
|
||||
osPredicates.add(osNamePredicate);
|
||||
if (osDescription != null)
|
||||
osPredicates.add(osDescriptionPredicate);
|
||||
if (osVersion != null)
|
||||
osPredicates.add(osVersionPredicate);
|
||||
if (os64Bit != null)
|
||||
osPredicates.add(os64BitPredicate);
|
||||
if (osArch != null)
|
||||
osPredicates.add(osArchPredicate);
|
||||
if (osPredicates.size() > 0)
|
||||
predicates.add(new Predicate<Image>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return and(osPredicates).apply(input.getOperatingSystem());
|
||||
}
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return and(osPredicates).apply(input.getOperatingSystem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return and(osPredicates).toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return and(osPredicates).toString();
|
||||
}
|
||||
|
||||
});
|
||||
if (imageVersion != null)
|
||||
predicates.add(imageVersionPredicate);
|
||||
if (imageName != null)
|
||||
predicates.add(imageNamePredicate);
|
||||
if (imageDescription != null)
|
||||
predicates.add(imageDescriptionPredicate);
|
||||
if (imagePredicate != null)
|
||||
predicates.add(imagePredicate);
|
||||
}
|
||||
});
|
||||
if (imageVersion != null)
|
||||
predicates.add(imageVersionPredicate);
|
||||
if (imageName != null)
|
||||
predicates.add(imageNamePredicate);
|
||||
if (imageDescription != null)
|
||||
predicates.add(imageDescriptionPredicate);
|
||||
if (imagePredicate != null)
|
||||
predicates.add(imagePredicate);
|
||||
|
||||
// looks verbose, but explicit <Image> type needed for this to compile
|
||||
// properly
|
||||
|
|
|
@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue