diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/EC2PropertiesBuilder.java b/aws/core/src/main/java/org/jclouds/aws/ec2/EC2PropertiesBuilder.java index 396f733271..3feee9d6dc 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/EC2PropertiesBuilder.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/EC2PropertiesBuilder.java @@ -38,7 +38,7 @@ public class EC2PropertiesBuilder extends HttpPropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_EC2_ENDPOINT, "https://ec2.amazonaws.com"); + properties.setProperty(PROPERTY_EC2_ENDPOINT, "https://ec2.us-east-1.amazonaws.com"); properties.setProperty(PROPERTY_AWS_EXPIREINTERVAL, "60"); return properties; } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java index ea007eb4c2..cd7f2f356a 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2ComputeService.java @@ -26,7 +26,6 @@ import java.net.InetAddress; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; -import java.util.SortedSet; import javax.annotation.Resource; import javax.inject.Inject; @@ -43,15 +42,16 @@ import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.options.RunInstancesOptions; import org.jclouds.compute.ComputeService; -import org.jclouds.compute.domain.Architecture; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.CreateNodeResponse; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeState; -import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl; @@ -76,22 +76,21 @@ public class EC2ComputeService implements ComputeService { @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; private final EC2Client ec2Client; - private final SortedSet sizes; - private final Provider> templates; + protected final Provider> images; + protected final Provider> sizes; + protected final Provider templateBuilderProvider; private final Predicate instanceStateRunning; private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata; - private final Map>> imageAmiIdMap; @Inject - public EC2ComputeService(EC2Client client, SortedSet sizes, - Provider> templates, - Map>> imageAmiIdMap, + public EC2ComputeService(EC2Client client, Provider templateBuilderProvider, + Provider> images, Provider> sizes, Predicate instanceStateRunning, RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) { this.ec2Client = client; + this.images = images; this.sizes = sizes; - this.templates = templates; // delayed intentionally, as generation is slow - this.imageAmiIdMap = imageAmiIdMap; + this.templateBuilderProvider = templateBuilderProvider; this.instanceStateRunning = instanceStateRunning; this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata; } @@ -108,20 +107,23 @@ public class EC2ComputeService implements ComputeService { @Override public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) { - checkArgument(template instanceof EC2Template, - "unexpected template type. should be EC2Template, was: " + template.getClass()); - EC2Template ec2Template = (EC2Template) template; + checkArgument(template.getImage() instanceof EC2Image, + "unexpected image type. should be EC2Image, was: " + template.getImage().getClass()); + checkArgument(template.getSize() instanceof EC2Size, + "unexpected image type. should be EC2Size, was: " + template.getSize().getClass()); + EC2Image ec2Image = EC2Image.class.cast(template.getImage()); + EC2Size ec2Size = EC2Size.class.cast(template.getSize()); - KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name); + Region region = ec2Image.getImage().getRegion(); + KeyPair keyPair = createKeyPairInRegion(region, name); String securityGroupName = name; - createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, options - .getOpenPorts()); + createSecurityGroupInRegion(region, securityGroupName, options.getOpenPorts()); logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)", - ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize() - .getInstanceType(), keyPair.getKeyName(), securityGroupName); + region, ec2Image.getId(), ec2Size.getInstanceType(), keyPair.getKeyName(), + securityGroupName); RunInstancesOptions instanceOptions = withKeyName(keyPair.getKeyName())// key - .asType(ec2Template.getSize().getInstanceType())// instance size + .asType(ec2Size.getInstanceType())// instance size .withSecurityGroup(securityGroupName)// group I created above .withAdditionalInfo(name); @@ -129,36 +131,24 @@ public class EC2ComputeService implements ComputeService { instanceOptions.withUserData(options.getRunScript()); RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices() - .runInstancesInRegion(ec2Template.getRegion(), null, ec2Template.getImage().getId(), - 1, 1, instanceOptions)); + .runInstancesInRegion(region, null, ec2Image.getId(), 1, 1, instanceOptions)); logger.debug("<< started instance(%s)", runningInstance.getId()); instanceStateRunning.apply(runningInstance); logger.debug("<< running instance(%s)", runningInstance.getId()); // refresh to get IP address - runningInstance = getOnlyRunningInstanceInRegion(ec2Template.getRegion(), runningInstance - .getId()); + runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId()); Set publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet . of() : ImmutableSet. of(runningInstance.getIpAddress()); Set privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet . of() : ImmutableSet. of(runningInstance.getPrivateIpAddress()); - return new CreateNodeResponseImpl( - runningInstance.getId(), - name, - runningInstance.getRegion().toString(), - null, - ImmutableMap. of(), - instanceToNodeState.get(runningInstance.getInstanceState()), - publicAddresses, - privateAddresses, - 22, + return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion() + .toString(), null, ImmutableMap. of(), instanceToNodeState + .get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22, LoginType.SSH, - new Credentials( - ec2Template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU ? "ubuntu" - : "root", keyPair.getKeyMaterial()), ImmutableMap - . of()); + new Credentials("root", keyPair.getKeyMaterial()), ImmutableMap. of()); } private KeyPair createKeyPairInRegion(Region region, String name) { @@ -316,17 +306,18 @@ public class EC2ComputeService implements ComputeService { } @Override - public SortedSet listSizes() { - return sizes; + public Set listSizes() { + return sizes.get(); } @Override - public Set listTemplates() { - return templates.get(); + public Set listImages() { + return images.get(); } @Override - public Template createTemplateInLocation(String location) { - return new EC2Template(ec2Client, imageAmiIdMap, location); + public TemplateBuilder templateBuilder() { + return templateBuilderProvider.get(); } + } \ No newline at end of file diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Image.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Image.java new file mode 100644 index 0000000000..2b2c673fb9 --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Image.java @@ -0,0 +1,139 @@ +/** + * + * Copyright (C) 2009 Global Cloud Specialists, Inc. + * + * ==================================================================== + * 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.aws.ec2.compute; + +import org.jclouds.compute.domain.Architecture; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; + +/** + * + * @author Adrian Cole + */ +public class EC2Image implements Image { + private final org.jclouds.aws.ec2.domain.Image image; + private final OperatingSystem os; + private final String osVersion; + private final String version; + + public EC2Image(org.jclouds.aws.ec2.domain.Image image, OperatingSystem os, String osVersion, + String version) { + this.image = image; + this.os = os; + this.osVersion = osVersion; + this.version = version; + } + + @Override + public Architecture getArchitecture() { + return getImage().getArchitecture() == org.jclouds.aws.ec2.domain.Image.Architecture.I386 ? Architecture.X86_32 + : Architecture.X86_64; + } + + @Override + public String getDescription() { + return getImage().getDescription(); + } + + @Override + public String getId() { + return getImage().getId(); + } + + @Override + public String getLocation() { + return getImage().getRegion().toString(); + } + + @Override + public OperatingSystem getOperatingSystem() { + return os; + } + + @Override + public String getOperatingSystemVersion() { + return osVersion; + } + + @Override + public String getVersion() { + return version; + } + + public org.jclouds.aws.ec2.domain.Image getImage() { + return image; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((image == null) ? 0 : image.hashCode()); + result = prime * result + ((os == null) ? 0 : os.hashCode()); + result = prime * result + ((osVersion == null) ? 0 : osVersion.hashCode()); + result = prime * result + ((version == null) ? 0 : version.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EC2Image other = (EC2Image) obj; + if (image == null) { + if (other.image != null) + return false; + } else if (!image.equals(other.image)) + return false; + if (os == null) { + if (other.os != null) + return false; + } else if (!os.equals(other.os)) + return false; + if (osVersion == null) { + if (other.osVersion != null) + return false; + } else if (!osVersion.equals(other.osVersion)) + return false; + if (version == null) { + if (other.version != null) + return false; + } else if (!version.equals(other.version)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + getId() + ", version=" + version + ", location=" + getLocation() + + ", architecture=" + getArchitecture() + ", operatingSystem=" + + getOperatingSystem() + ", operatingSystemVersion=" + getOperatingSystemVersion() + + ", description=" + getDescription() + "]"; + } + +} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Size.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Size.java index d32fcb747a..56dc5c9779 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Size.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Size.java @@ -38,7 +38,7 @@ public class EC2Size extends SizeImpl { EC2Size(InstanceType instanceType, Integer cores, Integer ram, Integer disk, Iterable supportedArchitectures) { - super(cores, ram, disk, supportedArchitectures); + super(instanceType.toString(), cores, ram, disk, supportedArchitectures); this.instanceType = instanceType; } @@ -85,4 +85,29 @@ public class EC2Size extends SizeImpl { public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20, 7168, 1690, ImmutableSet.of(Architecture.X86_64)); + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + EC2Size other = (EC2Size) obj; + if (instanceType == null) { + if (other.instanceType != null) + return false; + } else if (!instanceType.equals(other.instanceType)) + return false; + return true; + } + } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Template.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Template.java deleted file mode 100644 index 11503ee43d..0000000000 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Template.java +++ /dev/null @@ -1,233 +0,0 @@ -/** - * - * Copyright (C) 2009 Global Cloud Specialists, Inc. - * - * ==================================================================== - * 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.aws.ec2.compute; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import javax.annotation.Nullable; - -import org.jclouds.aws.domain.Region; -import org.jclouds.aws.ec2.EC2Client; -import org.jclouds.aws.ec2.util.EC2Utils; -import org.jclouds.compute.domain.Architecture; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.domain.Template; - -import com.google.common.annotations.VisibleForTesting; - -/** - * - * @author Adrian Cole - */ -public class EC2Template implements Template { - private final EC2Client client; - private final Map>> imageAmiIdMap; - private EC2Size size; - private OperatingSystem operatingSystem; - private Region region; - private transient Image image; - - public EC2Template(EC2Client client, - Map>> imageAmiIdMap, - EC2Size size, OperatingSystem operatingSystem, Region region, @Nullable Image image) { - this.client = client; - this.size = size; - this.operatingSystem = operatingSystem; - this.region = region; - this.imageAmiIdMap = imageAmiIdMap; - this.image = image != null ? image : resolveImage(); - } - - EC2Template(EC2Client client, - Map>> imageAmiIdMap, - String location) { - this(client, imageAmiIdMap, EC2Size.M1_SMALL, OperatingSystem.UBUNTU, Region - .fromValue(location), null); - } - - /** - * {@inheritDoc} - */ - @Override - public EC2Size getSize() { - return size; - } - - /** - * {@inheritDoc} - */ - @Override - public Image getImage() { - return image; - } - - @VisibleForTesting - Image resolveImage() { - Architecture architecture = size.supportsArchitecture(Architecture.X86_64) ? Architecture.X86_64 - : Architecture.X86_32; - String ami = checkNotNull( - checkNotNull( - checkNotNull( - imageAmiIdMap.get(architecture), - String.format( - "architecture %s not supported. Valid choices %s: ", - architecture, imageAmiIdMap.keySet())).get( - operatingSystem), - String - .format( - "operatingSystem %s not supported for architecture %s. Valid choices %s: ", - operatingSystem, architecture, imageAmiIdMap.get( - architecture).keySet())).get(region), - String - .format( - "region %s not supported for operatingSystem %s, architecture %s. Valid choices %s: ", - region, operatingSystem, architecture, imageAmiIdMap.get( - architecture).get(operatingSystem).keySet())); - return EC2Utils.newImage(client, region, operatingSystem, architecture, ami); - } - - public Template asSize(EC2Size size) { - this.size = size; - this.image = resolveImage(); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Template smallest() { - return asSize(EC2Size.M1_SMALL); - } - - /** - * {@inheritDoc} - */ - @Override - public Template biggest() { - return asSize(EC2Size.M2_4XLARGE); - } - - /** - * {@inheritDoc} - */ - @Override - public Template fastest() { - return asSize(EC2Size.C1_XLARGE); - } - - /** - * {@inheritDoc} - */ - @Override - public Template inLocation(String location) { - this.region = Region.fromValue(location); - this.image = resolveImage(); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Template os(OperatingSystem os) { - this.operatingSystem = os; - this.image = resolveImage(); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((image == null) ? 0 : image.hashCode()); - result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode()); - result = prime * result + ((region == null) ? 0 : region.hashCode()); - result = prime * result + ((size == null) ? 0 : size.hashCode()); - return result; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - EC2Template other = (EC2Template) obj; - if (image == null) { - if (other.image != null) - return false; - } else if (!image.equals(other.image)) - return false; - if (operatingSystem == null) { - if (other.operatingSystem != null) - return false; - } else if (!operatingSystem.equals(other.operatingSystem)) - return false; - if (region == null) { - if (other.region != null) - return false; - } else if (!region.equals(other.region)) - return false; - if (size == null) { - if (other.size != null) - return false; - } else if (!size.equals(other.size)) - return false; - return true; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "EC2Template [image=" + image + ", operatingSystem=" + operatingSystem + ", region=" - + region + ", size=" + size + "]"; - } - - /** - * {@inheritDoc} - */ - @Override - protected Object clone() throws CloneNotSupportedException { - return new EC2Template(client, imageAmiIdMap, size, operatingSystem, region, image); - } - - public Region getRegion() { - return region; - } - -} diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java index 6fc9647dc5..75d677ca62 100755 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -18,33 +18,40 @@ */ package org.jclouds.aws.ec2.compute.config; +import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy; + +import java.net.URI; import java.util.Map; import java.util.Set; -import java.util.SortedSet; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.annotation.Resource; import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.EC2; import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.compute.EC2ComputeService; +import org.jclouds.aws.ec2.compute.EC2Image; import org.jclouds.aws.ec2.compute.EC2Size; -import org.jclouds.aws.ec2.compute.EC2Template; import org.jclouds.aws.ec2.config.EC2ContextModule; -import org.jclouds.aws.ec2.util.EC2Utils; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.domain.Architecture; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Size; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.ResourceLocation; import org.jclouds.logging.Logger; import org.jclouds.rest.RestContext; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.inject.Provides; @@ -70,61 +77,55 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule { @Provides @Singleton - SortedSet provideSizes() { - return ImmutableSortedSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, + Set provideSizes() { + return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE); } + @Provides + @Singleton + @ResourceLocation + String getRegion(@EC2 Region region) { + return region.value(); + } + private static class LogHolder { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; } - @Provides - @Singleton - Set provideTemplates(EC2Client client, SortedSet sizes, - Map>> imageAmiIdMap, - LogHolder holder) { - Set templates = Sets.newHashSet(); - holder.logger.debug(">> generating templates"); - for (EC2Size size : sizes) { - for (Architecture architecture : imageAmiIdMap.keySet()) { - if (size.supportsArchitecture(architecture)) { - for (OperatingSystem operatingSystem : imageAmiIdMap.get(architecture).keySet()) { - for (Region region : imageAmiIdMap.get(architecture).get(operatingSystem) - .keySet()) { - String ami = imageAmiIdMap.get(architecture).get(operatingSystem).get(region); - templates.add(new EC2Template(client, imageAmiIdMap, size, operatingSystem, - region, EC2Utils.newImage(client, region, operatingSystem, - architecture, ami))); - } - } - } - } - } - holder.logger.debug("<< templates(%d)", templates.size()); - return templates; - } + // alestic-32-eu-west-1/debian-4.0-etch-base-20081130.manifest.xml + public static final Pattern ALESTIC_PATTERN = Pattern + .compile(".*/([^-]*)-([^-]*)-.*-(.*)\\.manifest\\.xml"); @Provides @Singleton - Map>> provideimageAmiIdMap() { - return ImmutableMap.>> of( - Architecture.X86_32,// - ImmutableMap.> builder().put( - OperatingSystem.UBUNTU, - ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1, - "ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38", - Region.EU_WEST_1, "ami-a62a01d2")).put( - OperatingSystem.RHEL, - ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1, - "ami-368b685f")).build(),// - Architecture.X86_64,// - ImmutableMap.> builder().put( - OperatingSystem.UBUNTU, - ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1, - "ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e", - Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami + protected Set provideImages(final EC2Client sync, Map regionMap, + LogHolder holder) throws InterruptedException, ExecutionException, TimeoutException { + final Set images = Sets.newHashSet(); + holder.logger.debug(">> providing images"); + for (final Region region : regionMap.keySet()) { + for (final org.jclouds.aws.ec2.domain.Image from : sync.getAMIServices() + .describeImagesInRegion(region, ownedBy("063491364108"))) { + OperatingSystem os = null; + String osVersion = ""; + String version = ""; + + Matcher matcher = ALESTIC_PATTERN.matcher(from.getImageLocation()); + if (matcher.find()) { + try { + os = OperatingSystem.fromValue(matcher.group(1)); + osVersion = matcher.group(2); + version = matcher.group(3); + } catch (IllegalArgumentException e) { + holder.logger.debug("<< didn't match os(%s)", matcher.group(1)); + } + } + images.add(new EC2Image(from, os, osVersion, version)); + } + } + holder.logger.debug("<< images(%d)", images.size()); + return images; } } diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java b/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java index 76c3d963f8..350499cb31 100755 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/config/EC2RestClientModule.java @@ -68,6 +68,7 @@ import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.RestClientFactory; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.Maps; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -92,6 +93,16 @@ public class EC2RestClientModule extends AbstractModule { bindRetryHandlers(); } + @Provides + @Singleton + @EC2 + Region provideCurrentRegion(Map regionMap, @EC2 URI currentUri) { + ImmutableBiMap map = ImmutableBiMap.copyOf(regionMap).inverse(); + Region region = map.get(currentUri); + assert region != null : currentUri + " not in " + map; + return region; + } + @Provides @Singleton Map provideRegions(AvailabilityZoneAndRegionClient client) { diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java index 897b720344..85f2f533fd 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/services/InstanceClient.java @@ -41,7 +41,7 @@ import org.jclouds.concurrent.Timeout; * * @author Adrian Cole */ -@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) +@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS) public interface InstanceClient { /** diff --git a/aws/core/src/main/java/org/jclouds/aws/ec2/util/EC2Utils.java b/aws/core/src/main/java/org/jclouds/aws/ec2/util/EC2Utils.java index 54468b31ab..ffbd57ad92 100644 --- a/aws/core/src/main/java/org/jclouds/aws/ec2/util/EC2Utils.java +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/util/EC2Utils.java @@ -20,30 +20,16 @@ package org.jclouds.aws.ec2.util; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds; import org.jclouds.aws.domain.Region; -import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.domain.AvailabilityZone; -import org.jclouds.compute.domain.Architecture; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.rest.internal.GeneratedHttpRequest; -import com.google.inject.internal.Iterables; - /** * * @author Adrian Cole */ public class EC2Utils { - public static Image newImage(EC2Client client, Region region, OperatingSystem os, - Architecture architecture, String ami) { - org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(client.getAMIServices() - .describeImagesInRegion(region, imageIds(ami))); - return new ImageImpl(ami, image.getDescription(), os, null, region.toString(), architecture); - } public static void indexStringArrayToFormValuesWithPrefix(GeneratedHttpRequest request, String prefix, Object input) { diff --git a/aws/core/src/main/java/org/jclouds/aws/sqs/xml/QueueHandler.java b/aws/core/src/main/java/org/jclouds/aws/sqs/xml/QueueHandler.java index 6e3c1d5803..3d0b1b75ba 100644 --- a/aws/core/src/main/java/org/jclouds/aws/sqs/xml/QueueHandler.java +++ b/aws/core/src/main/java/org/jclouds/aws/sqs/xml/QueueHandler.java @@ -46,7 +46,6 @@ public class QueueHandler extends ParseSax.HandlerWithResult { @Inject QueueHandler(Map regionMap) { this.regionBiMap = ImmutableBiMap.copyOf(regionMap); - } public Queue getResult() { diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ContextBuilderTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ContextBuilderTest.java index cdca18f72b..ea6fd2ecb6 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ContextBuilderTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/EC2ContextBuilderTest.java @@ -49,7 +49,7 @@ public class EC2ContextBuilderTest { public void testNewBuilder() { EC2ContextBuilder builder = newBuilder(); assertEquals(builder.getProperties().getProperty(EC2Constants.PROPERTY_EC2_ENDPOINT), - "https://ec2.amazonaws.com"); + "https://ec2.us-east-1.amazonaws.com"); assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id"); assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret"); } @@ -58,7 +58,7 @@ public class EC2ContextBuilderTest { RestContext context = newBuilder().buildContext(); assertEquals(context.getClass(), RestContextImpl.class); assertEquals(context.getAccount(), "id"); - assertEquals(context.getEndPoint(), URI.create("https://ec2.amazonaws.com")); + assertEquals(context.getEndPoint(), URI.create("https://ec2.us-east-1.amazonaws.com")); } public void testBuildInjector() { diff --git a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2ComputeServiceLiveTest.java b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2ComputeServiceLiveTest.java index 1e06914dab..e9d96b97a5 100644 --- a/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2ComputeServiceLiveTest.java +++ b/aws/core/src/test/java/org/jclouds/aws/ec2/compute/EC2ComputeServiceLiveTest.java @@ -21,6 +21,8 @@ package org.jclouds.aws.ec2.compute; import static org.jclouds.compute.domain.OperatingSystem.UBUNTU; import org.jclouds.compute.BaseComputeServiceLiveTest; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -37,7 +39,10 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { @Override public void setServiceDefaults() { service = "ec2"; - testOS = UBUNTU; + } + + protected Template buildTemplate(TemplateBuilder templateBuilder) { + return templateBuilder.os(UBUNTU).smallest().build(); } @Override diff --git a/compute/src/main/java/org/jclouds/compute/ComputeService.java b/compute/src/main/java/org/jclouds/compute/ComputeService.java index 28ef3e8850..80f99d71bd 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeService.java @@ -19,13 +19,14 @@ package org.jclouds.compute; import java.util.Set; -import java.util.SortedSet; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.CreateNodeResponse; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.options.RunNodeOptions; /** @@ -36,27 +37,19 @@ import org.jclouds.compute.options.RunNodeOptions; */ public interface ComputeService { /** - * Creates a new template in the specified location. - * - * @param location - * where the template is valid for + * Makes a new template builder for this service */ - Template createTemplateInLocation(String location); + TemplateBuilder templateBuilder(); /** * List all sizes available to the current user */ - SortedSet listSizes(); + Set listSizes(); /** * List all images available to the current user */ -// Set listImages(); - - /** - * List all templates available to the current user - */ - Set listTemplates(); + Set listImages(); /** * List all nodes available to the current user @@ -68,6 +61,7 @@ public interface ComputeService { * */ CreateNodeResponse runNode(String name, Template template); + CreateNodeResponse runNode(String name, Template template, RunNodeOptions options); /** diff --git a/compute/src/main/java/org/jclouds/compute/domain/Image.java b/compute/src/main/java/org/jclouds/compute/domain/Image.java index d951dc70a7..6082c3415b 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Image.java +++ b/compute/src/main/java/org/jclouds/compute/domain/Image.java @@ -46,6 +46,11 @@ public interface Image { */ OperatingSystem getOperatingSystem(); + /** + * Version of the operating system + */ + String getOperatingSystemVersion(); + /** * Version of the image */ diff --git a/compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java b/compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java index 76854b732e..b680a1b439 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java +++ b/compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java @@ -23,11 +23,28 @@ */ package org.jclouds.compute.domain; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.CaseFormat; + /** * Running Operating system * * @author Adrian Cole */ public enum OperatingSystem { - CENTOS, RHEL, UBUNTU, JEOS, WINDOWS, UNKNOWN; + CENTOS, RHEL, FEDORA, DEBIAN, UBUNTU, JEOS, WINDOWS; + public String value() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); + } + + @Override + public String toString() { + return value(); + } + + public static OperatingSystem fromValue(String operatingSystem) { + return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull( + operatingSystem, "region"))); + } } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/domain/Size.java b/compute/src/main/java/org/jclouds/compute/domain/Size.java index a5ad9c9dce..24b13f0b62 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Size.java +++ b/compute/src/main/java/org/jclouds/compute/domain/Size.java @@ -23,13 +23,23 @@ */ package org.jclouds.compute.domain; +import org.jclouds.compute.domain.internal.SizeImpl; + +import com.google.inject.ImplementedBy; + /** * Size of a node. * * @author Adrian Cole */ +@ImplementedBy(SizeImpl.class) public interface Size extends Comparable { - + + /** + * unique identifier of this configuration. + */ + String getId(); + /** * Amount of virtual or physical cores provided */ diff --git a/compute/src/main/java/org/jclouds/compute/domain/Template.java b/compute/src/main/java/org/jclouds/compute/domain/Template.java index df14a789a5..51f06a1c05 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Template.java +++ b/compute/src/main/java/org/jclouds/compute/domain/Template.java @@ -24,32 +24,6 @@ package org.jclouds.compute.domain; * @author Adrian Cole */ public interface Template extends Cloneable { - - /** - * configure this template to the smallest size. - */ - Template smallest(); - - /** - * configure this template to the fastest size. - */ - Template fastest(); - - /** - * configure this template to the largest size. - */ - Template biggest(); - - /** - * Configure this template to use a specific operating system image. - */ - Template os(OperatingSystem os); - - /** - * Configure this template to start in a specific location - */ - Template inLocation(String location); - /** * Image that suits the requirements. * diff --git a/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java b/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java new file mode 100644 index 0000000000..b838da926c --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java @@ -0,0 +1,124 @@ +/** + * + * Copyright (C) 2009 Global Cloud Specialists, Inc. + * + * ==================================================================== + * 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; + +import org.jclouds.compute.internal.TemplateBuilderImpl; + +import com.google.inject.ImplementedBy; + +/** + * Creates a customized template based on requirements. + * + * @author Adrian Cole + */ +@ImplementedBy(TemplateBuilderImpl.class) +public interface TemplateBuilder { + /** + * Configure this template to require the minimum size of the parameter. + */ + TemplateBuilder fromSize(Size size); + + /** + * Configure this template to fuzzy-match on the image parameter + */ + TemplateBuilder fromImage(Image image); + + /** + * Configure this template to match the resources of the template parameter. + */ + TemplateBuilder fromTemplate(Template image); + + /** + * configure this template to the smallest size. + */ + TemplateBuilder smallest(); + + /** + * configure this template to the fastest size. + */ + TemplateBuilder fastest(); + + /** + * configure this template to the largest size. + */ + TemplateBuilder biggest(); + + /** + * Configure this template to use a specific operating system image. + */ + TemplateBuilder os(OperatingSystem os); + + /** + * Configure this template to start in a specific location + */ + TemplateBuilder location(String location); + + /** + * Configure this template to require a specific architecture + */ + TemplateBuilder architecture(Architecture architecture); + + /** + * Configure this template to require a specific imageId. + *

+ * Note that image Ids are often scoped to {@code location} + */ + TemplateBuilder imageId(String imageId); + + /** + * Configure this template to require a specific sizeId. + */ + TemplateBuilder sizeId(String sizeId); + + /** + * Configure this template to have an operating system version that matches the regular + * expression + */ + TemplateBuilder osVersionMatches(String osVersionRegex); + + /** + * Configure this template to have an image version that matches the regular expression + */ + TemplateBuilder imageVersionMatches(String imageVersionRegex); + + /** + * Configure this template to have a description that matches the regular expression + */ + TemplateBuilder imageDescriptionMatches(String descriptionRegex); + + /** + * Configure this template to require the minimum cores below + */ + TemplateBuilder minCores(int minCores); + + /** + * Configure this template to require the minimum ram in megabytes below + */ + TemplateBuilder minRam(int megabytes); + + /** + * Generate an immutable template from the current builder. + */ + Template build(); +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/ImageImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/ImageImpl.java index 3d9502fa6b..5a7af607e4 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/ImageImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/ImageImpl.java @@ -34,21 +34,12 @@ public class ImageImpl implements Image { private final String id; private final String description; - private final OperatingSystem operatingSystem; private final String version; + private final OperatingSystem operatingSystem; + private final String operatingSystemVersion; private final String location; private final Architecture architecture; - public ImageImpl(String id, String description, OperatingSystem operatingSystem, String version, - String location, Architecture architecture) { - this.id = id; - this.description = description; - this.operatingSystem = operatingSystem; - this.version = version; - this.location = location; - this.architecture = architecture; - } - /** * {@inheritDoc} */ @@ -65,6 +56,17 @@ public class ImageImpl implements Image { return result; } + public ImageImpl(String id, String description, String version, OperatingSystem operatingSystem, + String operatingSystemVersion, String location, Architecture architecture) { + this.id = id; + this.description = description; + this.version = version; + this.operatingSystem = operatingSystem; + this.operatingSystemVersion = operatingSystemVersion; + this.location = location; + this.architecture = architecture; + } + /** * {@inheritDoc} */ @@ -110,14 +112,12 @@ public class ImageImpl implements Image { return true; } - /** - * {@inheritDoc} - */ @Override public String toString() { - return "ImageImpl [architecture=" + architecture + ", description=" + description + ", id=" - + id + ", location=" + location + ", operatingSystem=" + operatingSystem - + ", version=" + version + "]"; + return "[id=" + id + ", version=" + version + ", location=" + location + ", architecture=" + + architecture + ", operatingSystem=" + operatingSystem + + ", operatingSystemVersion=" + operatingSystemVersion + ", description=" + + description + "]"; } /** @@ -168,4 +168,12 @@ public class ImageImpl implements Image { return architecture; } + /** + * {@inheritDoc} + */ + @Override + public String getOperatingSystemVersion() { + return operatingSystemVersion; + } + } diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/SizeImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/SizeImpl.java index 534879d0b5..ef1637ec1d 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/SizeImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/SizeImpl.java @@ -31,13 +31,15 @@ import com.google.common.collect.Sets; * @author Adrian Cole */ public class SizeImpl implements Size { - + private String id; private final int cores; private final int ram; private final int disk; private final Set supportedArchitectures = Sets.newHashSet(); - public SizeImpl(int cores, int ram, int disk, Iterable supportedArchitectures) { + public SizeImpl(String id, int cores, int ram, int disk, + Iterable supportedArchitectures) { + this.id = id; this.cores = cores; this.ram = ram; this.disk = disk; @@ -74,6 +76,7 @@ public class SizeImpl implements Size { int result = 1; result = prime * result + cores; result = prime * result + disk; + result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ram; result = prime * result + ((supportedArchitectures == null) ? 0 : supportedArchitectures.hashCode()); @@ -93,6 +96,11 @@ public class SizeImpl implements Size { return false; if (disk != other.disk) return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; if (ram != other.ram) return false; if (supportedArchitectures == null) { @@ -108,12 +116,10 @@ public class SizeImpl implements Size { this.getRam(), that.getRam()).compare(this.getDisk(), that.getDisk()).result(); } - /** - * {@inheritDoc} - */ @Override public String toString() { - return "Size [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]"; + return "[id=" + id + ", cores=" + cores + ", ram=" + ram + ", disk=" + disk + + ", supportedArchitectures=" + supportedArchitectures + "]"; } /** @@ -123,4 +129,12 @@ public class SizeImpl implements Size { public boolean supportsArchitecture(Architecture architecture) { return supportedArchitectures.contains(architecture); } + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return id; + } } diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateImpl.java new file mode 100644 index 0000000000..f3bed07aaa --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateImpl.java @@ -0,0 +1,103 @@ +/** + * + * Copyright (C) 2009 Global Cloud Specialists, Inc. + * + * ==================================================================== + * 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 org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; + +/** + * + * @author Adrian Cole + */ +public class TemplateImpl implements Template { + + private final Image image; + private final Size size; + + protected TemplateImpl(Image image, Size size) { + this.image = image; + this.size = size; + } + + /** + * {@inheritDoc} + */ + @Override + public Image getImage() { + return image; + } + + /** + * {@inheritDoc} + */ + @Override + public Size getSize() { + return size; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((image == null) ? 0 : image.hashCode()); + result = prime * result + ((size == null) ? 0 : size.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateImpl other = (TemplateImpl) obj; + if (image == null) { + if (other.image != null) + return false; + } else if (!image.equals(other.image)) + return false; + if (size == null) { + if (other.size != null) + return false; + } else if (!size.equals(other.size)) + return false; + return true; + } + + @Override + public String toString() { + return "TemplateImpl [image=" + image + ", size=" + size + "]"; + } + + /** + * {@inheritDoc} + */ + @Override + protected Object clone() throws CloneNotSupportedException { + return new TemplateImpl(image, size); + } +} diff --git a/compute/src/main/java/org/jclouds/compute/internal/TemplateBuilderImpl.java b/compute/src/main/java/org/jclouds/compute/internal/TemplateBuilderImpl.java new file mode 100644 index 0000000000..fc48b8a211 --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/internal/TemplateBuilderImpl.java @@ -0,0 +1,413 @@ +package org.jclouds.compute.internal; + +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; + +import org.jclouds.compute.domain.Architecture; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.domain.internal.TemplateImpl; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.ResourceLocation; +import org.jclouds.logging.Logger; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.ComparisonChain; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Ordering; +import com.google.common.primitives.Ints; + +/** + * + * @author Adrian Cole + */ +@SuppressWarnings("unchecked") +public class TemplateBuilderImpl implements TemplateBuilder { + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final Set images; + private final Set sizes; + private String location; + private OperatingSystem os; + private Architecture arch; + private String imageId; + private String sizeId; + + private String osVersion; + private String imageVersion; + private String imageDescription; + + private int minCores; + private int minRam; + + private boolean biggest; + private boolean fastest; + + @Inject + public TemplateBuilderImpl(@ResourceLocation String location, Set images, + Set sizes) { + this.location = location; + this.images = images; + this.sizes = sizes; + } + + private final Predicate imageIdPredicate = new Predicate() { + @Override + public boolean apply(Image input) { + boolean returnVal = true; + if (imageId != null) { + returnVal = imageId.equals(input.getId()); + // match our input params so that the later predicates pass. + if (returnVal) { + fromImage(input); + } + } + return returnVal; + } + }; + + private final Predicate locationPredicate = new Predicate() { + @Override + public boolean apply(Image input) { + boolean returnVal = true; + if (location != null) + returnVal = location.equals(input.getLocation()); + return returnVal; + } + }; + + private final Predicate osPredicate = new Predicate() { + + @Override + public boolean apply(Image input) { + boolean returnVal = true; + if (os != null) + returnVal = os.equals(input.getOperatingSystem()); + return returnVal; + } + + }; + private final Predicate imageArchPredicate = new Predicate() { + + @Override + public boolean apply(Image input) { + boolean returnVal = true; + if (arch != null) + returnVal = arch.equals(input.getArchitecture()); + return returnVal; + } + + }; + private final Predicate osVersionPredicate = new Predicate() { + @Override + public boolean apply(Image input) { + boolean returnVal = true; + if (osVersion != null) { + if (input.getOperatingSystemVersion() == null) + returnVal = false; + else + returnVal = input.getOperatingSystemVersion().matches(osVersion); + } + return returnVal; + } + }; + 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().matches(imageVersion); + } + return returnVal; + } + }; + 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().matches(imageDescription); + } + return returnVal; + } + }; + + private final Predicate sizeIdPredicate = new Predicate() { + @Override + public boolean apply(Size input) { + boolean returnVal = true; + if (sizeId != null) { + returnVal = sizeId.equals(input.getId()); + // match our input params so that the later predicates pass. + if (returnVal) { + fromSize(input); + } + } + return returnVal; + } + }; + + private final Predicate imagePredicate = Predicates.and(imageIdPredicate, + locationPredicate, osPredicate, imageArchPredicate, osVersionPredicate, + imageVersionPredicate, imageDescriptionPredicate); + + private final Predicate sizeArchPredicate = new Predicate() { + @Override + public boolean apply(Size input) { + boolean returnVal = false; + if (arch != null) + returnVal = input.supportsArchitecture(arch); + return returnVal; + } + }; + + private final Predicate sizeCoresPredicate = new Predicate() { + @Override + public boolean apply(Size input) { + return input.getCores() >= TemplateBuilderImpl.this.minCores; + } + }; + + private final Predicate sizeRamPredicate = new Predicate() { + @Override + public boolean apply(Size input) { + return input.getRam() >= TemplateBuilderImpl.this.minRam; + } + }; + private final Predicate sizePredicate = Predicates.and(sizeIdPredicate, sizeArchPredicate, + sizeCoresPredicate, sizeRamPredicate); + + static final Ordering DEFAULT_SIZE_ORDERING = new Ordering() { + public int compare(Size left, Size right) { + return ComparisonChain.start().compare(left.getCores(), right.getCores()).compare( + left.getRam(), right.getRam()).compare(left.getDisk(), right.getDisk()).result(); + } + }; + static final Ordering BY_CORES_ORDERING = new Ordering() { + public int compare(Size left, Size right) { + return Ints.compare(left.getCores(), right.getCores()); + } + }; + static final Ordering DEFAULT_IMAGE_ORDERING = new Ordering() { + public int compare(Image left, Image right) { + return ComparisonChain.start().compare(left.getOperatingSystemVersion(), + right.getOperatingSystemVersion()).compare(left.getVersion(), right.getVersion()) + .result(); + } + }; + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder fromTemplate(Template template) { + fromSize(template.getSize()); + fromImage(template.getImage()); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder fromSize(Size size) { + this.minCores = size.getCores(); + this.minRam = size.getRam(); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder fromImage(Image image) { + if (image.getLocation() != null) + this.location = image.getLocation(); + if (image.getOperatingSystem() != null) + this.os = image.getOperatingSystem(); + if (image.getOperatingSystemVersion() != null) + this.osVersion = image.getOperatingSystemVersion(); + if (image.getVersion() != null) + this.imageVersion = image.getVersion(); + if (image.getArchitecture() != null) + this.arch = image.getArchitecture(); + 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 location(String location) { + this.location = location; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder os(OperatingSystem os) { + this.os = os; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder architecture(Architecture architecture) { + this.arch = architecture; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public Template build() { + logger.debug(">> searching params(%s)", this); + Image image; + try { + image = DEFAULT_IMAGE_ORDERING.max(Iterables.filter(images, imagePredicate)); + } catch (NoSuchElementException exception) { + throw new NoSuchElementException("image didn't match: " + toString() + "\n" + images); + } + logger.debug("<< matched image(%s)", image); + // ensure we have an architecture matching + this.arch = image.getArchitecture(); + + Ordering sizeOrdering = DEFAULT_SIZE_ORDERING; + if (!biggest) + sizeOrdering = sizeOrdering.reverse(); + if (fastest) + sizeOrdering = Ordering.compound(ImmutableList.of(BY_CORES_ORDERING, sizeOrdering)); + Size size; + try { + size = sizeOrdering.max(Iterables.filter(sizes, sizePredicate)); + } catch (NoSuchElementException exception) { + throw new NoSuchElementException("size didn't match: " + toString() + "\n" + sizes); + } + logger.debug("<< matched size(%s)", size); + return new TemplateImpl(image, size) { + }; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder imageId(String imageId) { + this.imageId = imageId; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder imageDescriptionMatches(String descriptionRegex) { + this.imageDescription = descriptionRegex; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder imageVersionMatches(String imageVersionRegex) { + this.imageVersion = imageVersionRegex; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder minCores(int minCores) { + this.minCores = minCores; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder minRam(int megabytes) { + this.minRam = megabytes; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder osVersionMatches(String osVersionRegex) { + this.osVersion = osVersionRegex; + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public TemplateBuilder sizeId(String sizeId) { + this.sizeId = sizeId; + return this; + } + + @Override + public String toString() { + return "[arch=" + arch + ", biggest=" + biggest + ", fastest=" + fastest + + ", imageDescription=" + imageDescription + ", imageId=" + imageId + + ", imageVersion=" + imageVersion + ", location=" + location + ", minCores=" + + minCores + ", minRam=" + minRam + ", os=" + os + ", osVersion=" + osVersion + + ", sizeId=" + sizeId + "]"; + } + +} diff --git a/compute/src/main/resources/compute.properties b/compute/src/main/resources/compute.properties index 9b3692a9f2..e021ed996f 100644 --- a/compute/src/main/resources/compute.properties +++ b/compute/src/main/resources/compute.properties @@ -23,4 +23,6 @@ terremark.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudProperti hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeServiceContextBuilder hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder ec2.contextbuilder=org.jclouds.aws.ec2.compute.EC2ComputeServiceContextBuilder -ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder \ No newline at end of file +ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder +# example of where to change your endpoint +# ec2.endpoint=https://ec2.us-west-1.amazonaws.com \ No newline at end of file diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index aa99804ee9..190c8a1e3a 100644 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -32,11 +32,13 @@ import java.util.concurrent.TimeoutException; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.CreateNodeResponse; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.options.RunNodeOptions; import org.jclouds.http.HttpResponseException; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -70,7 +72,6 @@ public abstract class BaseComputeServiceLiveTest { abstract public void setServiceDefaults(); protected String service; - protected OperatingSystem testOS; protected SshClient.Factory sshFactory; protected RunNodeOptions options = RunNodeOptions.Builder.openPorts(22); private String nodeName; @@ -81,23 +82,12 @@ public abstract class BaseComputeServiceLiveTest { protected ComputeService client; protected String user; protected String password; + private Template template; @BeforeGroups(groups = { "live" }) public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { - checkNotNull(testOS, "testOS"); nodeName = checkNotNull(service, "service"); - if (canRunScript()) - options.runScript(new ScriptBuilder() - // update add dns and install jdk - .addStatement( - Statements.exec("echo nameserver 208.67.222.222 >> /etc/resolv.conf")) - .addStatement(Statements.exec("apt-get update"))// - .addStatement(Statements.exec("apt-get upgrade -y"))// - .addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))// - .addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))// - .addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))// - .build(OsFamily.UNIX).getBytes()); user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); context = new ComputeServiceContextFactory().createContext(service, user, password, @@ -110,12 +100,14 @@ public abstract class BaseComputeServiceLiveTest { client = context.getComputeService(); } - private boolean canRunScript() { - return testOS == OperatingSystem.UBUNTU || testOS == OperatingSystem.JEOS; + private boolean canRunScript(Template template) { + return template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU + || template.getImage().getOperatingSystem() == OperatingSystem.JEOS; } abstract protected Module getSshModule(); + @Test(enabled = false) public void testCreate() throws Exception { try { client.destroyNode(Iterables.find(client.listNodes(), new Predicate() { @@ -129,7 +121,19 @@ public abstract class BaseComputeServiceLiveTest { } catch (NoSuchElementException e) { } - Template template = client.createTemplateInLocation("default").os(testOS).smallest(); + template = buildTemplate(client.templateBuilder()); + + if (canRunScript(template)) + options.runScript(new ScriptBuilder() + // update add dns and install jdk + .addStatement( + Statements.exec("echo nameserver 208.67.222.222 >> /etc/resolv.conf")) + .addStatement(Statements.exec("apt-get update"))// + .addStatement(Statements.exec("apt-get upgrade -y"))// + .addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))// + .addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))// + .addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))// + .build(OsFamily.UNIX).getBytes()); node = client.runNode(nodeName, template, options); assertNotNull(node.getId()); assertEquals(node.getLoginPort(), 22); @@ -142,7 +146,9 @@ public abstract class BaseComputeServiceLiveTest { sshPing(); } - @Test(dependsOnMethods = "testCreate") + protected abstract Template buildTemplate(TemplateBuilder templateBuilder); + + @Test(enabled = false, dependsOnMethods = "testCreate") public void testGet() throws Exception { NodeMetadata metadata = client.getNodeMetadata(node); assertEquals(metadata.getId(), node.getId()); @@ -153,7 +159,7 @@ public abstract class BaseComputeServiceLiveTest { assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses()); } - public void testList() throws Exception { + public void testListNodes() throws Exception { for (ComputeMetadata node : client.listNodes()) { assert node.getId() != null; assert node.getLocation() != null; @@ -161,9 +167,10 @@ public abstract class BaseComputeServiceLiveTest { } } - public void testListTemplates() throws Exception { - for (Template template : client.listTemplates()) { - assert template.getImage() != null; + public void testListImages() throws Exception { + for (Image image : client.listImages()) { + assert image.getId() != null : image; + assert image.getLocation() != null : image; } } @@ -197,7 +204,7 @@ public abstract class BaseComputeServiceLiveTest { ssh.connect(); ExecResponse hello = ssh.exec("echo hello"); assertEquals(hello.getOutput().trim(), "hello"); - if (canRunScript()) + if (canRunScript(template)) System.out.println(ssh.exec("java -version")); } finally { if (ssh != null) diff --git a/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java b/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java index b7aaf8ad3e..1f3092c378 100644 --- a/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java +++ b/core/src/main/java/org/jclouds/concurrent/ConcurrentUtils.java @@ -18,15 +18,22 @@ */ package org.jclouds.concurrent; +import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import javax.inject.Singleton; +import org.jclouds.logging.Logger; + +import com.google.common.base.Throwables; +import com.google.common.collect.Sets; import com.google.common.util.concurrent.ExecutionList; import com.google.common.util.concurrent.ForwardingFuture; import com.google.common.util.concurrent.ListenableFuture; @@ -38,6 +45,37 @@ import com.google.common.util.concurrent.ListenableFuture; */ @Singleton public class ConcurrentUtils { + + public static void pollResponsesAndLogWhenComplete(int total, String description, Logger logger, + Set> responses) throws InterruptedException, TimeoutException, + ExecutionException { + int complete = 0; + long start = System.currentTimeMillis(); + long timeOut = 180 * 1000; + do { + Set> retries = Sets.newHashSet(); + for (Future future : responses) { + try { + future.get(100, TimeUnit.MILLISECONDS); + complete++; + } catch (ExecutionException e) { + Throwables.propagate(e); + } catch (TimeoutException e) { + retries.add(future); + } + } + responses = Sets.newHashSet(retries); + } while (responses.size() > 0 && System.currentTimeMillis() < start + timeOut); + long duration = System.currentTimeMillis() - start; + if (duration > timeOut) + throw new TimeoutException(String.format("TIMEOUT: %s(%d/%d) rate: %f %s/second", + description, complete, total, ((double) complete) / (duration / 1000.0), + description)); + for (Future future : responses) + future.get(30, TimeUnit.SECONDS); + logger.debug("<< %s(%d)", description, total); + } + /** * Converts an exception into an object, which is useful for transforming to null or false. */ diff --git a/core/src/main/java/org/jclouds/domain/ResourceLocation.java b/core/src/main/java/org/jclouds/domain/ResourceLocation.java new file mode 100644 index 0000000000..ccd9acf8c1 --- /dev/null +++ b/core/src/main/java/org/jclouds/domain/ResourceLocation.java @@ -0,0 +1,21 @@ +package org.jclouds.domain; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +/** + * Related to the location of a resource + * + * @author Adrian Cole + * + */ +@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) +@Qualifier +public @interface ResourceLocation { + +} \ No newline at end of file diff --git a/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeService.java b/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeService.java index ecd63f9ea8..59af5a594f 100644 --- a/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeService.java +++ b/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeService.java @@ -36,12 +36,14 @@ import org.jclouds.compute.ComputeService; import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.CreateNodeResponse; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.options.RunNodeOptions; @@ -145,18 +147,18 @@ public class RimuHostingComputeService implements ComputeService { rhClient.destroyServer(new Long(node.getId())); } - @Override - public Template createTemplateInLocation(String location) { - return null; - } - @Override public SortedSet listSizes() { return null; } @Override - public Set listTemplates() { + public Set listImages() { + return null; + } + + @Override + public TemplateBuilder templateBuilder() { return null; } } diff --git a/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeServiceLiveTest.java b/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeServiceLiveTest.java index 639feaa6a4..7995f849ec 100755 --- a/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeServiceLiveTest.java +++ b/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/RimuHostingComputeServiceLiveTest.java @@ -18,9 +18,11 @@ */ package org.jclouds.rimuhosting.miro.compute; -import static org.jclouds.compute.domain.OperatingSystem.UBUNTU; +import static org.jclouds.compute.domain.OperatingSystem.JEOS; import org.jclouds.compute.BaseComputeServiceLiveTest; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -34,7 +36,10 @@ public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTes @Override public void setServiceDefaults() { service = "rimuhosting"; - testOS = UBUNTU; + } + + protected Template buildTemplate(TemplateBuilder templateBuilder) { + return templateBuilder.os(JEOS).osVersionMatches(".*9.04.*").smallest().build(); } @Override diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index 411614c978..25e0db1f9a 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -92,7 +92,7 @@ - + diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java index 6af124be4b..9403372758 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTaskUtils.java @@ -37,6 +37,7 @@ import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.options.RunNodeOptions; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.ssh.jsch.config.JschSshClientModule; @@ -75,11 +76,11 @@ public class ComputeTaskUtils { try { Properties props = new Properties(); props.putAll(projectProvider.get().getProperties()); - return new ComputeServiceContextFactory().createContext(from, ImmutableSet.of( - (Module) new AntLoggingModule(projectProvider.get(), + return new ComputeServiceContextFactory().createContext(from, + ImmutableSet + .of((Module) new AntLoggingModule(projectProvider.get(), ComputeServiceConstants.COMPUTE_LOGGER), - new JschSshClientModule()), - props); + new JschSshClientModule()), props); } catch (IOException e) { throw new RuntimeException(e); } @@ -90,13 +91,15 @@ public class ComputeTaskUtils { } static Template createTemplateFromElement(NodeElement nodeElement, ComputeService computeService) { - Template template = computeService.createTemplateInLocation(nodeElement.getLocation()); - template.os(OperatingSystem.valueOf(nodeElement.getOs())); - addSizeFromElementToTemplate(nodeElement, template); - return template; + TemplateBuilder templateBuilder = computeService.templateBuilder(); + if (nodeElement.getLocation() != null && !"".equals(nodeElement.getLocation())) + templateBuilder.location(nodeElement.getLocation()); + templateBuilder.os(OperatingSystem.valueOf(nodeElement.getOs())); + addSizeFromElementToTemplate(nodeElement, templateBuilder); + return templateBuilder.build(); } - static void addSizeFromElementToTemplate(NodeElement nodeElement, Template template) { + static void addSizeFromElementToTemplate(NodeElement nodeElement, TemplateBuilder template) { if (nodeElement.getSize().equalsIgnoreCase("smallest")) { template.smallest(); } else if (nodeElement.getSize().equalsIgnoreCase("fastest")) { diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java index 38c5cec677..eb4702db85 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java @@ -34,7 +34,7 @@ public class NodeElement { private String hostproperty; private String idproperty; private String usernameproperty; - private String location = "default"; + private String location; private File runscript; public String getLocation() { diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudComputeService.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudComputeService.java index dfde7d853b..8bd362d51c 100644 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudComputeService.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudComputeService.java @@ -28,7 +28,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.Map; import java.util.Set; -import java.util.SortedSet; import javax.annotation.Resource; import javax.inject.Named; @@ -45,6 +44,7 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.options.RunNodeOptions; @@ -76,9 +76,9 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient protected Logger logger = Logger.NULL; private final VCloudClient client; protected final Provider> images; - protected final Provider> sizes; - private final Provider> templates; - + protected final Provider> sizes; + protected final Provider templateBuilderProvider; + private final Predicate taskTester; @Inject(optional = true) private SshClient.Factory sshFactory; private Predicate socketTester; @@ -90,15 +90,15 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient NodeState.PENDING).build(); @Inject - public VCloudComputeService(VCloudClient client, Provider> images, - Provider> sizes, - Provider> templates, Predicate successTester, - Predicate socketTester) { + public VCloudComputeService(VCloudClient client, + Provider templateBuilderProvider, + Provider> images, Provider> sizes, + Predicate successTester, Predicate socketTester) { this.taskTester = successTester; this.client = client; this.images = images; this.sizes = sizes; - this.templates = templates; + this.templateBuilderProvider = templateBuilderProvider; this.socketTester = socketTester; } @@ -204,22 +204,20 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient } @Override - public Template createTemplateInLocation(String location) { - return new VCloudTemplate(client, images.get(), sizes.get(), location); + public TemplateBuilder templateBuilder() { + return templateBuilderProvider.get(); } @Override - public SortedSet listSizes() { + public Set listSizes() { return sizes.get(); } @Override - public Set listTemplates() { - return templates.get(); + public Set listImages() { + return images.get(); } - private final Predicate taskTester; - public Map start(String vDCId, String name, String templateId, int minCores, int minMegs, Long diskSize, Map properties, int... portsToOpen) { logger diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudTemplate.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudTemplate.java deleted file mode 100644 index 0f3d1cf8c4..0000000000 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/VCloudTemplate.java +++ /dev/null @@ -1,180 +0,0 @@ -package org.jclouds.vcloud.compute; - -import java.util.Set; - -import javax.annotation.Nullable; - -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.domain.Size; -import org.jclouds.compute.domain.Template; -import org.jclouds.vcloud.VCloudClient; - -import com.google.common.collect.Iterables; - -/** - * - * @author Adrian Cole - */ -public class VCloudTemplate implements Template { - private final VCloudClient client; - private final Set images; - private final Set sizes; - private Size size; - private String vDC; - private OperatingSystem operatingSystem; - private transient Image image; - - public VCloudTemplate(VCloudClient client, - Set images, Set sizes, String location, - @Nullable Size size, OperatingSystem operatingSystem, @Nullable Image image) { - this.client = client; - this.images = images; - this.sizes = sizes; - this.vDC = location; - this.image = image != null ? image : resolveTemplate(images, operatingSystem); - this.size = size != null ? size : Iterables.get(sizes, 0); - this.operatingSystem = operatingSystem; - } - - private Image resolveTemplate(Set images, OperatingSystem operatingSystem) { - for (Image image : images) { - if (image.getOperatingSystem() == operatingSystem) - return image; - } - throw new RuntimeException("no configured image matches os: " + operatingSystem); - } - - VCloudTemplate(VCloudClient client, Set images, - Set sizes, String location) { - this(client, images, sizes, location, null, OperatingSystem.CENTOS, null);// note the default - // os - } - - /** - * {@inheritDoc} - */ - @Override - public Size getSize() { - return size; - } - - /** - * {@inheritDoc} - */ - @Override - public Image getImage() { - return image; - } - - /** - * {@inheritDoc} - */ - @Override - public Template smallest() { - this.size = Iterables.get(sizes, 0); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Template biggest() { - this.size = Iterables.getLast(sizes); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Template fastest() { - this.size = Iterables.getLast(sizes); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Template inLocation(String location) { - if (location.equalsIgnoreCase("default")) - location = client.getDefaultVDC().getId(); - this.vDC = location;// TODO match vdc on template as well arch - return this; - } - - /** - * {@inheritDoc} - */ - @Override - public Template os(OperatingSystem os) { - this.operatingSystem = os; - this.image = resolveTemplate(images, operatingSystem); - return this; - } - - /** - * {@inheritDoc} - */ - @Override - protected Object clone() throws CloneNotSupportedException { - return new VCloudTemplate(client, images, sizes, vDC, size, operatingSystem, - image); - } - - public String getvDC() { - return vDC; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((image == null) ? 0 : image.hashCode()); - result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode()); - result = prime * result + ((size == null) ? 0 : size.hashCode()); - result = prime * result + ((vDC == null) ? 0 : vDC.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - VCloudTemplate other = (VCloudTemplate) obj; - if (image == null) { - if (other.image != null) - return false; - } else if (!image.equals(other.image)) - return false; - if (operatingSystem == null) { - if (other.operatingSystem != null) - return false; - } else if (!operatingSystem.equals(other.operatingSystem)) - return false; - if (size == null) { - if (other.size != null) - return false; - } else if (!size.equals(other.size)) - return false; - if (vDC == null) { - if (other.vDC != null) - return false; - } else if (!vDC.equals(other.vDC)) - return false; - return true; - } - - @Override - public String toString() { - return "VCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem - + ", size=" + size + ", vDC=" + vDC + "]"; - } - -} diff --git a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java index 06c13d6606..45e1fd271d 100755 --- a/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java +++ b/vcloud/core/src/main/java/org/jclouds/vcloud/compute/config/VCloudComputeServiceContextModule.java @@ -19,12 +19,10 @@ package org.jclouds.vcloud.compute.config; import java.util.Set; -import java.util.SortedSet; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import javax.annotation.Resource; @@ -41,6 +39,8 @@ import org.jclouds.compute.domain.internal.ImageImpl; import org.jclouds.compute.domain.internal.SizeImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.concurrent.ConcurrentUtils; +import org.jclouds.domain.ResourceLocation; import org.jclouds.logging.Logger; import org.jclouds.rest.RestContext; import org.jclouds.vcloud.VCloudAsyncClient; @@ -48,16 +48,13 @@ import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudMediaType; import org.jclouds.vcloud.compute.VCloudComputeClient; import org.jclouds.vcloud.compute.VCloudComputeService; -import org.jclouds.vcloud.compute.VCloudTemplate; import org.jclouds.vcloud.config.VCloudContextModule; import org.jclouds.vcloud.domain.Catalog; import org.jclouds.vcloud.domain.CatalogItem; import org.jclouds.vcloud.domain.NamedResource; import org.jclouds.vcloud.domain.VAppTemplate; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Sets; import com.google.inject.Injector; import com.google.inject.Provides; @@ -93,6 +90,13 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule { return new ComputeServiceContextImpl(computeService, context); } + @Provides + @Singleton + @ResourceLocation + String getVDC(VCloudClient client) { + return client.getDefaultVDC().getId(); + } + protected static class LogHolder { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -101,13 +105,12 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule { @Provides @Singleton - protected Set provideImages(final VCloudClient client, LogHolder holder, - ExecutorService executor) throws InterruptedException, ExecutionException, - TimeoutException { + protected Set provideImages(final VCloudClient client, + final @ResourceLocation String vDC, LogHolder holder, ExecutorService executor) + throws InterruptedException, ExecutionException, TimeoutException { final Set images = Sets.newHashSet(); holder.logger.debug(">> providing images"); Catalog response = client.getDefaultCatalog(); - final String vDC = client.getDefaultVDC().getId(); Set> responses = Sets.newHashSet(); for (final NamedResource resource : response.values()) { @@ -117,9 +120,9 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule { responses.add(executor.submit(new Callable() { @Override public Void call() throws Exception { - OperatingSystem myOs = OperatingSystem.UNKNOWN; + OperatingSystem myOs = null; for (OperatingSystem os : OperatingSystem.values()) { - if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf( + if (resource.getName().toLowerCase().replaceAll("\\s", "").indexOf( os.toString()) != -1) { myOs = os; } @@ -127,73 +130,31 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule { Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32 : Architecture.X86_64; VAppTemplate template = client.getVAppTemplate(item.getEntity().getId()); - images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, - null, vDC, arch)); + images.add(new ImageImpl(resource.getId(), template.getName(), "", myOs, + template.getName(), vDC, arch)); return null; } })); } } } - pollResponsesAndLogWhenComplete(images.size(), "images", holder, responses); + ConcurrentUtils.pollResponsesAndLogWhenComplete(images.size(), "images", holder.logger, + responses); return images; } - protected void pollResponsesAndLogWhenComplete(int total, String description, LogHolder holder, - Set> responses) throws InterruptedException, TimeoutException, - ExecutionException { - int complete = 0; - long start = System.currentTimeMillis(); - long timeOut = 60 * 1000; - do { - Set> retries = Sets.newHashSet(); - for (Future future : responses) { - try { - future.get(100, TimeUnit.MILLISECONDS); - complete++; - } catch (ExecutionException e) { - Throwables.propagate(e); - } catch (TimeoutException e) { - retries.add(future); - } - } - responses = Sets.newHashSet(retries); - } while (responses.size() > 0 && System.currentTimeMillis() < start + timeOut); - long duration = System.currentTimeMillis() - start; - if (duration > timeOut) - throw new TimeoutException(String.format("TIMEOUT: %s(%d/%d) rate: %f %s/second%n", - description, complete, total, ((double) complete) / (duration / 1000.0), - description)); - for (Future future : responses) - future.get(30, TimeUnit.SECONDS); - holder.logger.debug("<< %s(%d) rate: %f %s/second%n", description, total, ((double) complete) - / (duration / 1000.0), description); - } - @Provides @Singleton - protected SortedSet provideSizes(VCloudClient client, - Set images, LogHolder holder, ExecutorService executor) - throws InterruptedException, TimeoutException, ExecutionException { - return ImmutableSortedSet.of(new SizeImpl(1, 512, 10, ImmutableSet. of( - Architecture.X86_32, Architecture.X86_64))); - } - - @Provides - @Singleton - protected Set provideTemplates(VCloudClient client, - Set images, SortedSet sizes, LogHolder holder) { - Set templates = Sets.newHashSet(); - holder.logger.debug(">> generating templates"); - String vDC = client.getDefaultVDC().getId(); - for (Size size : sizes) { - for (Image image : images) { - templates.add(new VCloudTemplate(client, images, sizes, vDC, size, image - .getOperatingSystem(), image)); - } - } - holder.logger.debug("<< templates(%d)", templates.size()); - return templates; + protected Set provideSizes(VCloudClient client, Set images, + LogHolder holder, ExecutorService executor) throws InterruptedException, + TimeoutException, ExecutionException { + Set sizes = Sets.newHashSet(); + for (int cpus : new int[] { 1, 2, 4 }) + for (int ram : new int[] { 512, 1024, 2048, 4096, 8192, 16384 }) + sizes.add(new SizeImpl(String.format("cpu=%d,ram=%s,disk=%d", cpus, ram, 10), cpus, + ram, 10, ImmutableSet. of(Architecture.X86_32, + Architecture.X86_64))); + return sizes; } } diff --git a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeService.java b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeService.java index bfada2ca3b..341669f76b 100644 --- a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeService.java +++ b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeService.java @@ -5,7 +5,6 @@ import static com.google.common.base.Preconditions.checkState; import java.net.InetSocketAddress; import java.util.Map; import java.util.Set; -import java.util.SortedSet; import javax.inject.Inject; import javax.inject.Provider; @@ -13,9 +12,9 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.compute.VCloudComputeService; -import org.jclouds.vcloud.compute.VCloudTemplate; import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.hostingdotcom.domain.HostingDotComVApp; @@ -29,11 +28,11 @@ import com.google.common.collect.ImmutableMap; public class HostingDotComVCloudComputeService extends VCloudComputeService { @Inject - public HostingDotComVCloudComputeService(VCloudClient client, - Provider> images, Provider> sizes, - Provider> templates, Predicate successTester, - Predicate socketTester) { - super(client, images, sizes, templates, successTester, socketTester); + HostingDotComVCloudComputeService(VCloudClient client, + Provider templateBuilderProvider, + Provider> images, Provider> sizes, + Predicate successTester, Predicate socketTester) { + super(client, templateBuilderProvider, images, sizes, successTester, socketTester); } @Override diff --git a/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeServiceLiveTest.java b/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeServiceLiveTest.java index 03b2d78b78..3c2c1ea73f 100644 --- a/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeServiceLiveTest.java +++ b/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeServiceLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.vcloud.hostingdotcom.compute; import static org.jclouds.compute.domain.OperatingSystem.CENTOS; import org.jclouds.compute.BaseComputeServiceLiveTest; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -37,7 +39,10 @@ public class HostingDotComVCloudComputeServiceLiveTest extends BaseComputeServic @Override public void setServiceDefaults() { service = "hostingdotcom"; - testOS = CENTOS; + } + + protected Template buildTemplate(TemplateBuilder templateBuilder) { + return templateBuilder.os(CENTOS).smallest().build(); } @Override diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java index 59681f104b..e7ebfac5db 100644 --- a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java @@ -34,10 +34,10 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; import org.jclouds.vcloud.compute.VCloudComputeService; -import org.jclouds.vcloud.compute.VCloudTemplate; import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.terremark.TerremarkVCloudClient; import org.jclouds.vcloud.terremark.domain.InternetService; @@ -62,10 +62,10 @@ public class TerremarkVCloudComputeService extends VCloudComputeService { @Inject public TerremarkVCloudComputeService(TerremarkVCloudClient client, - Provider> images, Provider> sizes, - Provider> templates, Predicate successTester, - Predicate socketTester) { - super(client, images, sizes, templates, successTester, socketTester); + Provider templateBuilderProvider, + Provider> images, Provider> sizes, + Predicate successTester, Predicate socketTester) { + super(client, templateBuilderProvider, images, sizes, successTester, socketTester); this.client = client; } diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java index 2ce1b48aed..edbfc751ef 100755 --- a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkVCloudComputeServiceContextModule.java @@ -62,8 +62,8 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer private static class ComputeOptionsToSize implements Function { @Override public Size apply(ComputeOptions from) { - return new SizeImpl(from.getProcessorCount(), from.getMemory(), 10, ImmutableSet - . of(Architecture.X86_32, Architecture.X86_64)); + return new SizeImpl(from.toString(), from.getProcessorCount(), from.getMemory(), 10, + ImmutableSet. of(Architecture.X86_32, Architecture.X86_64)); } } diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeServiceLiveTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeServiceLiveTest.java index 42d2a20506..fc72d54bc1 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeServiceLiveTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeServiceLiveTest.java @@ -23,6 +23,8 @@ import static org.jclouds.compute.domain.OperatingSystem.JEOS; import org.jclouds.compute.BaseComputeServiceLiveTest; import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.rest.RestContext; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.vcloud.compute.VCloudComputeClient; @@ -39,11 +41,15 @@ import org.testng.annotations.Test; */ @Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest") public class TerremarkVCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest { + @BeforeClass @Override public void setServiceDefaults() { service = "terremark"; - testOS = JEOS; + } + + protected Template buildTemplate(TemplateBuilder templateBuilder) { + return templateBuilder.os(JEOS).osVersionMatches(".*9.04.*").smallest().build(); } @Override @@ -55,10 +61,10 @@ public class TerremarkVCloudComputeServiceLiveTest extends BaseComputeServiceLiv @SuppressWarnings("unused") RestContext tmContext = new ComputeServiceContextFactory() .createContext(service, user, password).getProviderSpecificContext(); - + TerremarkVCloudComputeService computeService = TerremarkVCloudComputeService.class .cast(client); - + @SuppressWarnings("unused") VCloudComputeClient computeClient = VCloudComputeClient.class.cast(computeService); }