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 e97552015e..3770ea369e 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 @@ -81,7 +81,6 @@ import org.apache.brooklyn.location.jclouds.api.JcloudsLocationPublic; import org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension; import org.apache.brooklyn.location.jclouds.networking.creator.DefaultAzureArmNetworkCreator; -import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder; import org.apache.brooklyn.location.jclouds.templates.customize.TemplateBuilderCustomizer; import org.apache.brooklyn.location.jclouds.templates.customize.TemplateBuilderCustomizers; import org.apache.brooklyn.location.jclouds.templates.customize.TemplateOptionCustomizer; @@ -1330,23 +1329,16 @@ public Template buildTemplate(ComputeService computeService, ConfigBag config, C /** 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, JcloudsLocationCustomizer customizersDelegate) { TemplateBuilder templateBuilder = config.get(TEMPLATE_BUILDER); - if (templateBuilder==null) { - templateBuilder = new PortableTemplateBuilder>(); + if (templateBuilder == null) { + templateBuilder = computeService.templateBuilder(); } else { - LOG.debug("jclouds using templateBuilder {} as custom base for provisioning in {} for {}", new Object[] { + LOG.debug("jclouds using templateBuilder {} as custom base for provisioning in {} for {}", new Object[]{ templateBuilder, this, getCreationString(config)}); } - if (templateBuilder instanceof PortableTemplateBuilder) { - if (((PortableTemplateBuilder)templateBuilder).imageChooser()==null) { - Function, Image> chooser = getImageChooser(computeService, config); - templateBuilder.imageChooser(chooser); - } else { - // an image chooser is already set, so do nothing - } - } else { - // template builder supplied, and we cannot check image chooser status; warn, for now - LOG.warn("Cannot check imageChooser status for {} due to manually supplied black-box TemplateBuilder; " - + "it is recommended to use a PortableTemplateBuilder if you supply a TemplateBuilder", getCreationString(config)); + + Function, Image> imageChooser = getImageChooser(computeService, config); + if (imageChooser != null) { + templateBuilder.imageChooser(imageChooser); } if (!Strings.isEmpty(config.get(CLOUD_REGION_ID))) { @@ -1372,34 +1364,30 @@ public Template buildTemplate(ComputeService computeService, ConfigBag config, J } } - if (templateBuilder instanceof PortableTemplateBuilder) { - ((PortableTemplateBuilder)templateBuilder).attachComputeService(computeService); - // do the default last, and only if nothing else specified (guaranteed to be a PTB if nothing else specified) - if (groovyTruth(config.get(DEFAULT_IMAGE_ID))) { - if (((PortableTemplateBuilder)templateBuilder).isBlank()) { - templateBuilder.imageId(config.get(DEFAULT_IMAGE_ID).toString()); - } - } + if (!Strings.isBlank(config.get(DEFAULT_IMAGE_ID))) { + templateBuilder.imageId(config.get(DEFAULT_IMAGE_ID).toString()); } customizersDelegate.customize(this, computeService, templateBuilder); - LOG.debug("jclouds using templateBuilder {} for provisioning in {} for {}", new Object[] { - templateBuilder, this, getCreationString(config)}); + LOG.debug("jclouds using templateBuilder {} for provisioning in {} for {}", new Object[]{ + templateBuilder, this, getCreationString(config)}); // Finally try to build the template Template template = null; Image image; try { template = templateBuilder.build(); - if (template==null) throw new IllegalStateException("No matching template; check image and hardware constraints (e.g. OS, RAM); using "+templateBuilder); + if (template == null) + throw new IllegalStateException("No matching template; check image and hardware constraints (e.g. OS, RAM); using " + templateBuilder); image = template.getImage(); - LOG.debug("jclouds found template "+template+" (image "+image+") for provisioning in "+this+" for "+getCreationString(config)); - if (image==null) throw new IllegalStateException("No matching image in template at "+toStringNice()+"; check image constraints (OS, providers, ID); using "+templateBuilder); + LOG.debug("jclouds found template " + template + " (image " + image + ") for provisioning in " + this + " for " + getCreationString(config)); + if (image == null) + throw new IllegalStateException("No matching image in template at " + toStringNice() + "; check image constraints (OS, providers, ID); using " + templateBuilder); } catch (AuthorizationException e) { - LOG.warn("Error resolving template -- not authorized (rethrowing: "+e+"); template is: "+template); - throw new IllegalStateException("Not authorized to access cloud "+toStringNice()+"; "+ - "check identity, credentials, and endpoint (identity='"+getIdentity()+"', credential length "+getCredential().length()+")", e); + LOG.warn("Error resolving template -- not authorized (rethrowing: " + e + "); template is: " + template); + throw new IllegalStateException("Not authorized to access cloud " + toStringNice() + "; " + + "check identity, credentials, and endpoint (identity='" + getIdentity() + "', credential length " + getCredential().length() + ")", e); } catch (Exception e) { try { IOException ioe = Exceptions.getFirstThrowableOfType(e, IOException.class); @@ -1409,17 +1397,16 @@ public Template buildTemplate(ComputeService computeService, ConfigBag config, J } if (listedAvailableTemplatesOnNoSuchTemplate.compareAndSet(false, true)) { // delay subsequent log.warns (put in synch block) so the "Loading..." message is obvious - LOG.warn("Unable to match required VM template constraints "+templateBuilder+" when trying to provision VM in "+this+" (rethrowing): "+e); + LOG.warn("Unable to match required VM template constraints " + templateBuilder + " when trying to provision VM in " + this + " (rethrowing): " + e); logAvailableTemplates(config); } } catch (Exception e2) { - LOG.warn("Error loading available images to report (following original error matching template which will be rethrown): "+e2, e2); - throw new IllegalStateException("Unable to access cloud "+this+" to resolve "+templateBuilder+": "+e, e); + LOG.warn("Error loading available images to report (following original error matching template which will be rethrown): " + e2, e2); + throw new IllegalStateException("Unable to access cloud " + this + " to resolve " + templateBuilder + ": " + e, e); } - throw new IllegalStateException("Unable to match required VM template constraints "+templateBuilder+" when trying to provision VM in "+this+"; " - + "see list of images in log. Root cause: "+e, e); + throw new IllegalStateException("Unable to match required VM template constraints " + templateBuilder + " when trying to provision VM in " + this + "; " + + "see list of images in log. Root cause: " + e, e); } - TemplateOptions options = template.getOptions(); // For windows, we need a startup-script to be executed that will enable winrm access. // If there is already conflicting userMetadata, then don't replace it (and just warn). @@ -1434,19 +1421,19 @@ public Template buildTemplate(ComputeService computeService, ConfigBag config, J String startupScriptKey = "sysprep-specialize-script-cmd"; Object metadataMapRaw = config.get(USER_METADATA_MAP); if (metadataMapRaw instanceof Map) { - Map metadataMap = (Map) metadataMapRaw; + Map metadataMap = (Map) metadataMapRaw; if (metadataMap.containsKey(startupScriptKey)) { - LOG.warn("Not adding startup-script for Windows VM on "+provider+", because already has key "+startupScriptKey+" in config "+USER_METADATA_MAP.getName()); + LOG.warn("Not adding startup-script for Windows VM on " + provider + ", because already has key " + startupScriptKey + " in config " + USER_METADATA_MAP.getName()); } else { Map metadataMapReplacement = MutableMap.copyOf(metadataMap); metadataMapReplacement.put(startupScriptKey, initScript); config.put(USER_METADATA_MAP, metadataMapReplacement); - LOG.debug("Adding startup-script to enable WinRM for Windows VM on "+provider); + LOG.debug("Adding startup-script to enable WinRM for Windows VM on " + provider); } } else if (metadataMapRaw == null) { Map metadataMapReplacement = MutableMap.of(startupScriptKey, initScript); config.put(USER_METADATA_MAP, metadataMapReplacement); - LOG.debug("Adding startup-script to enable WinRM for Windows VM on "+provider); + LOG.debug("Adding startup-script to enable WinRM for Windows VM on " + provider); } } else { // For AWS and vCloudDirector, we just set user_metadata_string. @@ -1455,26 +1442,27 @@ public Template buildTemplate(ComputeService computeService, ConfigBag config, J boolean userMetadataMap = config.containsKey(JcloudsLocationConfig.USER_METADATA_MAP); if (!(userMetadataString || userMetadataMap)) { config.put(JcloudsLocationConfig.USER_METADATA_STRING, WinRmMachineLocation.getDefaultUserMetadataString(config())); - LOG.debug("Adding startup-script to enable WinRM for Windows VM on "+provider); + LOG.debug("Adding startup-script to enable WinRM for Windows VM on " + provider); } else { - LOG.warn("Not adding startup-script for Windows VM on "+provider+", because already has config " - +(userMetadataString ? USER_METADATA_STRING.getName() : USER_METADATA_MAP.getName())); + LOG.warn("Not adding startup-script for Windows VM on " + provider + ", because already has config " + + (userMetadataString ? USER_METADATA_STRING.getName() : USER_METADATA_MAP.getName())); } } } + TemplateOptions templateOptions = template.getOptions(); + for (Map.Entry, ? extends TemplateOptionCustomizer> entry : SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.entrySet()) { ConfigKey key = entry.getKey(); TemplateOptionCustomizer code = entry.getValue(); if (config.containsKey(key) && config.get(key) != null) { - code.apply(options, config, config.get(key)); + code.apply(templateOptions, config, config.get(key)); } } return template; } - /** * See {@link https://issues.apache.org/jira/browse/JCLOUDS-1108}. * diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java index a988ab6ad1..ca1fc37e48 100644 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/MachinePoolPredicates.java @@ -22,6 +22,7 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Template; import org.jclouds.domain.Location; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +48,7 @@ public static Predicate except(final Predicate predi return Predicates.not(predicateToExclude); } - public static Predicate matching(final ReusableMachineTemplate template) { + public static Predicate matching(final Template template) { return new Predicate() { @Override public boolean apply(NodeMetadata input) { @@ -82,40 +83,31 @@ public static Predicate compose(final Predicate ...p * (Caveat: If explicit Hardware, Image, and/or Template were specified in the template, * then the hash code probably will not detect it.) **/ - public static boolean matches(ReusableMachineTemplate template, NodeMetadata m) { + public static boolean matches(Template template, NodeMetadata m) { try { // tags and user metadata - if (! m.getTags().containsAll( template.getTags(false) )) return false; + if (! m.getTags().containsAll( template.getOptions().getTags())) return false; - if (! isSubMapOf(template.getUserMetadata(false), m.getUserMetadata())) return false; + if (! isSubMapOf(template.getOptions().getUserMetadata(), m.getUserMetadata())) return false; // common hardware parameters + if (m.getHardware().getRam() < template.getHardware().getRam()) return false; - if (template.getMinRam()!=null && m.getHardware().getRam() < template.getMinRam()) return false; - - if (template.getMinCores()!=null) { + if (template.getHardware().getProcessors().get(0) != null) { double numCores = 0; for (Processor p: m.getHardware().getProcessors()) numCores += p.getCores(); - if (numCores+0.001 < template.getMinCores()) return false; - } - - if (template.getIs64bit()!=null) { - if (m.getOperatingSystem().is64Bit() != template.getIs64bit()) return false; + if (numCores+0.001 < template.getHardware().getProcessors().get(0).getCores()) return false; } - if (template.getOsFamily()!=null) { + if (template.getImage().getOperatingSystem().getFamily() != null) { if (m.getOperatingSystem() == null || - !template.getOsFamily().equals(m.getOperatingSystem().getFamily())) return false; + !template.getImage().getOperatingSystem().getFamily().equals(m.getOperatingSystem().getFamily())) return false; } - if (template.getOsNameMatchesRegex()!=null) { - if (m.getOperatingSystem() == null || m.getOperatingSystem().getName()==null || - !m.getOperatingSystem().getName().matches(template.getOsNameMatchesRegex())) return false; - } - - if (template.getLocationId()!=null) { - if (!isLocationContainedIn(m.getLocation(), template.getLocationId())) return false; + + if (template.getLocation().getId() != null) { + if (!isLocationContainedIn(m.getLocation(), template.getLocation().getId())) return false; } // TODO other TemplateBuilder fields and TemplateOptions diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java deleted file mode 100644 index ea93685912..0000000000 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/pool/ReusableMachineTemplate.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.apache.brooklyn.location.jclouds.pool; - - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder; -import org.jclouds.compute.options.TemplateOptions; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -/** - * A facility for having a template we can declare without knowing the provider, - * then find matching instances, create instances, and generally manipulate them. - *

- * NB: to be sure of matching a specific template, you should provide a unique id in the constructor. - * (this will force 'strict' mode.) - */ -// TODO tags/metadata semantics are not quite right, as they could apply to the server _image_ or _instance_ - -// TODO we could use a hashcode over the values of template-builder and template-options fields, as a tag/usermetadata, -// to guarantee (virtually) matching only machines created from this template (instead of asking for unique id) -public class ReusableMachineTemplate extends PortableTemplateBuilder { - - public static final String PREFIX = "brooklyn:template."; - public static final String NAME_METADATA_KEY = PREFIX+"name"; - public static final String DESCRIPTION_METADATA_KEY = PREFIX+"name"; - public static final String HASH_METADATA_KEY = PREFIX+"hash"; - public static final String TEMPLATE_OWNER_METADATA_KEY = PREFIX+"owner"; - - private String name = null; - private String templateOwner = null; - private String description = null; - private boolean strict; - - public ReusableMachineTemplate() { strict = false; } - public ReusableMachineTemplate(String name) { name(name); } - - /** see #getName() */ - public ReusableMachineTemplate name(String name) { - this.name = name; - strict = true; - return this; - } - - /** see #getDescription() */ - public ReusableMachineTemplate description(String description) { - this.description = description; - return this; - } - - /** whether this template only matches machines instances created from this template; - * defaults true if a name is set, otherwise false. - * if false, it will ignore name, owner, and hashcode */ - public ReusableMachineTemplate strict(boolean strict) { - this.strict = strict; - return this; - } - - /** no owner, means anyone can pick this up (default) */ - public ReusableMachineTemplate templateUnowned() { - return templateOwner(null); - } - /** adds user.name as owner of this template */ - public ReusableMachineTemplate templateOwnedByMe() { - return templateOwner(System.getProperty("user.name")); - } - /** adds an owner tag to this template */ - public ReusableMachineTemplate templateOwner(String owner) { - this.templateOwner = owner; - return this; - } - - /** human-friendly name for this template. should normally be unique, it is the primary differentiator for strict matching. */ - public String getName() { - return name; - } - - /** a description for this template; this is set on created machines but _not_ used to filter them - * (so you can change description freely). */ - public String getDescription() { - return description; - } - - public String getOwner() { - return templateOwner; - } - - public boolean isStrict() { - return strict; - } - - @Override - public List getAdditionalOptions() { - List result = new ArrayList(); - result.addAll(super.getAdditionalOptions()); - if (isStrict()) addStrictOptions(result); - return result; - } - - @Override - public List getAdditionalOptionalOptions() { - List result = new ArrayList(); - result.addAll(super.getAdditionalOptions()); - addStrictOptions(result); - return result; - } - - protected void addStrictOptions(List result) { - if (name!=null) result.add(TemplateOptions.Builder.userMetadata(NAME_METADATA_KEY, name)); - if (templateOwner!=null) result.add(TemplateOptions.Builder.userMetadata(TEMPLATE_OWNER_METADATA_KEY, templateOwner)); - // this is too strict -- the hash code seems to change from run to run (would be nice to fix that) -// result.add(TemplateOptions.Builder.userMetadata(HASH_METADATA_KEY, ""+hashCode())); - } - - /** computes the user metadata that this template will set (argument true) or required to match (argument false) */ - public Map getUserMetadata(boolean includeOptional) { - return ImmutableMap.copyOf(computeAggregatedOptions(includeOptional).getUserMetadata()); - } - - /** computes the tags that this template will set (argument true) or require to match (argument false) */ - public Set getTags(boolean includeOptional) { - return ImmutableSet.copyOf(computeAggregatedOptions(includeOptional).getTags()); - } - - public ReusableMachineTemplate tag(String tag) { - return tags(tag); - } - public ReusableMachineTemplate tags(String ...tags) { - return addOptions(TemplateOptions.Builder.tags(Arrays.asList(tags))); - } - - public ReusableMachineTemplate metadata(String key, String value) { - return addOptions(TemplateOptions.Builder.userMetadata(key, value)); - } - public ReusableMachineTemplate metadata(Map m) { - return addOptions(TemplateOptions.Builder.userMetadata(m)); - } - - public ReusableMachineTemplate tagOptional(String tag) { - return tagsOptional(tag); - } - public ReusableMachineTemplate tagsOptional(String ...tags) { - return addOptionalOptions(TemplateOptions.Builder.tags(Arrays.asList(tags))); - } - - public ReusableMachineTemplate metadataOptional(String key, String value) { - return addOptionalOptions(TemplateOptions.Builder.userMetadata(key, value)); - } - public ReusableMachineTemplate metadataOptional(Map m) { - return addOptionalOptions(TemplateOptions.Builder.userMetadata(m)); - } - - @Override - public String toString() { - String s = makeNonTrivialArgumentsString(); - return (name!=null ? name : "Template") + " [ " + s + " ]"; - } - -} diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java deleted file mode 100644 index 1347426c03..0000000000 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/AbstractPortableTemplateBuilder.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * 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.apache.brooklyn.location.jclouds.templates; - -import java.util.ArrayList; -import java.util.List; - -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.domain.TemplateBuilder; -import org.jclouds.compute.options.TemplateOptions; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.base.Objects; -import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableList; - -public abstract class AbstractPortableTemplateBuilder> implements TemplateBuilder { - - /** list of commands supplied by user, excluding options */ - protected List> commands = new ArrayList>(); - - private Hardware hardware; - private Image image; - private Template template; - private String locationId; - private String imageId; - private String hardwareId; - private OsFamily os; - private String osNameRegex; - private String osDescriptionRegex; - private String osVersionRegex; - private String osArchitectureRegex; - private String hypervisorRegex; - private Boolean is64bit; - private String imageNameRegex; - private String imageDescriptionRegex; - private String imageVersionRegex; - private Double minCores; - private Integer minRam; - private Double minDisk; - private Predicate imageCondition; - private Function, Image> imageChooserFunction; - /** this is the last options instance set by a call to options(TemplateOptions) */ - private TemplateOptions options; - /** these are extra options that we want _added_, in order, on top of the last options set */ - private List additionalOptions = new ArrayList(); - @VisibleForTesting - protected Boolean forceCacheReload; - - @Override - public T any() { - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.any(); }}); - return (T)this; - } - - @Override - public T fromHardware(final Hardware hardware) { - this.hardware = hardware; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.fromHardware(hardware); }}); - return (T)this; - } - - public Hardware getHardware() { - return hardware; - } - - @Override - public T fromImage(final Image image) { - this.image = image; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.fromImage(image); }}); - return (T)this; - } - - public Image getImage() { - return image; - } - - @Override - public T fromTemplate(final Template template) { - this.template = template; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.fromTemplate(template); }}); - return (T)this; - } - - public Template getTemplate() { - return template; - } - - @Override - public T smallest() { - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.smallest(); }}); - return (T)this; - } - - @Override - public T fastest() { - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.fastest(); }}); - return (T)this; - } - - @Override - public T biggest() { - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.biggest(); }}); - return (T)this; - } - - @Override - public T locationId(final String locationId) { - this.locationId = locationId; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.locationId(locationId); }}); - return (T)this; - } - - public String getLocationId() { - return locationId; - } - - @Override - public T imageId(final String imageId) { - this.imageId = imageId; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.imageId(imageId); }}); - return (T)this; - } - - public String getImageId() { - return imageId; - } - - @Override - public T hardwareId(final String hardwareId) { - this.hardwareId = hardwareId; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.hardwareId(hardwareId); }}); - return (T)this; - } - - public String getHardwareId() { - return hardwareId; - } - - @Override - public T osNameMatches(final String osNameRegex) { - this.osNameRegex = osNameRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.osNameMatches(osNameRegex); }}); - return (T)this; - } - - public String getOsNameMatchesRegex() { - return osNameRegex; - } - - @Override - public T osDescriptionMatches(final String osDescriptionRegex) { - this.osDescriptionRegex = osDescriptionRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.osDescriptionMatches(osDescriptionRegex); }}); - return (T)this; - } - - public String getOsDescriptionMatchesRegex() { - return osDescriptionRegex; - } - - @Override - public T osVersionMatches(final String osVersionRegex) { - this.osVersionRegex = osVersionRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.osVersionMatches(osVersionRegex); }}); - return (T)this; - } - - public String getOsVersionMatchesRegex() { - return osVersionRegex; - } - - @Override - public T osArchMatches(final String osArchitectureRegex) { - this.osArchitectureRegex = osArchitectureRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.osArchMatches(osArchitectureRegex); }}); - return (T)this; - } - - public String getOsArchitectureMatchesRegex() { - return osArchitectureRegex; - } - - @Override - public T os64Bit(final boolean is64bit) { - this.is64bit = is64bit; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.os64Bit(is64bit); }}); - return (T)this; - } - - public Boolean getIs64bit() { - return is64bit; - } - - @Override - public T osFamily(final OsFamily os) { - this.os = os; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.osFamily(os); }}); - return (T)this; - } - - public OsFamily getOsFamily() { - return os; - } - - @Override - public T hypervisorMatches(final String hypervisorRegex) { - this.hypervisorRegex = hypervisorRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.hypervisorMatches(hypervisorRegex); }}); - return (T)this; - } - - public String getHypervisorMatchesRegex() { - return hypervisorRegex; - } - - @Override - public T imageNameMatches(final String imageNameRegex) { - this.imageNameRegex = imageNameRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.imageNameMatches(imageNameRegex); }}); - return (T)this; - } - - public String getImageNameMatchesRegex() { - return imageNameRegex; - } - - @Override - public T imageDescriptionMatches(final String imageDescriptionRegex) { - this.imageDescriptionRegex = imageDescriptionRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.imageDescriptionMatches(imageDescriptionRegex); }}); - return (T)this; - } - - public String getImageDescriptionMatchesRegex() { - return imageDescriptionRegex; - } - - @Override - public T imageVersionMatches(final String imageVersionRegex) { - this.imageVersionRegex = imageVersionRegex; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.imageVersionMatches(imageVersionRegex); }}); - return (T)this; - } - - public String getImageVersionMatchesRegex() { - return imageVersionRegex; - } - - @Override - public T imageMatches(final Predicate condition) { - this.imageCondition = condition; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.imageMatches(condition); }}); - return (T)this; - } - - public Predicate getImageMatchesCondition() { - return imageCondition; - } - - @Override - public T minCores(final double minCores) { - this.minCores = minCores; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.minCores(minCores); }}); - return (T)this; - } - - public Double getMinCores() { - return minCores; - } - - @Override - public T minRam(final int megabytes) { - this.minRam = megabytes; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.minRam(megabytes); }}); - return (T)this; - } - - /** megabytes */ - public Integer getMinRam() { - return minRam; - } - - @Override - public T minDisk(final double gigabytes) { - this.minDisk = gigabytes; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.minDisk(gigabytes); }}); - return (T)this; - } - - /** megabytes */ - public Double getMinDisk() { - return minDisk; - } - - @Override - public T imageChooser(final Function, Image> imageChooserFunction) { - this.imageChooserFunction = imageChooserFunction; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.imageChooser(imageChooserFunction); }}); - return (T)this; - } - - public Function, Image> imageChooser() { - return imageChooserFunction; - } - - /** clears everything set in this template, including any default from the compute service */ - // not sure this is that useful, as the default is only applied if there are no changes - public T blank() { - hardware = null; - image = null; - template = null; - hypervisorRegex = null; - os = null; - locationId = null; - imageId = null; - hardwareId = null; - osNameRegex = null; - osDescriptionRegex = null; - osVersionRegex = null; - osArchitectureRegex = null; - is64bit = null; - imageNameRegex = null; - imageDescriptionRegex = null; - imageVersionRegex = null; - imageCondition = null; - minCores = null; - minRam = null; - options = null; - additionalOptions.clear(); - - // clear all fields, and commands - commands.clear(); - // then add a command to clear osName + Version + 64bit - osFamily(null); - osVersionMatches(null); - // no way to turn off 64-bitness, but it won't usually be turned on -// os64bit(null); - // set _something_ to prevent the default from applying - minRam(1); - - return (T)this; - } - - /** true if the templateBuilder spec is blank (ignoring customization options e.g. tags for the resulting instance) */ - public boolean isBlank() { - if (commands.isEmpty()) return true; - //also "blank" if we've blanked it - if (commands.size()==1 && (minRam!=null && minRam==1)) return true; - return false; - } - - @Override - public T options(final TemplateOptions options) { - this.options = options; - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.options(options); }}); - return (T)this; - } - - /** sets customization options; may be null if not set. use addOptions(new TemplateOptions()) to set new ones. */ - public TemplateOptions getOptions() { - return options; - } - - /** adds customization options; if options have already been set, this will additively set selected options - * (but not all, see addTemplateOptions for more info) - */ - public T addOptions(final TemplateOptions options) { - this.additionalOptions.add(options); - commands.add(new Function() { - @Override - public TemplateBuilder apply(TemplateBuilder b) { return b.options(options); }}); - return (T)this; - } - - public List getAdditionalOptions() { - return ImmutableList.copyOf(additionalOptions); - } - - @Override - public int hashCode() { - return Objects.hashCode( - hypervisorRegex, - os, - locationId, - hardwareId, - imageId, - imageDescriptionRegex, - imageNameRegex, - imageVersionRegex, - // might not be implement hashCode, so ignore -// imageCondition, -// imageChooserFunction, - is64bit, - locationId, - osArchitectureRegex, - osDescriptionRegex, - osNameRegex, - osVersionRegex, - minCores, - minRam, - minDisk, - options, - additionalOptions, - // might not implement hashCode, so ignore -// template, - 0); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - AbstractPortableTemplateBuilder other = (AbstractPortableTemplateBuilder) obj; - if (!Objects.equal(additionalOptions, other.additionalOptions)) return false; - if (!Objects.equal(commands, other.commands)) return false; - if (!Objects.equal(locationId, other.locationId)) return false; - if (!Objects.equal(hardware, other.hardware)) return false; - if (!Objects.equal(hardwareId, other.hardwareId)) return false; - if (!Objects.equal(image, other.image)) return false; - if (!Objects.equal(imageId, other.imageId)) return false; - if (!Objects.equal(imageDescriptionRegex, other.imageDescriptionRegex)) return false; - if (!Objects.equal(imageNameRegex, other.imageNameRegex)) return false; - if (!Objects.equal(imageVersionRegex, other.imageVersionRegex)) return false; - if (!Objects.equal(imageCondition, other.imageCondition)) return false; - if (!Objects.equal(imageChooserFunction, other.imageChooserFunction)) return false; - if (!Objects.equal(os, other.os)) return false; - if (!Objects.equal(osArchitectureRegex, other.osArchitectureRegex)) return false; - if (!Objects.equal(osDescriptionRegex, other.osDescriptionRegex)) return false; - if (!Objects.equal(osNameRegex, other.osNameRegex)) return false; - if (!Objects.equal(osVersionRegex, other.osVersionRegex)) return false; - if (!Objects.equal(is64bit, other.is64bit)) return false; - if (!Objects.equal(hypervisorRegex, other.hypervisorRegex)) return false; - if (!Objects.equal(minCores, other.minCores)) return false; - if (!Objects.equal(minRam, other.minRam)) return false; - if (!Objects.equal(minDisk, other.minDisk)) return false; - if (!Objects.equal(options, other.options)) return false; - if (!Objects.equal(template, other.template)) return false; - return true; - } - - @Override - public String toString() { - return getClass().getSimpleName()+"["+makeNonTrivialArgumentsString()+"]"; - } - - protected String makeNonTrivialArgumentsString() { - String s = - (hardware != null ? "hardware=" + hardware + ", " : "") - + (image != null ? "image=" + image + ", " : "") - + (template != null ? "template=" + template + ", " : "") - + (hypervisorRegex != null ? "hypervisorRegex=" - + hypervisorRegex + ", " : "") - + (os != null ? "os=" + os + ", " : "") - + (locationId != null ? "locationId=" + locationId + ", " : "") - + (imageId != null ? "imageId=" + imageId + ", " : "") - + (hardwareId != null ? "hardwareId=" + hardwareId + ", " : "") - + (osNameRegex != null ? "osNameRegex=" + osNameRegex + ", " - : "") - + (osDescriptionRegex != null ? "osDescriptionRegex=" - + osDescriptionRegex + ", " : "") - + (osVersionRegex != null ? "osVersionRegex=" + osVersionRegex - + ", " : "") - + (osArchitectureRegex != null ? "osArchictectureRegex=" - + osArchitectureRegex + ", " : "") - + (is64bit != null ? "is64bit=" + is64bit + ", " : "") - + (imageNameRegex != null ? "imageNameRegex=" + imageNameRegex - + ", " : "") - + (imageDescriptionRegex != null ? "imageDescriptionRegex=" - + imageDescriptionRegex + ", " : "") - + (imageVersionRegex != null ? "imageVersionRegex=" - + imageVersionRegex + ", " : "") - + (imageCondition != null ? "imageCondition=" + imageCondition - + ", " : "") - + (imageChooserFunction != null ? "imageChooserFunction=" + imageChooserFunction - + ", " : "") - + (minCores != null ? "minCores=" + minCores + ", " : "") - + (minRam != null ? "minRam=" + minRam + ", " : "") - + (minDisk != null ? "minDisk=" + minDisk + ", " : ""); - if (s.endsWith(", ")) s = s.substring(0, s.length()-2); - return s; - } - - -} diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java deleted file mode 100644 index 86dfe4bf1e..0000000000 --- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/PortableTemplateBuilder.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.apache.brooklyn.location.jclouds.templates; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.jclouds.compute.ComputeService; -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 com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.primitives.Ints; - - -public class PortableTemplateBuilder> extends AbstractPortableTemplateBuilder { - - ComputeService svc; - List additionalOptionalOptions = new ArrayList(); - - @Override - public synchronized Template build() { - if (svc!=null) return newJcloudsTemplate(svc); - throw new IllegalStateException("Cannot build a portable template until a compute service is attached"); - } - - @Override - public TemplateBuilder forceCacheReload() { - this.forceCacheReload = true; - return this; - } - - public synchronized ComputeService attachComputeService(ComputeService svc) { - ComputeService old = this.svc; - this.svc = svc; - return old; - } - - public TemplateBuilder newJcloudsTemplateBuilder(ComputeService svc) { - TemplateBuilder tb = svc.templateBuilder(); - for (Function c: commands) { - tb = c.apply(tb); - } - - tb.options(computeAggregatedOptions(true)); - - return tb; - } - - public Template newJcloudsTemplate(ComputeService svc) { - return newJcloudsTemplateBuilder(svc).build(); - } - - /** Adds template options which are used for building, but not for matching/filtering. - * (eg tags added here will be set on any machine created by this template, - * but will not be required when matching this template to existing machines) */ - @SuppressWarnings("unchecked") - public T addOptionalOptions(TemplateOptions options) { - additionalOptionalOptions.add(options); - return (T)this; - } - - protected TemplateOptions computeAggregatedOptions(boolean includeOptional) { - TemplateOptions result; - if (getOptions()!=null) result = getOptions().clone(); - else result = new TemplateOptions(); - if (includeOptional) - for (TemplateOptions moreOptions: getAdditionalOptionalOptions()) result = addTemplateOptions(result, moreOptions); - for (TemplateOptions moreOptions: getAdditionalOptions()) result = addTemplateOptions(result, moreOptions); - return result; - } - - public List getAdditionalOptionalOptions() { - return ImmutableList.copyOf(additionalOptionalOptions); - } - - /** like TemplateOptions.copyTo but additive wrt arrays, collections, and maps, - * putting moreOptions in on top of / at the end of options. - * currently applies to inboundPorts, tags, and userMetadata. */ - public static TemplateOptions addTemplateOptions(TemplateOptions options, TemplateOptions moreOptions) { - TemplateOptions result = options.clone(); - moreOptions.copyTo(result); - - Set tags = new LinkedHashSet(options.getTags()); - tags.addAll(moreOptions.getTags()); - result.tags(tags); - - Map userMetadata = new LinkedHashMap(options.getUserMetadata()); - userMetadata.putAll(moreOptions.getUserMetadata()); - result.userMetadata(userMetadata); - - Set inboundPorts = new TreeSet(); - for (int port: options.getInboundPorts()) inboundPorts.add(port); - for (int port: moreOptions.getInboundPorts()) inboundPorts.add(port); - int[] inboundPortsArray = new int[inboundPorts.size()]; - int i=0; - for (Iterator portI=inboundPorts.iterator(); portI.hasNext();) { - inboundPortsArray[i++] = portI.next(); - } - result.inboundPorts(inboundPortsArray); - - return result; - } - - @Override - protected String makeNonTrivialArgumentsString() { - String s = super.makeNonTrivialArgumentsString(); - TemplateOptions aggr = computeAggregatedOptions(false); - if (aggr.getInboundPorts().length>0) s = "ports="+Ints.asList(aggr.getInboundPorts())+(s!=null && s.length()>0 ? ", "+s : ""); - if (!aggr.getUserMetadata().isEmpty()) s = "metadata="+aggr.getUserMetadata()+(s!=null && s.length()>0 ? ", "+s : ""); - if (!aggr.getTags().isEmpty()) s = "tags="+aggr.getTags()+(s!=null && s.length()>0 ? ", "+s : ""); - return s; - } - - @Override - public TemplateBuilder from(TemplateBuilderSpec spec) { - TemplateOptions options = new TemplateOptions(); - addOptionalOptions(options); - TemplateBuilder result = spec.copyTo(this, options); - return result; - } - - @Override - public TemplateBuilder from(String spec) { - return from(TemplateBuilderSpec.parse(spec)); - } -}