org.jclouds.compute.domain.internal.TemplateBuilderImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jclouds-compute Show documentation
Show all versions of jclouds-compute Show documentation
jclouds components to access compute providers
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.compute.domain.internal;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Doubles;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.domain.TemplateBuilderSpec;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.suppliers.ImageCacheSupplier;
import org.jclouds.domain.Location;
import org.jclouds.logging.Logger;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Pattern;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
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;
import static org.jclouds.compute.util.ComputeServiceUtils.getCoresAndSpeed;
import static org.jclouds.compute.util.ComputeServiceUtils.getSpace;
public class TemplateBuilderImpl implements TemplateBuilder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
protected final ImageCacheSupplier images;
protected final Supplier> hardwares;
protected final Supplier> locations;
protected final Supplier defaultLocation;
protected final Provider optionsProvider;
protected final Provider defaultTemplateProvider;
@VisibleForTesting
protected Location location;
@VisibleForTesting
protected String imageId;
@VisibleForTesting
protected String hardwareId;
@VisibleForTesting
protected String hypervisor;
@VisibleForTesting
protected String imageVersion;
@VisibleForTesting
protected OsFamily osFamily;
@VisibleForTesting
protected String osVersion;
@VisibleForTesting
protected Boolean os64Bit;
@VisibleForTesting
protected String osName;
@VisibleForTesting
protected String osDescription;
@VisibleForTesting
protected String osArch;
@VisibleForTesting
protected String imageName;
@VisibleForTesting
protected String imageDescription;
@VisibleForTesting
protected Predicate imagePredicate;
@VisibleForTesting
protected Function, Image> imageChooser;
@VisibleForTesting
protected double minCores;
@VisibleForTesting
protected int minRam;
@VisibleForTesting
protected double minDisk;
@VisibleForTesting
protected boolean biggest;
@VisibleForTesting
protected boolean fastest;
@VisibleForTesting
protected TemplateOptions options;
@VisibleForTesting
protected Boolean forceCacheReload;
@Inject
protected TemplateBuilderImpl(@Memoized Supplier> locations,
@Memoized Supplier> images, @Memoized Supplier> hardwares,
Supplier defaultLocation, @Named("DEFAULT") Provider optionsProvider,
@Named("DEFAULT") Provider defaultTemplateProvider) {
this.locations = checkNotNull(locations, "locations");
checkArgument(images instanceof ImageCacheSupplier, "an instance of the ImageCacheSupplier is needed");
this.images = ImageCacheSupplier.class.cast(images);
this.hardwares = checkNotNull(hardwares, "hardwares");
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
this.optionsProvider = checkNotNull(optionsProvider, "optionsProvider");
this.defaultTemplateProvider = checkNotNull(defaultTemplateProvider, "defaultTemplateProvider");
}
static Predicate supportsImagesPredicate(final Iterable extends Image> images) {
return new Predicate() {
@Override
public boolean apply(final Hardware hardware) {
return Iterables.any(images, new Predicate() {
@Override
public boolean apply(Image input) {
return hardware.supportsImage().apply(input);
}
@Override
public String toString() {
return "hardware(" + hardware + ").supportsImage()";
}
});
}
};
}
final Predicate locationPredicate = new NullEqualToIsParentOrIsGrandparentOfCurrentLocation(new Supplier() {
@Override
public Location get() {
return location;
}
});
private final Predicate osFamilyPredicate = new Predicate() {
@Override
public boolean apply(OperatingSystem input) {
boolean returnVal = true;
if (osFamily != null)
returnVal = osFamily.equals(input.getFamily());
return returnVal;
}
@Override
public String toString() {
return "osFamily(" + osFamily + ")";
}
};
private final Predicate osNamePredicate = new Predicate() {
@Override
public boolean apply(OperatingSystem input) {
boolean returnVal = true;
if (osName != null) {
if (input.getName() == null)
returnVal = false;
else
returnVal = input.getName().contains(osName) || input.getName().matches(osName);
}
return returnVal;
}
@Override
public String toString() {
return "osName(" + osName + ")";
}
};
private final Predicate osDescriptionPredicate = new Predicate() {
@Override
public boolean apply(OperatingSystem input) {
boolean returnVal = true;
if (osDescription != null) {
if (input.getDescription() == null)
returnVal = false;
else
returnVal = input.getDescription().contains(osDescription)
|| input.getDescription().matches(osDescription);
}
return returnVal;
}
@Override
public String toString() {
return "osDescription(" + osDescription + ")";
}
};
private final Predicate osVersionPredicate = new Predicate() {
@Override
public boolean apply(OperatingSystem input) {
boolean returnVal = true;
if (osVersion != null) {
if (input.getVersion() == null)
returnVal = false;
else
returnVal = input.getVersion().contains(osVersion) || input.getVersion().matches(osVersion);
}
return returnVal;
}
@Override
public String toString() {
return "osVersion(" + osVersion + ")";
}
};
private final Predicate os64BitPredicate = new Predicate() {
@Override
public boolean apply(OperatingSystem input) {
boolean returnVal = true;
if (os64Bit != null) {
if (os64Bit)
return input.is64Bit();
else
return !input.is64Bit();
}
return returnVal;
}
@Override
public String toString() {
return "os64Bit(" + os64Bit + ")";
}
};
private final Predicate osArchPredicate = new Predicate() {
@Override
public boolean apply(OperatingSystem input) {
boolean returnVal = true;
if (osArch != null) {
if (input.getArch() == null)
returnVal = false;
else
returnVal = input.getArch().contains(osArch) || input.getArch().matches(osArch);
}
return returnVal;
}
@Override
public String toString() {
return "osArch(" + osArch + ")";
}
};
private final Predicate imageVersionPredicate = new Predicate() {
@Override
public boolean apply(Image input) {
boolean returnVal = true;
if (imageVersion != null) {
if (input.getVersion() == null)
returnVal = false;
else
returnVal = input.getVersion().contains(imageVersion) || input.getVersion().matches(imageVersion);
}
return returnVal;
}
@Override
public String toString() {
return "imageVersion(" + imageVersion + ")";
}
};
private final Predicate imageNamePredicate = new Predicate() {
@Override
public boolean apply(Image input) {
boolean returnVal = true;
if (imageName != null) {
if (input.getName() == null)
returnVal = false;
else
returnVal = input.getName().equals(imageName) || input.getName().contains(imageName)
|| input.getName().matches(imageName);
}
return returnVal;
}
@Override
public String toString() {
return "imageName(" + imageName + ")";
}
};
private final Predicate imageDescriptionPredicate = new Predicate() {
@Override
public boolean apply(Image input) {
boolean returnVal = true;
if (imageDescription != null) {
if (input.getDescription() == null)
returnVal = false;
else
returnVal = input.getDescription().equals(imageDescription)
|| input.getDescription().contains(imageDescription)
|| input.getDescription().matches(imageDescription);
}
return returnVal;
}
@Override
public String toString() {
return "imageDescription(" + imageDescription + ")";
}
};
private final Predicate hardwareIdPredicate = new Predicate() {
@Override
public boolean apply(Hardware input) {
boolean returnVal = true;
if (hardwareId != null) {
returnVal = hardwareId.equals(input.getId());
// match our input params so that the later predicates pass.
if (returnVal) {
fromHardware(input);
}
}
return returnVal;
}
@Override
public String toString() {
return "hardwareId(" + hardwareId + ")";
}
};
private final Predicate hypervisorPredicate = new Predicate() {
@Override
public boolean apply(Hardware input) {
boolean returnVal = true;
if (hypervisor != null) {
if (input.getHypervisor() == null)
returnVal = false;
else
returnVal = input.getHypervisor().contains(hypervisor)
|| input.getHypervisor().matches(hypervisor);
}
return returnVal;
}
@Override
public String toString() {
return "hypervisorMatches(" + hypervisor + ")";
}
};
private final Predicate hardwareCoresPredicate = new Predicate() {
@Override
public boolean apply(Hardware input) {
double cores = getCores(input);
return cores >= TemplateBuilderImpl.this.minCores;
}
@Override
public String toString() {
return "minCores(" + minCores + ")";
}
};
private final Predicate hardwareDiskPredicate = new Predicate() {
@Override
public boolean apply(Hardware input) {
return getSpace(input) >= TemplateBuilderImpl.this.minDisk;
}
@Override
public String toString() {
return "minDisk(" + minDisk + ")";
}
};
private final Predicate hardwareRamPredicate = new Predicate() {
@Override
public boolean apply(Hardware input) {
return input.getRam() >= TemplateBuilderImpl.this.minRam;
}
@Override
public String toString() {
return "minRam(" + minRam + ")";
}
};
private Predicate buildHardwarePredicate() {
List> predicates = newArrayList();
if (location != null)
predicates.add(new Predicate() {
@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);
predicates.add(hardwareDiskPredicate);
// looks verbose, but explicit type needed for this to compile
// properly
Predicate hardwarePredicate = predicates.size() == 1 ? Iterables.> get(predicates, 0)
: Predicates. and(predicates);
return hardwarePredicate;
}
static final Ordering DEFAULT_SIZE_ORDERING = new Ordering() {
public int compare(Hardware left, Hardware right) {
return ComparisonChain.start().compare(getCores(left), getCores(right)).compare(left.getRam(), right.getRam())
.compare(getSpace(left), getSpace(right)).result();
}
};
static final Ordering BY_CORES_ORDERING = new Ordering() {
public int compare(Hardware left, Hardware right) {
return Doubles.compare(getCoresAndSpeed(left), getCoresAndSpeed(right));
}
};
static final Ordering NOT_DEPRECATED_ORDERING = new Ordering() {
public int compare(Hardware left, Hardware right) {
// we take max so deprecated items come first
return ComparisonChain.start().compareTrueFirst(left.isDeprecated(), right.isDeprecated()).result();
}
};
static final Ordering DEFAULT_IMAGE_ORDERING = new Ordering() {
public int compare(Image left, Image right) {
/* This currently, and for some time, has *preferred* images whose fields are null,
* and prefers those which come last alphabetically.
* It seems preferable to take images whose fields are *not* null, ie nullsFirst;
* and to use something like the AlphaNum Algorithm then take the last
* (so "Ubuntu 13.04" would be preferred over "Ubuntu 9.10").
* However not changing it now as people may be surprised if the images they get back start changing.
*/
return ComparisonChain.start()
.compare(left.getName(), right.getName(), Ordering. natural().nullsLast())
.compare(left.getVersion(), right.getVersion(), Ordering. natural().nullsLast())
.compare(left.getDescription(), right.getDescription(), Ordering. natural().nullsLast())
.compare(left.getOperatingSystem().getName(), right.getOperatingSystem().getName(),
Ordering. natural().nullsLast())
.compare(left.getOperatingSystem().getVersion(), right.getOperatingSystem().getVersion(),
Ordering. natural().nullsLast())
.compare(left.getOperatingSystem().getDescription(), right.getOperatingSystem().getDescription(),
Ordering. natural().nullsLast())
.compare(left.getOperatingSystem().getArch(), right.getOperatingSystem().getArch(),
Ordering. natural().nullsLast()).result();
}
};
@VisibleForTesting
// non-static for logging
final Function, Image> imageChooserFromOrdering(final Ordering ordering) {
return new Function, Image>() {
@Override
public Image apply(Iterable extends Image> input) {
List extends Image> maxImages = multiMax(ordering, input);
if (logger.isTraceEnabled())
logger.trace("<< best images(%s)", transform(maxImages, imageToId));
return maxImages.get(maxImages.size() - 1);
}
};
}
@VisibleForTesting
Function, Image> defaultImageChooser() {
return imageChooserFromOrdering(DEFAULT_IMAGE_ORDERING);
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder fromTemplate(Template template) {
location = template.getLocation();
fromHardware(template.getHardware());
fromImage(template.getImage());
options(template.getOptions());
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder fromHardware(Hardware hardware) {
if (currentLocationWiderThan(hardware.getLocation()))
this.location = hardware.getLocation();
this.minCores = getCores(hardware);
this.minRam = hardware.getRam();
this.minDisk = getSpace(hardware);
this.hypervisor = hardware.getHypervisor();
return this;
}
private boolean currentLocationWiderThan(Location location) {
return this.location == null || (location != null && this.location.getScope().compareTo(location.getScope()) < 0);
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder fromImage(Image image) {
if (currentLocationWiderThan(image.getLocation()))
this.location = image.getLocation();
if (image.getOperatingSystem().getFamily() != null)
this.osFamily = image.getOperatingSystem().getFamily();
if (image.getName() != null)
this.imageName = image.getName();
if (image.getDescription() != null)
this.imageDescription = String.format("^%s$", Pattern.quote(image.getDescription()));
if (image.getOperatingSystem().getName() != null)
this.osName = image.getOperatingSystem().getName();
if (image.getOperatingSystem().getDescription() != null)
this.osDescription = image.getOperatingSystem().getDescription();
if (image.getVersion() != null)
this.imageVersion = String.format("^%s$", Pattern.quote(image.getVersion()));
if (image.getOperatingSystem().getVersion() != null)
this.osVersion = image.getOperatingSystem().getVersion();
this.os64Bit = image.getOperatingSystem().is64Bit();
if (image.getOperatingSystem().getArch() != null)
this.osArch = image.getOperatingSystem().getArch();
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder smallest() {
this.biggest = false;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder biggest() {
this.biggest = true;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder fastest() {
this.fastest = true;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder locationId(final String locationId) {
Set extends Location> locations = this.locations.get();
try {
this.location = find(locations, new Predicate() {
@Override
public boolean apply(Location input) {
return input.getId().equals(locationId);
}
@Override
public String toString() {
return "locationId(" + locationId + ")";
}
});
} catch (NoSuchElementException e) {
throw new NoSuchElementException(format("location id %s not found in: %s", locationId, locations));
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder osFamily(OsFamily os) {
this.osFamily = os;
return this;
}
private static final Function imageToId = new Function() {
@Override
public String apply(Image arg0) {
return arg0.getId();
}
};
private static final Function hardwareToId = new Function() {
@Override
public String apply(Hardware arg0) {
return arg0.getId();
}
};
/**
* {@inheritDoc}
*/
@Override
public Template build() {
if (nothingChangedExceptOptions()) {
TemplateBuilder defaultTemplate = defaultTemplateProvider.get();
if (options != null)
defaultTemplate.options(options);
return defaultTemplate.build();
}
if (options == null)
options = optionsProvider.get();
logger.debug(">> searching params(%s)", this);
Set extends Image> images = getImages();
checkState(!images.isEmpty(), "no images present!");
Set extends Hardware> hardwaresToSearch = hardwares.get();
checkState(!hardwaresToSearch.isEmpty(), "no hardware profiles present!");
Image image = null;
if (imageId != null) {
image = loadImageWithId(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();
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));
}
logger.debug("<< matched image(%s) hardware(%s) location(%s)", image.getId(), hardware.getId(),
location.getId());
return new TemplateImpl(image, hardware, location, options);
}
private Iterable extends Image> findSupportedImages(Set extends Image> images) {
Predicate 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 loadImageWithId(Iterable extends Image> images) {
Optional extends Image> image = tryFind(images, ImagePredicates.idEquals(imageId));
if (!image.isPresent()) {
image = this.images.get(imageId); // Load the image from the cache, and refresh if missing
if (!image.isPresent()) {
throw throwNoSuchElementExceptionAfterLoggingImageIds(format("imageId(%s) not found", imageId), images);
}
}
fromImage(image.get());
return image.get();
}
protected 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 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 hardwareOrdering = hardwareSorter();
Iterable> supportsImagePredicates = Iterables.transform(hardwarel,
new Function>() {
@Override
public Predicate apply(Hardware input) {
return input.supportsImage();
}
});
Predicate supportsImagePredicate = Iterables.size(supportsImagePredicates) == 1 ? Iterables
.getOnlyElement(supportsImagePredicates) : Predicates.or(supportsImagePredicates);
if (!Iterables.any(images, supportsImagePredicate)) {
String message = format("no hardware profiles support images matching params: %s", supportsImagePredicate);
throw throwNoSuchElementExceptionAfterLoggingHardwareIds(message, hardwarel);
}
Iterable extends Hardware> hardwareCompatibleWithOurImages = filter(hardwarel, supportsImagesPredicate(images));
Predicate hardwarePredicate = buildHardwarePredicate();
Hardware hardware;
try {
hardware = hardwareOrdering.max(filter(hardwareCompatibleWithOurImages, hardwarePredicate));
} catch (NoSuchElementException exception) {
String message = format("no hardware profiles match params: %s", hardwarePredicate);
throw throwNoSuchElementExceptionAfterLoggingHardwareIds(message, hardwareCompatibleWithOurImages);
}
logger.trace("<< matched hardware(%s)", hardware.getId());
return hardware;
}
protected Function, Image> imageChooser() {
if (imageChooser != null) return imageChooser;
return defaultImageChooser();
}
protected Ordering hardwareSorter() {
Ordering hardwareOrdering = DEFAULT_SIZE_ORDERING;
if (!biggest)
hardwareOrdering = hardwareOrdering.reverse();
if (fastest)
hardwareOrdering = Ordering.compound(ImmutableList.of(BY_CORES_ORDERING, hardwareOrdering));
hardwareOrdering = Ordering.compound(ImmutableList.of(NOT_DEPRECATED_ORDERING, hardwareOrdering));
return hardwareOrdering;
}
/**
*
* @param hardware
* @param supportedImages
* @throws NoSuchElementException
* if there's no image that matches the predicate
*/
protected Image resolveImage(final Hardware hardware, Iterable extends Image> supportedImages) {
Predicate imagePredicate = new Predicate() {
@Override
public boolean apply(Image arg0) {
return hardware.supportsImage().apply(arg0);
}
@Override
public String toString() {
return "hardware(" + hardware + ").supportsImage()";
}
};
try {
Iterable extends Image> matchingImages = filter(supportedImages, imagePredicate);
if (logger.isTraceEnabled())
logger.trace("<< matched images(%s)", transform(matchingImages, imageToId));
return imageChooser().apply(matchingImages);
} catch (NoSuchElementException exception) {
throw throwNoSuchElementExceptionAfterLoggingImageIds(format("no image matched params: %s", toString()),
supportedImages);
}
}
/**
* Like Ordering, but handle the case where there are multiple valid maximums
*/
@SuppressWarnings("unchecked")
@VisibleForTesting
static List multiMax(Comparator ordering, Iterable iterable) {
Iterator iterator = iterable.iterator();
List maxes = newArrayList(iterator.next());
E maxSoFar = maxes.get(0);
while (iterator.hasNext()) {
E current = iterator.next();
int comparison = ordering.compare(maxSoFar, current);
if (comparison == 0) {
maxes.add(current);
} else if (comparison < 0) {
maxes = newArrayList(current);
maxSoFar = current;
}
}
return maxes;
}
protected Set extends Image> getImages() {
return forceCacheReload != null && forceCacheReload ? images.rebuildCache() : images.get();
}
private Predicate buildImagePredicate() {
List> predicates = newArrayList();
if (location != null)
predicates.add(new Predicate() {
@Override
public boolean apply(Image input) {
return locationPredicate.apply(input);
}
@Override
public String toString() {
return locationPredicate.toString();
}
});
final List> 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.isEmpty())
predicates.add(new Predicate() {
@Override
public boolean apply(Image input) {
return Predicates.and(osPredicates).apply(input.getOperatingSystem());
}
@Override
public String toString() {
return Predicates.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);
// looks verbose, but explicit type needed for this to compile
// properly
Predicate imagePredicate = predicates.size() == 1 ? Iterables.> get(predicates, 0)
: Predicates. and(predicates);
return imagePredicate;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder imageId(String imageId) {
this.imageId = imageId;
this.imageName = null;
this.imageDescription = null;
this.imagePredicate = null;
this.imageVersion = null;
this.osFamily = null;
this.osName = null;
this.osDescription = null;
this.osVersion = null;
this.os64Bit = null;
this.osArch = null;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder imageNameMatches(String nameRegex) {
this.imageName = nameRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder imageDescriptionMatches(String descriptionRegex) {
this.imageDescription = descriptionRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder imageMatches(Predicate condition) {
this.imagePredicate = condition;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilderImpl imageChooser(Function, Image> imageChooser) {
this.imageChooser = imageChooser;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder imageVersionMatches(String imageVersionRegex) {
this.imageVersion = imageVersionRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder osVersionMatches(String osVersionRegex) {
this.osVersion = osVersionRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder osArchMatches(String osArchitectureRegex) {
this.osArch = osArchitectureRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder minCores(double minCores) {
this.minCores = minCores;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder minRam(int megabytes) {
this.minRam = megabytes;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder minDisk(double gigabytes) {
this.minDisk = gigabytes;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder osNameMatches(String osNameRegex) {
this.osName = osNameRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder osDescriptionMatches(String osDescriptionRegex) {
this.osDescription = osDescriptionRegex;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder hardwareId(String hardwareId) {
this.hardwareId = hardwareId;
this.hypervisor = null;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder hypervisorMatches(String hypervisor) {
this.hypervisor = hypervisor;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder options(TemplateOptions options) {
this.options = optionsProvider.get();
checkNotNull(options, "options").copyTo(this.options);
return this;
}
@VisibleForTesting
boolean nothingChangedExceptOptions() {
return osFamily == null && location == null && imageId == null && hardwareId == null && hypervisor == null
&& osName == null && imagePredicate == null && imageChooser == null && osDescription == null
&& imageVersion == null && osVersion == null && osArch == null && os64Bit == null && imageName == null
&& imageDescription == null && minCores == 0 && minRam == 0 && minDisk == 0 && !biggest && !fastest;
}
/**
* {@inheritDoc}
*/
@Override
public TemplateBuilder any() {
return defaultTemplateProvider.get();
}
@Override
public String toString() {
return string().toString();
}
/**
* @since 1.5
*/
protected ToStringHelper string() {
ToStringHelper toString = MoreObjects.toStringHelper("").omitNullValues();
if (biggest)
toString.add("biggest", biggest);
if (fastest)
toString.add("fastest", fastest);
toString.add("imageName", imageName);
toString.add("imageDescription", imageDescription);
toString.add("imageId", imageId);
toString.add("imagePredicate", imagePredicate);
toString.add("imageChooser", imageChooser);
toString.add("imageVersion", imageVersion);
if (location != null)
toString.add("locationId", location.getId());
if (minCores > 0) //TODO: make non-primitive
toString.add("minCores", minCores);
if (minRam > 0) //TODO: make non-primitive
toString.add("minRam", minRam);
if (minRam > 0) //TODO: make non-primitive
toString.add("minRam", minRam);
if (minDisk > 0) //TODO: make non-primitive
toString.add("minDisk", minDisk);
toString.add("osFamily", osFamily);
toString.add("osName", osName);
toString.add("osDescription", osDescription);
toString.add("osVersion", osVersion);
toString.add("osArch", osArch);
toString.add("os64Bit", os64Bit);
toString.add("hardwareId", hardwareId);
toString.add("hypervisor", hypervisor);
toString.add("forceCacheReload", forceCacheReload);
return toString;
}
@Override
public TemplateBuilder os64Bit(boolean is64Bit) {
this.os64Bit = is64Bit;
return this;
}
@Override
public TemplateBuilder from(TemplateBuilderSpec spec) {
return spec.copyTo(this, options != null ? options : (options = optionsProvider.get()));
}
@Override
public TemplateBuilder from(String spec) {
return from(TemplateBuilderSpec.parse(spec));
}
@Override
public TemplateBuilder forceCacheReload() {
this.forceCacheReload = true;
return this;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy