From 2e213ae223a2880385e588cd90950faa91ee836d Mon Sep 17 00:00:00 2001 From: "adrian.f.cole" Date: Wed, 20 Jan 2010 11:34:24 +0000 Subject: [PATCH] Issue 130: properly modeled node and templates git-svn-id: http://jclouds.googlecode.com/svn/trunk@2702 3d8758e0-26b5-11de-8745-db77d3ebf521 --- .../aws/ec2/compute/EC2ComputeService.java | 131 +++++----- .../org/jclouds/aws/ec2/compute/EC2Size.java | 88 +++++++ .../jclouds/aws/ec2/compute/EC2Template.java | 233 ++++++++++++++++++ .../EC2ComputeServiceContextModule.java | 75 ++++++ .../org/jclouds/aws/ec2/util/EC2Utils.java | 17 +- .../compute/EC2ComputeServiceLiveTest.java | 37 ++- aws/core/src/test/resources/log4j.xml | 32 +++ .../org/jclouds/compute/ComputeService.java | 27 +- .../{Image.java.new => Architecture.java} | 24 +- .../org/jclouds/compute/domain/Image.java | 63 ++++- ...{Profile.java.new => OperatingSystem.java} | 9 +- .../java/org/jclouds/compute/domain/Size.java | 59 ++--- .../domain/{Profile.java => Template.java} | 42 +++- .../compute/domain/internal/ImageImpl.java | 171 +++++++++++++ .../compute/domain/internal/SizeImpl.java | 138 +++++++++++ .../jclouds/compute/util/ComputeUtils.java | 2 +- .../compute/RimuHostingComputeService.java | 35 ++- .../RimuHostingComputeServiceLiveTest.java | 110 +++------ .../antcontrib/samples/cargooverssh/build.xml | 2 +- tools/antcontrib/samples/compute/build.xml | 4 +- .../ant/taskdefs/compute/ComputeTask.java | 29 ++- .../ant/taskdefs/compute/NodeElement.java | 36 +-- .../jclouds/vcloud/VCloudComputeClient.java | 22 +- .../vcloud/VCloudComputeClientLiveTest.java | 29 +-- .../HostingDotComVCloudComputeClient.java | 30 +-- .../HostingDotComVCloudComputeService.java | 57 +++-- .../compute/HostingDotComVCloudTemplate.java | 180 ++++++++++++++ ...tComVCloudComputeServiceContextModule.java | 88 ++++++- ...tingDotComVCloudComputeClientLiveTest.java | 23 +- ...ingDotComVCloudComputeServiceLiveTest.java | 47 +++- .../src/test/resources/log4j.xml | 159 ++++++------ .../compute/TerremarkVCloudComputeClient.java | 18 +- .../TerremarkVCloudComputeService.java | 42 +++- .../compute/TerremarkVCloudTemplate.java | 178 +++++++++++++ ...markVCloudComputeServiceContextModule.java | 103 ++++++++ .../TerremarkVCloudComputeClientLiveTest.java | 25 +- ...TerremarkVCloudComputeServiceLiveTest.java | 48 +++- vcloud/terremark/src/test/resources/log4j.xml | 31 +++ 38 files changed, 1936 insertions(+), 508 deletions(-) create mode 100644 aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Size.java create mode 100644 aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Template.java rename compute/src/main/java/org/jclouds/compute/domain/{Image.java.new => Architecture.java} (70%) rename compute/src/main/java/org/jclouds/compute/domain/{Profile.java.new => OperatingSystem.java} (84%) rename compute/src/main/java/org/jclouds/compute/domain/{Profile.java => Template.java} (52%) create mode 100644 compute/src/main/java/org/jclouds/compute/domain/internal/ImageImpl.java create mode 100644 compute/src/main/java/org/jclouds/compute/domain/internal/SizeImpl.java create mode 100644 vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudTemplate.java create mode 100644 vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplate.java 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 f4ef159819..4b9861e299 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 @@ -24,7 +24,6 @@ import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyNam import static org.jclouds.scriptbuilder.domain.Statements.exec; import java.net.InetAddress; -import java.util.Arrays; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; @@ -32,26 +31,26 @@ import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.domain.Region; import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.domain.InstanceState; -import org.jclouds.aws.ec2.domain.InstanceType; import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.RunningInstance; 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.Profile; -import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl; @@ -62,7 +61,6 @@ import org.jclouds.scriptbuilder.ScriptBuilder; import org.jclouds.scriptbuilder.domain.OsFamily; import com.google.common.base.Function; -import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -78,67 +76,40 @@ public class EC2ComputeService implements ComputeService { @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; private final EC2Client ec2Client; + private final Set sizes; + private final Provider> templates; private final Predicate instanceStateRunning; private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata; + private final Map>> imageAmiIdMap; @Inject - public EC2ComputeService(EC2Client tmClient, Predicate instanceStateRunning, + public EC2ComputeService(EC2Client client, Set sizes, + Provider> templates, + Map>> imageAmiIdMap, + Predicate instanceStateRunning, RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) { - this.ec2Client = tmClient; + this.ec2Client = client; + this.sizes = sizes; + this.templates = templates; // delayed intentionally, as generation is slow + this.imageAmiIdMap = imageAmiIdMap; this.instanceStateRunning = instanceStateRunning; this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata; } - private Map>> imageAmiIdMap = ImmutableMap - .>> of(InstanceType.M1_SMALL,// - ImmutableMap.> builder().put( - Image.UBUNTU_90, - 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( - Image.RHEL_53, - ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1, - "ami-368b685f")).build(),// - InstanceType.C1_MEDIUM,// - ImmutableMap.> builder().put( - Image.UBUNTU_90, - 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( - Image.RHEL_53, - ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1, - "ami-368b685f")).build(), // - InstanceType.C1_XLARGE,// - ImmutableMap.> builder().put( - Image.UBUNTU_90, - 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 - - private Map profileInstanceTypeMap = ImmutableMap - . builder().put(Profile.SMALLEST, InstanceType.M1_SMALL).put( - Profile.MEDIUM, InstanceType.C1_MEDIUM).put(Profile.FASTEST, - InstanceType.C1_XLARGE).build(); - private static Map instanceToNodeState = ImmutableMap . builder().put(InstanceState.PENDING, NodeState.PENDING) .put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN, NodeState.PENDING).put(InstanceState.TERMINATED, NodeState.TERMINATED).build(); @Override - public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, - Image image) { - Region region = Region.fromValue(location); + public CreateNodeResponse runNode(String name, Template template) { + checkArgument(template instanceof EC2Template, + "unexpected template type. should be EC2Template, was: " + template.getClass()); + EC2Template ec2Template = (EC2Template) template; - InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile), - "profile not supported: " + profile); - String ami = checkNotNull(checkNotNull( - checkNotNull(imageAmiIdMap.get(type), "type not supported: " + type).get(image), - "image not supported: " + image).get(region), "region not supported: " + region); - - KeyPair keyPair = createKeyPairInRegion(region, name); + KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name); String securityGroupName = name; - createSecurityGroupInRegion(region, securityGroupName, 22, 80, 8080, 443); + createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, 22, 80, 8080, 443); String script = new ScriptBuilder() // update and install jdk .addStatement(exec("apt-get update"))// @@ -149,35 +120,45 @@ public class EC2ComputeService implements ComputeService { .build(OsFamily.UNIX); logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)", - region, ami, type, keyPair.getKeyName(), securityGroupName); + ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize() + .getInstanceType(), keyPair.getKeyName(), securityGroupName); RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices() - .runInstancesInRegion(region, null, ami, 1, 1, withKeyName(keyPair.getKeyName())// key - // I - // created - // above - .asType(type)// instance size - .withSecurityGroup(securityGroupName)// group I created above - .withAdditionalInfo(name)// description - .withUserData(script.getBytes()) // script to run as root + .runInstancesInRegion(ec2Template.getRegion(), null, ec2Template.getImage().getId(), + 1, 1, withKeyName(keyPair.getKeyName())// key + .asType(ec2Template.getSize().getInstanceType())// instance size + .withSecurityGroup(securityGroupName)// group I created above + .withAdditionalInfo(name)// description + .withUserData(script.getBytes()) // script to run as root )); logger.debug("<< started instance(%s)", runningInstance.getId()); instanceStateRunning.apply(runningInstance); logger.debug("<< running instance(%s)", runningInstance.getId()); // refresh to get IP address - runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId()); + runningInstance = getOnlyRunningInstanceInRegion(ec2Template.getRegion(), 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, - LoginType.SSH, new Credentials(image == Image.UBUNTU_90 ? "ubuntu" : "root", keyPair - .getKeyMaterial()), ImmutableMap. of()); + 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()); } private KeyPair createKeyPairInRegion(Region region, String name) { @@ -205,13 +186,13 @@ public class EC2ComputeService implements ComputeService { try { ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name); logger.debug("<< created securityGroup(%s)", name); - logger.debug(">> authorizing securityGroup region(%s) name(%s) ports(%s)", region, name, - Joiner.on(',').join(Arrays.asList(ports))); for (int port : ports) { + logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name, + port); ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, name, IpProtocol.TCP, port, port, "0.0.0.0/0"); + logger.debug("<< authorized securityGroup(%s)", name); } - logger.debug("<< authorized securityGroup(%s)", name); } catch (AWSResponseException e) { if (e.getError().getCode().equals("InvalidGroup.Duplicate")) { logger.debug("<< reused securityGroup(%s)", name); @@ -335,7 +316,17 @@ public class EC2ComputeService implements ComputeService { } @Override - public Map getSizes() { - throw new UnsupportedOperationException(); + public Set listSizes() { + return sizes; + } + + @Override + public Set listTemplates() { + return templates.get(); + } + + @Override + public Template createTemplateInLocation(String location) { + return new EC2Template(ec2Client, imageAmiIdMap, location); } } \ No newline at end of file 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 new file mode 100644 index 0000000000..d32fcb747a --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Size.java @@ -0,0 +1,88 @@ +/** + * + * 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.aws.ec2.domain.InstanceType; +import org.jclouds.compute.domain.Architecture; +import org.jclouds.compute.domain.internal.SizeImpl; + +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +public class EC2Size extends SizeImpl { + private final InstanceType instanceType; + + EC2Size(InstanceType instanceType, Integer cores, Integer ram, Integer disk, + Iterable supportedArchitectures) { + super(cores, ram, disk, supportedArchitectures); + this.instanceType = instanceType; + } + + /** + * Returns the EC2 InstanceType associated with this size. + */ + public InstanceType getInstanceType() { + return instanceType; + } + + /** + * @see InstanceType#M1_SMALL + */ + public static final EC2Size M1_SMALL = new EC2Size(InstanceType.M1_SMALL, 1, 1740, 160, + ImmutableSet.of(Architecture.X86_32)); + /** + * @see InstanceType#M1_LARGE + */ + public static final EC2Size M1_LARGE = new EC2Size(InstanceType.M1_LARGE, 4, 7680, 850, + ImmutableSet.of(Architecture.X86_64)); + /** + * @see InstanceType#M1_XLARGE + */ + public static final EC2Size M1_XLARGE = new EC2Size(InstanceType.M1_XLARGE, 8, 15360, 1690, + ImmutableSet.of(Architecture.X86_64)); + /** + * @see InstanceType#M2_2XLARGE + */ + public static final EC2Size M2_2XLARGE = new EC2Size(InstanceType.M2_2XLARGE, 13, 35020, 850, + ImmutableSet.of(Architecture.X86_64)); + /** + * @see InstanceType#M2_4XLARGE + */ + public static final EC2Size M2_4XLARGE = new EC2Size(InstanceType.M2_4XLARGE, 26, 70041, 1690, + ImmutableSet.of(Architecture.X86_64)); + /** + * @see InstanceType#C1_MEDIUM + */ + public static final EC2Size C1_MEDIUM = new EC2Size(InstanceType.C1_MEDIUM, 5, 1740, 350, + ImmutableSet.of(Architecture.X86_32)); + /** + * @see InstanceType#C1_XLARGE + */ + public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20, 7168, 1690, + ImmutableSet.of(Architecture.X86_64)); + +} 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 new file mode 100644 index 0000000000..11503ee43d --- /dev/null +++ b/aws/core/src/main/java/org/jclouds/aws/ec2/compute/EC2Template.java @@ -0,0 +1,233 @@ +/** + * + * 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 c473bc8974..46deb92f5a 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,17 +18,33 @@ */ package org.jclouds.aws.ec2.compute.config; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Named; import javax.inject.Singleton; +import org.jclouds.aws.domain.Region; 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.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.OperatingSystem; import org.jclouds.compute.internal.ComputeServiceContextImpl; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.logging.Logger; import org.jclouds.rest.RestContext; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import com.google.inject.Provides; /** @@ -51,4 +67,63 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule { return new ComputeServiceContextImpl(computeService, context); } + @Provides + @Singleton + 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); + } + + private static class LogHolder { + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + } + + @Provides + @Singleton + Set provideTemplates(EC2Client client, Set 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; + } + + @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 + } } 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 92e5baf337..54468b31ab 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,16 +20,31 @@ 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) { checkArgument(checkNotNull(input, "input") instanceof String[], @@ -62,7 +77,7 @@ public class EC2Utils { } return null; } - + public static AvailabilityZone findAvailabilityZoneInArgsOrNull(GeneratedHttpRequest gRequest) { for (Object arg : gRequest.getArgs()) { if (arg instanceof AvailabilityZone) { 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 a006228210..8fa8f52c89 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 @@ -19,6 +19,7 @@ package org.jclouds.aws.ec2.compute; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.domain.OperatingSystem.UBUNTU; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; @@ -29,15 +30,16 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; 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.Profile; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.SocketOpen; @@ -61,31 +63,34 @@ import com.google.inject.Injector; */ @Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest") public class EC2ComputeServiceLiveTest { + private static final String service = "ec2"; protected SshClient.Factory sshFactory; - private String nodePrefix = System.getProperty("user.name") + ".ec2serv"; + private String nodeName = System.getProperty("user.name") + service; private RetryablePredicate socketTester; private CreateNodeResponse node; private ComputeServiceContext context; + private ComputeService client; @BeforeGroups(groups = { "live" }) public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); - context = new ComputeServiceContextFactory().createContext("ec2", user, password, + context = new ComputeServiceContextFactory().createContext(service, user, password, ImmutableSet.of(new Log4JLoggingModule()), new Properties()); Injector injector = Guice.createInjector(new JschSshClientModule()); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); injector.injectMembers(socketOpen); // add logger + client = context.getComputeService(); } public void testCreate() throws Exception { - node = context.getComputeService().startNodeInLocation("default", nodePrefix, - Profile.SMALLEST, Image.UBUNTU_90); + Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest(); + node = client.runNode(nodeName, template); assertNotNull(node.getId()); assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginType(), LoginType.SSH); @@ -100,7 +105,7 @@ public class EC2ComputeServiceLiveTest { @Test(dependsOnMethods = "testCreate") public void testGet() throws Exception { - NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); + NodeMetadata metadata = client.getNodeMetadata(node); assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginType(), node.getLoginType()); @@ -110,13 +115,27 @@ public class EC2ComputeServiceLiveTest { } public void testList() throws Exception { - for (ComputeMetadata node : context.getComputeService().listNodes()) { + for (ComputeMetadata node : client.listNodes()) { assert node.getId() != null; assert node.getLocation() != null; assertEquals(node.getType(), ComputeType.NODE); } } + public void testListTemplates() throws Exception { + for (Template template : client.listTemplates()) { + assert template.getImage() != null; + System.out.println(template); + } + } + + public void testListSizes() throws Exception { + for (Size size : client.listSizes()) { + assert size.getCores() != null; + System.out.println(size); + } + } + private void sshPing() throws IOException { try { doCheckKey(); @@ -150,7 +169,7 @@ public class EC2ComputeServiceLiveTest { @AfterTest void cleanup() throws InterruptedException, ExecutionException, TimeoutException { if (node != null) - context.getComputeService().destroyNode(node); + client.destroyNode(node); context.close(); } diff --git a/aws/core/src/test/resources/log4j.xml b/aws/core/src/test/resources/log4j.xml index cc486890e6..2e8beb8d60 100644 --- a/aws/core/src/test/resources/log4j.xml +++ b/aws/core/src/test/resources/log4j.xml @@ -45,6 +45,32 @@ --> + + + + + + + + + + + + + + + + + + + + + + @@ -72,6 +98,12 @@ + + + + + + diff --git a/compute/src/main/java/org/jclouds/compute/ComputeService.java b/compute/src/main/java/org/jclouds/compute/ComputeService.java index 0006b24f29..33e547ac6a 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeService.java @@ -18,15 +18,13 @@ */ package org.jclouds.compute; -import java.util.Map; import java.util.Set; 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.Profile; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; /** * Provides portable access to launching compute instances. @@ -35,23 +33,34 @@ import org.jclouds.compute.domain.Size; * @author Ivan Meredith */ public interface ComputeService { + /** + * Creates a new template in the specified location. + * + * @param location + * where the template is valid for + */ + Template createTemplateInLocation(String location); /** * List all sizes available to the current user */ - Map getSizes(); - + Set listSizes(); + + /** + * List all templates available to the current user + */ + Set listTemplates(); + /** * List all nodes available to the current user */ - Set listNodes(); - + Set listNodes(); /** - * Create a new node given the name, size, and Image + * Create a new node given the name, and template * */ - CreateNodeResponse startNodeInLocation(String location, String name, Profile size, Image image); + CreateNodeResponse runNode(String name, Template template); /** * destroy the node. diff --git a/compute/src/main/java/org/jclouds/compute/domain/Image.java.new b/compute/src/main/java/org/jclouds/compute/domain/Architecture.java similarity index 70% rename from compute/src/main/java/org/jclouds/compute/domain/Image.java.new rename to compute/src/main/java/org/jclouds/compute/domain/Architecture.java index 20d328ef5e..7f711c6220 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Image.java.new +++ b/compute/src/main/java/org/jclouds/compute/domain/Architecture.java @@ -1,6 +1,6 @@ /** * - * Copyright (C) 2009 Cloud Conscious, LLC. + * Copyright (C) 2009 Global Cloud Specialists, Inc. * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one @@ -23,29 +23,19 @@ */ package org.jclouds.compute.domain; -import java.util.Map; - /** - * Configured operating system used to start nodes. + * Architecture of a node * * @author Adrian Cole */ -public interface Image { - /** - * Unique ID provided by the provider (ami-abcd1234, etc) - * - */ - String getId(); +public enum Architecture { /** - * Name provided by the provider (Ubuntu 8.1) - * + * 32-bit platform */ - String getName(); - + X86_32, /** - * Other variables present that the provider supports + * 64-bit platform */ - Map getExtra(); - + X86_64; } \ No newline at end of file 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 5badf92528..d951dc70a7 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Image.java +++ b/compute/src/main/java/org/jclouds/compute/domain/Image.java @@ -1,26 +1,63 @@ /** * - * Copyright (C) 2009 Cloud Conscious, LLC. + * Copyright (C) 2009 Global Cloud Specialists, Inc. * * ==================================================================== - * Licensed 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 + * 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 + * 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. + * 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; /** + * Running Operating system + * * @author Adrian Cole */ -public enum Image { - CENTOS_53, RHEL_53, UBUNTU_90, UBUNTU_JEOS_90, WEBAPPVM_93 -} +public interface Image { + + /** + * Unique ID provided by the provider (ami-abcd1234, etc) + * + */ + String getId(); + + /** + * Description of the image + */ + String getDescription(); + + /** + * Operating System + */ + OperatingSystem getOperatingSystem(); + + /** + * Version of the image + */ + String getVersion(); + + /** + * Geographic location of the image. + */ + String getLocation(); + + /** + * Operating System + */ + Architecture getArchitecture(); +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/domain/Profile.java.new b/compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java similarity index 84% rename from compute/src/main/java/org/jclouds/compute/domain/Profile.java.new rename to compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java index 022826fcef..c6eee06b60 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Profile.java.new +++ b/compute/src/main/java/org/jclouds/compute/domain/OperatingSystem.java @@ -1,6 +1,6 @@ /** * - * Copyright (C) 2009 Cloud Conscious, LLC. + * Copyright (C) 2009 Global Cloud Specialists, Inc. * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one @@ -24,10 +24,11 @@ package org.jclouds.compute.domain; /** + * Running Operating system + * * @author Adrian Cole */ -public interface Profile { - Image getImage(); +public enum OperatingSystem { - Size getSize(); + CENTOS, RHEL, UBUNTU, WINDOWS, UNKNOWN; } \ 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 c07f6bfefa..29eab0597c 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Size.java +++ b/compute/src/main/java/org/jclouds/compute/domain/Size.java @@ -1,40 +1,34 @@ /** * - * Copyright (C) 2009 Cloud Conscious, LLC. + * Copyright (C) 2009 Global Cloud Specialists, Inc. * * ==================================================================== - * Licensed 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 + * 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 + * 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. + * 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 java.util.Map; - /** - * Configured operating system used to start nodes. + * Size of a node. * * @author Adrian Cole */ -public interface Size { - /** - * provider-specific identifier (m1.small, etc) - */ - String getId(); - - /** - * Name provided by the provider (Small CPU, etc) - */ - String getName(); +public interface Size extends Comparable { /** * Amount of virtual or physical cores provided @@ -44,26 +38,15 @@ public interface Size { /** * Amount of RAM provided in MB (256M, 1740) */ - Long getRam(); + Integer getRam(); /** * Amount of boot disk provided in GB (200) */ - Long getDisk(); + Integer getDisk(); /** - * Amount of total transfer bandwidth in GB + * Determines platforms this can support */ - Long getBandwidth(); - - /** - * Hourly price of this server in USD, estimated if monthly. - */ - Float getPrice(); - - /** - * Other variables present that the provider supports - */ - Map getExtra(); - + boolean supportsArchitecture(Architecture architecture); } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/domain/Profile.java b/compute/src/main/java/org/jclouds/compute/domain/Template.java similarity index 52% rename from compute/src/main/java/org/jclouds/compute/domain/Profile.java rename to compute/src/main/java/org/jclouds/compute/domain/Template.java index 7066cb2adb..df14a789a5 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/Profile.java +++ b/compute/src/main/java/org/jclouds/compute/domain/Template.java @@ -19,8 +19,46 @@ package org.jclouds.compute.domain; /** + * Configured operating system used to start nodes. + * * @author Adrian Cole */ -public enum Profile { - SMALLEST, MEDIUM, FASTEST +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. + * + */ + Image getImage(); + + /** + * Size that suits the requirements. + */ + Size getSize(); + } \ 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 new file mode 100644 index 0000000000..3d9502fa6b --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/ImageImpl.java @@ -0,0 +1,171 @@ +/** + * + * 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.Architecture; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; + +/** + * @author Adrian Cole + */ +public class ImageImpl implements Image { + + private final String id; + private final String description; + private final OperatingSystem operatingSystem; + private final String version; + 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} + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((architecture == null) ? 0 : architecture.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((location == null) ? 0 : location.hashCode()); + result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode()); + result = prime * result + ((version == null) ? 0 : version.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; + ImageImpl other = (ImageImpl) obj; + if (architecture == null) { + if (other.architecture != null) + return false; + } else if (!architecture.equals(other.architecture)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (location == null) { + if (other.location != null) + return false; + } else if (!location.equals(other.location)) + return false; + if (operatingSystem == null) { + if (other.operatingSystem != null) + return false; + } else if (!operatingSystem.equals(other.operatingSystem)) + return false; + if (version == null) { + if (other.version != null) + return false; + } else if (!version.equals(other.version)) + return false; + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "ImageImpl [architecture=" + architecture + ", description=" + description + ", id=" + + id + ", location=" + location + ", operatingSystem=" + operatingSystem + + ", version=" + version + "]"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return id; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDescription() { + return description; + } + + /** + * {@inheritDoc} + */ + @Override + public OperatingSystem getOperatingSystem() { + return operatingSystem; + } + + /** + * {@inheritDoc} + */ + @Override + public String getVersion() { + return version; + } + + /** + * {@inheritDoc} + */ + @Override + public String getLocation() { + return location; + } + + /** + * {@inheritDoc} + */ + @Override + public Architecture getArchitecture() { + return architecture; + } + +} 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 new file mode 100644 index 0000000000..9f70849150 --- /dev/null +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/SizeImpl.java @@ -0,0 +1,138 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed 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 java.util.Set; + +import org.jclouds.compute.domain.Architecture; +import org.jclouds.compute.domain.Size; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; + +/** + * @author Adrian Cole + */ +public class SizeImpl implements Size { + + private final Integer cores; + private final Integer ram; + private final Integer disk; + private final Set supportedArchitectures = Sets.newHashSet(); + + public SizeImpl(Integer cores, Integer ram, Integer disk, + Iterable supportedArchitectures) { + this.cores = cores; + this.ram = ram; + this.disk = disk; + Iterables.addAll(this.supportedArchitectures, supportedArchitectures); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer getCores() { + return cores; + } + + /** + * {@inheritDoc} + */ + @Override + public Integer getRam() { + return ram; + } + + /** + * {@inheritDoc} + */ + @Override + public Integer getDisk() { + return disk; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((cores == null) ? 0 : cores.hashCode()); + result = prime * result + ((disk == null) ? 0 : disk.hashCode()); + result = prime * result + ((ram == null) ? 0 : ram.hashCode()); + result = prime * result + + ((supportedArchitectures == null) ? 0 : supportedArchitectures.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; + SizeImpl other = (SizeImpl) obj; + if (cores == null) { + if (other.cores != null) + return false; + } else if (!cores.equals(other.cores)) + return false; + if (disk == null) { + if (other.disk != null) + return false; + } else if (!disk.equals(other.disk)) + return false; + if (ram == null) { + if (other.ram != null) + return false; + } else if (!ram.equals(other.ram)) + return false; + if (supportedArchitectures == null) { + if (other.supportedArchitectures != null) + return false; + } else if (!supportedArchitectures.equals(other.supportedArchitectures)) + return false; + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "SizeImpl [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]"; + } + + /** + * {@inheritDoc} + */ + @Override + public int compareTo(Size o) { + return (this == o) ? 0 : getCores().compareTo(o.getCores()); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean supportsArchitecture(Architecture architecture) { + return supportedArchitectures.contains(architecture); + } +} diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java index 89e40e4f62..a1e3b3cd2e 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java +++ b/compute/src/main/java/org/jclouds/compute/util/ComputeUtils.java @@ -28,7 +28,7 @@ import com.google.common.collect.Iterables; * @author Adrian Cole */ public class ComputeUtils { - public static Iterable filterByName(Iterable nodes, + public static Iterable filterByName(Iterable nodes, final String name) { return Iterables.filter(nodes, new Predicate() { @Override 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 a08a9eef1f..b12d786e64 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 @@ -35,12 +35,12 @@ 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.Profile; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.reference.ComputeServiceConstants; @@ -73,17 +73,18 @@ public class RimuHostingComputeService implements ComputeService { this.rhClient = rhClient; } - private Map imageNameMap = ImmutableMap. builder().put( - Image.CENTOS_53, "centos53").put(Image.UBUNTU_90, "ubuntu904").build(); - private Map profileNameMap = ImmutableMap. builder().put( - Profile.SMALLEST, "MIRO1B").build(); + private Map imageNameMap = ImmutableMap + . builder().put(OperatingSystem.CENTOS, "centos53").put( + OperatingSystem.UBUNTU, "ubuntu904").build(); + + // private Map profileNameMap = ImmutableMap. builder().put( + // Profile.SMALLEST, "MIRO1B").build(); @Override - public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, - Image image) { + public CreateNodeResponse runNode(String name, Template template) { NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap - .get(image), "image not supported: " + image), checkNotNull(profileNameMap - .get(profile), "profile not supported: " + profile)); + .get(template.getImage().getOperatingSystem()), "os not supported: " + + template.getImage().getOperatingSystem()), "MIRO1B"); return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(), serverResponse.getServer().getName(), "default", null, ImmutableMap . of(), @@ -138,7 +139,17 @@ public class RimuHostingComputeService implements ComputeService { } @Override - public Map getSizes() { + public Template createTemplateInLocation(String location) { return null; } -} \ No newline at end of file + + @Override + public Set listSizes() { + return null; + } + + @Override + public Set listTemplates() { + 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 d646ef0f27..b73a07ca20 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 @@ -19,37 +19,30 @@ package org.jclouds.rimuhosting.miro.compute; import static com.google.common.base.Preconditions.checkNotNull; -import static org.easymock.EasyMock.expect; -import static org.easymock.classextension.EasyMock.createMock; -import static org.easymock.classextension.EasyMock.replay; +import static org.jclouds.compute.domain.OperatingSystem.UBUNTU; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.io.IOException; import java.net.InetSocketAddress; -import java.net.UnknownHostException; import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; 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.Profile; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.SocketOpen; -import org.jclouds.rimuhosting.miro.data.CreateOptions; -import org.jclouds.rimuhosting.miro.data.NewServerData; -import org.jclouds.rimuhosting.miro.domain.IpAddresses; -import org.jclouds.rimuhosting.miro.domain.NewServerResponse; -import org.jclouds.rimuhosting.miro.domain.Server; import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshException; @@ -59,7 +52,6 @@ import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; import com.google.inject.Guice; import com.google.inject.Injector; @@ -68,29 +60,34 @@ import com.google.inject.Injector; */ @Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest") public class RimuHostingComputeServiceLiveTest { + private static final String service = "rimuhosting"; protected SshClient.Factory sshFactory; - private String nodePrefix = System.getProperty("user.name") + ".rimuhosting"; + private String nodeName = System.getProperty("user.name") + service; private RetryablePredicate socketTester; private CreateNodeResponse node; private ComputeServiceContext context; + private ComputeService client; @BeforeGroups(groups = { "live" }) - public void setupClient() throws IOException { - String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); - context = new ComputeServiceContextFactory().createContext("rimuhosting", key, key, + public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, + IOException { + String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); + String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); + context = new ComputeServiceContextFactory().createContext(service, user, password, ImmutableSet.of(new Log4JLoggingModule()), new Properties()); Injector injector = Guice.createInjector(new JschSshClientModule()); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); injector.injectMembers(socketOpen); // add logger + client = context.getComputeService(); } public void testCreate() throws Exception { - node = context.getComputeService().startNodeInLocation("default", nodePrefix, - Profile.SMALLEST, Image.CENTOS_53); + Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest(); + node = client.runNode(nodeName, template); assertNotNull(node.getId()); assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginType(), LoginType.SSH); @@ -105,7 +102,7 @@ public class RimuHostingComputeServiceLiveTest { @Test(dependsOnMethods = "testCreate") public void testGet() throws Exception { - NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); + NodeMetadata metadata = client.getNodeMetadata(node); assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginType(), node.getLoginType()); @@ -115,13 +112,27 @@ public class RimuHostingComputeServiceLiveTest { } public void testList() throws Exception { - for (ComputeMetadata node : context.getComputeService().listNodes()) { + for (ComputeMetadata node : client.listNodes()) { assert node.getId() != null; assert node.getLocation() != null; assertEquals(node.getType(), ComputeType.NODE); } } + public void testListTemplates() throws Exception { + for (Template template : client.listTemplates()) { + assert template.getImage() != null; + System.out.println(template); + } + } + + public void testListSizes() throws Exception { + for (Size size : client.listSizes()) { + assert size.getCores() != null; + System.out.println(size); + } + } + private void sshPing() throws IOException { try { doCheckKey(); @@ -155,65 +166,8 @@ public class RimuHostingComputeServiceLiveTest { @AfterTest void cleanup() throws InterruptedException, ExecutionException, TimeoutException { if (node != null) - context.getComputeService().destroyNode(node); + client.destroyNode(node); context.close(); } - public void testParseInetAddress() throws UnknownHostException { - - Server rhServer = createMock(Server.class); - IpAddresses addresses = createMock(IpAddresses.class); - expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce(); - expect(addresses.getPrimaryIp()).andReturn("127.0.0.1"); - expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.of("www.yahoo.com")); - replay(rhServer); - replay(addresses); - - // assertEquals(Sets - // .newLinkedHashSet(RimuHostingCreateNodeResponse.getPublicAddresses(rhServer)), - // ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress - // .getByName("www.yahoo.com"))); - } - - @Test(enabled = false) - public void test() throws UnknownHostException { - - NewServerResponse nsResponse = createMock(NewServerResponse.class); - Server rhServer = createMock(Server.class); - - expect(nsResponse.getServer()).andReturn(rhServer).atLeastOnce(); - - expect(rhServer.getId()).andReturn(new Long(1)); - expect(rhServer.getName()).andReturn("name"); - - IpAddresses addresses = createMock(IpAddresses.class); - expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce(); - - expect(addresses.getPrimaryIp()).andReturn("127.0.0.1"); - expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet. of()); - - NewServerData data = createMock(NewServerData.class); - - expect(nsResponse.getNewInstanceRequest()).andReturn(data).atLeastOnce(); - CreateOptions options = createMock(CreateOptions.class); - expect(data.getCreateOptions()).andReturn(options); - expect(options.getPassword()).andReturn("password"); - - replay(nsResponse); - replay(rhServer); - replay(addresses); - replay(data); - replay(options); - - // RimuHostingCreateNodeResponse response = new RimuHostingCreateNodeResponse(nsResponse); - // assertEquals(response.getId(), "1"); - // assertEquals(response.getName(), "name"); - // assertEquals(response.getPublicAddresses(), ImmutableSet. of(InetAddress - // .getByName("127.0.0.1"))); - // assertEquals(response.getPrivateAddresses(), ImmutableSet. of()); - // assertEquals(response.getLoginPort(), 22); - // assertEquals(response.getLoginType(), LoginType.SSH); - // assertEquals(response.getCredentials(), new Credentials("root", "password")); - - } } diff --git a/tools/antcontrib/samples/cargooverssh/build.xml b/tools/antcontrib/samples/cargooverssh/build.xml index a268e42aec..5769fa6a35 100644 --- a/tools/antcontrib/samples/cargooverssh/build.xml +++ b/tools/antcontrib/samples/cargooverssh/build.xml @@ -72,7 +72,7 @@ - diff --git a/tools/antcontrib/samples/compute/build.xml b/tools/antcontrib/samples/compute/build.xml index 538cfc4d62..411614c978 100644 --- a/tools/antcontrib/samples/compute/build.xml +++ b/tools/antcontrib/samples/compute/build.xml @@ -94,7 +94,7 @@ - + - + diff --git a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java index e0da749fa9..67b7c2179a 100644 --- a/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java +++ b/tools/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java @@ -35,9 +35,9 @@ import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; 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.Profile; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.util.ComputeUtils; import org.jclouds.http.HttpUtils; @@ -187,12 +187,21 @@ public class ComputeTask extends Task { } private void create(ComputeService computeService) { - log(String.format("create name: %s, profile: %s, image: %s", nodeElement.getName(), - nodeElement.getProfile(), nodeElement.getImage())); - CreateNodeResponse createdNode = computeService.startNodeInLocation( - nodeElement.getLocation(), nodeElement.getName(), Profile.valueOf(nodeElement - .getProfile().toUpperCase()), Image.valueOf(nodeElement.getImage() - .toUpperCase())); + log(String.format("create name: %s, size: %s, os: %s", nodeElement.getName(), nodeElement + .getSize(), nodeElement.getOs())); + Template template = computeService.createTemplateInLocation(nodeElement.getLocation()); + template.os(OperatingSystem.valueOf(nodeElement.getOs())); + if (nodeElement.getSize().equalsIgnoreCase("smallest")) { + template.smallest(); + } else if (nodeElement.getSize().equalsIgnoreCase("fastest")) { + template.fastest(); + } else if (nodeElement.getSize().equalsIgnoreCase("biggest")) { + template.biggest(); + } else { + throw new BuildException("size: " + nodeElement.getSize() + + " not supported. valid sizes are smallest, fastest, biggest"); + } + CreateNodeResponse createdNode = computeService.runNode(nodeElement.getName(), template); log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdNode.getId(), createdNode.getName(), createdNode.getLoginType().toString().toLowerCase(), createdNode.getCredentials().account, createdNode.getCredentials().key, createdNode @@ -221,7 +230,7 @@ public class ComputeTask extends Task { private void destroy(ComputeService computeService) { log(String.format("destroy name: %s", nodeElement.getName())); - Iterable nodesThatMatch = ComputeUtils.filterByName(computeService + Iterable nodesThatMatch = ComputeUtils.filterByName(computeService .listNodes(), nodeElement.getName()); for (ComputeMetadata node : nodesThatMatch) { log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName())); @@ -231,7 +240,7 @@ public class ComputeTask extends Task { private void get(ComputeService computeService) { log(String.format("get name: %s", nodeElement.getName())); - Iterable nodesThatMatch = ComputeUtils.filterByName(computeService + Iterable nodesThatMatch = ComputeUtils.filterByName(computeService .listNodes(), nodeElement.getName()); for (ComputeMetadata node : nodesThatMatch) { logDetails(computeService, node); 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 79b537dcf0..3716812c93 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 @@ -24,8 +24,8 @@ package org.jclouds.tools.ant.taskdefs.compute; */ public class NodeElement { private String name; - private String profile; - private String image; + private String size; + private String os; private String passwordproperty; private String keyfi1le; private String hostproperty; @@ -49,22 +49,6 @@ public class NodeElement { this.name = name; } - String getProfile() { - return profile; - } - - public void setProfile(String profile) { - this.profile = profile; - } - - String getImage() { - return image; - } - - public void setImage(String image) { - this.image = image; - } - String getUsernameproperty() { return usernameproperty; } @@ -124,4 +108,20 @@ public class NodeElement { return keyfi1le; } + public void setSize(String size) { + this.size = size; + } + + public String getSize() { + return size; + } + + public void setOs(String os) { + this.os = os; + } + + public String getOs() { + return os; + } + } diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClient.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClient.java index 65ac9154d3..fbcf1c18f6 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClient.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClient.java @@ -26,7 +26,7 @@ import java.util.Map; import javax.annotation.Resource; import javax.inject.Inject; -import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.logging.Logger; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; @@ -49,17 +49,16 @@ public class VCloudComputeClient { private final VCloudClient tmClient; @Inject - public VCloudComputeClient(VCloudClient tmClient, - Predicate successTester) { + public VCloudComputeClient(VCloudClient tmClient, Predicate successTester) { this.tmClient = tmClient; this.taskTester = successTester; } - private Map imageCatalogIdMap = ImmutableMap. builder().put( - Image.CENTOS_53, "1").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put( - Image.UBUNTU_JEOS_90, "11").build(); + private Map imageCatalogIdMap = ImmutableMap + . builder().put(OperatingSystem.CENTOS, "1").put( + OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "11").build(); - public Map start(String name, Image image, int minCores, int minMegs, + public Map start(String name, OperatingSystem image, int minCores, int minMegs, long diskSize, Map properties) { checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image); String templateId = imageCatalogIdMap.get(image); @@ -68,9 +67,9 @@ public class VCloudComputeClient { .debug( ">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ", vDCId, name, templateId, minCores, minMegs, diskSize, properties); - VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, - templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores) - .memory(minMegs).disk(diskSize).productProperties(properties)); + VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, templateId, + InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(minMegs) + .disk(diskSize).productProperties(properties)); logger.debug("<< instantiated VApp(%s)", vAppResponse.getId()); logger.debug(">> deploying vApp(%s)", vAppResponse.getId()); @@ -85,7 +84,8 @@ public class VCloudComputeClient { // "powerOn", VAppStatus.ON); logger.debug("<< on vApp(%s)", vApp.getId()); - return ImmutableMap. of("id", vApp.getId(), "username", null, "password", null); + return ImmutableMap. of("id", vApp.getId(), "username", null, "password", + null); } /** diff --git a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClientLiveTest.java b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClientLiveTest.java index 3c4798310e..8909237e2f 100644 --- a/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClientLiveTest.java +++ b/vcloud/core/src/test/java/org/jclouds/vcloud/VCloudComputeClientLiveTest.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.vcloud.domain.ResourceType; @@ -59,7 +59,8 @@ public class VCloudComputeClientLiveTest { private String id; private InetAddress privateAddress; - public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll("\\.",""); + public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll( + "\\.", ""); private static class Expectation { final long hardDisk; @@ -71,20 +72,20 @@ public class VCloudComputeClientLiveTest { } } - private Map expectationMap = ImmutableMap. builder() - .put(Image.CENTOS_53, + private Map expectationMap = ImmutableMap + . builder().put(OperatingSystem.CENTOS, new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( - Image.RHEL_53, + OperatingSystem.RHEL, new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( - Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put( - Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build(); + OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)")) + .build(); private Predicate addressTester; @Test public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, IOException { - Image toTest = Image.CENTOS_53; + OperatingSystem toTest = OperatingSystem.CENTOS; String serverName = getCompatibleServerName(toTest); int processorCount = 1; @@ -101,10 +102,10 @@ public class VCloudComputeClientLiveTest { assertEquals(vApp.getStatus(), VAppStatus.ON); } - private String getCompatibleServerName(Image toTest) { - String serverName = CaseFormat.UPPER_UNDERSCORE - .to(CaseFormat.LOWER_CAMEL, toTest.toString()).substring(0, - toTest.toString().length()-1 <= 15 ? toTest.toString().length()-1 : 14); + private String getCompatibleServerName(OperatingSystem toTest) { + String serverName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, toTest.toString()) + .substring(0, + toTest.toString().length() - 1 <= 15 ? toTest.toString().length() - 1 : 14); return serverName; } @@ -146,8 +147,8 @@ public class VCloudComputeClientLiveTest { String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); Injector injector = new VCloudContextBuilder(new VCloudPropertiesBuilder( - URI.create(endpoint), account, key).build()).withModules( - new Log4JLoggingModule(), new JschSshClientModule()).buildInjector(); + URI.create(endpoint), account, key).build()).withModules(new Log4JLoggingModule(), + new JschSshClientModule()).buildInjector(); client = injector.getInstance(VCloudComputeClient.class); tmClient = injector.getInstance(VCloudClient.class); addressTester = injector.getInstance(Key.get(new TypeLiteral>() { diff --git a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClient.java b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClient.java index 97c97c8ccb..2eb0202f13 100644 --- a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClient.java +++ b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClient.java @@ -18,15 +18,12 @@ */ package org.jclouds.vcloud.hostingdotcom.compute; -import static com.google.common.base.Preconditions.checkArgument; - import java.net.InetAddress; import java.util.Map; import javax.annotation.Resource; import javax.inject.Inject; -import org.jclouds.compute.domain.Image; import org.jclouds.logging.Logger; import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.VApp; @@ -57,34 +54,15 @@ public class HostingDotComVCloudComputeClient { this.taskTester = successTester; } - private Map imageCatalogIdMap = ImmutableMap. builder().put( - Image.CENTOS_53, "3").build(); - -// -// -// -// - - public Map start(String name, Image image, int minCores, int minMegs, - long diskSize, Map properties) { - checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image); - String templateId = imageCatalogIdMap.get(image); - String vDCId = tmClient.getDefaultVDC().getId(); + public Map start(String vDCId, String name, String templateId, int minCores, + int minMegs, long diskSize, Map properties) { logger .debug( ">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ", vDCId, name, templateId, minCores, minMegs, diskSize, properties); HostingDotComVApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, - templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores) - .memory(minMegs).disk(diskSize).productProperties(properties)); + templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory( + minMegs).disk(diskSize).productProperties(properties)); logger.debug("<< instantiated VApp(%s)", vAppResponse.getId()); logger.debug(">> deploying vApp(%s)", vAppResponse.getId()); 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 d240ebcad4..27ff08cb21 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 @@ -28,6 +28,7 @@ import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.compute.ComputeService; @@ -38,8 +39,8 @@ 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.Profile; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.reference.ComputeServiceConstants; @@ -65,6 +66,9 @@ public class HostingDotComVCloudComputeService implements ComputeService { protected Logger logger = Logger.NULL; private final HostingDotComVCloudComputeClient computeClient; private final HostingDotComVCloudClient client; + private final Set images; + private final Set sizes; + private final Provider> templates; private static final Map vAppStatusToNodeState = ImmutableMap . builder().put(VAppStatus.OFF, NodeState.TERMINATED).put( @@ -74,25 +78,28 @@ public class HostingDotComVCloudComputeService implements ComputeService { @Inject public HostingDotComVCloudComputeService(HostingDotComVCloudClient client, - HostingDotComVCloudComputeClient computeClient) { + HostingDotComVCloudComputeClient computeClient, Set images, + Set sizes, Provider> templates) { this.client = client; this.computeClient = computeClient; - + this.images = images; + this.sizes = sizes; + this.templates = templates; } @Override - public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, - Image image) { - if (checkNotNull(location, "location").equalsIgnoreCase("default")) - location = client.getDefaultVDC().getId(); - Map metaMap = computeClient.start(name, image, 1, 512, (10l * 1025 * 1024), - ImmutableMap. of()); + public CreateNodeResponse runNode(String name, Template template) { + checkNotNull(template.getImage().getLocation(), "location"); + Map metaMap = computeClient.start(template.getImage().getLocation(), name, + template.getImage().getId(), template.getSize().getCores(), template.getSize() + .getRam(), template.getSize().getDisk(), ImmutableMap. of()); VApp vApp = client.getVApp(metaMap.get("id")); - return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(), - ImmutableMap. of(), vAppStatusToNodeState.get(vApp.getStatus()), - vApp.getNetworkToAddresses().values(), ImmutableSet. of(), 22, - LoginType.SSH, new Credentials(metaMap.get("username"), metaMap.get("password")), - ImmutableMap. of()); + return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage() + .getLocation(), vApp.getLocation(), ImmutableMap. of(), + vAppStatusToNodeState.get(vApp.getStatus()), vApp.getNetworkToAddresses().values(), + ImmutableSet. of(), 22, LoginType.SSH, new Credentials(metaMap + .get("username"), metaMap.get("password")), ImmutableMap + . of()); } @Override @@ -105,10 +112,10 @@ public class HostingDotComVCloudComputeService implements ComputeService { private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) { VApp vApp = client.getVApp(id); - return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp - .getLocation(), ImmutableMap. of(), vAppStatusToNodeState.get(vApp - .getStatus()), vApp.getNetworkToAddresses().values(), ImmutableSet - . of(), 22, LoginType.SSH, ImmutableMap. of()); + return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(), + ImmutableMap. of(), vAppStatusToNodeState.get(vApp.getStatus()), + vApp.getNetworkToAddresses().values(), ImmutableSet. of(), 22, + LoginType.SSH, ImmutableMap. of()); } @Override @@ -132,7 +139,17 @@ public class HostingDotComVCloudComputeService implements ComputeService { } @Override - public Map getSizes() { - return null;// TODO + public Template createTemplateInLocation(String location) { + return new HostingDotComVCloudTemplate(client, images, sizes, location); + } + + @Override + public Set listSizes() { + return sizes; + } + + @Override + public Set listTemplates() { + return templates.get(); } } \ No newline at end of file diff --git a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudTemplate.java b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudTemplate.java new file mode 100644 index 0000000000..f45383564e --- /dev/null +++ b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudTemplate.java @@ -0,0 +1,180 @@ +package org.jclouds.vcloud.hostingdotcom.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.hostingdotcom.HostingDotComVCloudClient; + +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +public class HostingDotComVCloudTemplate implements Template { + private final HostingDotComVCloudClient client; + private final Set images; + private final Set sizes; + private Size size; + private String vDC; + private OperatingSystem operatingSystem; + private transient Image image; + + public HostingDotComVCloudTemplate(HostingDotComVCloudClient 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); + } + + HostingDotComVCloudTemplate(HostingDotComVCloudClient 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 HostingDotComVCloudTemplate(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; + HostingDotComVCloudTemplate other = (HostingDotComVCloudTemplate) 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 "HostingDotComVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem + + ", size=" + size + ", vDC=" + vDC + "]"; + } + +} diff --git a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/config/HostingDotComVCloudComputeServiceContextModule.java b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/config/HostingDotComVCloudComputeServiceContextModule.java index e8172f9f03..c04ef14ef1 100755 --- a/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/config/HostingDotComVCloudComputeServiceContextModule.java +++ b/vcloud/hostingdotcom/src/main/java/org/jclouds/vcloud/hostingdotcom/compute/config/HostingDotComVCloudComputeServiceContextModule.java @@ -18,16 +18,38 @@ */ package org.jclouds.vcloud.hostingdotcom.compute.config; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Named; import javax.inject.Singleton; 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.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.logging.Logger; import org.jclouds.rest.RestContext; +import org.jclouds.vcloud.VCloudClient; +import org.jclouds.vcloud.VCloudMediaType; +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 org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient; +import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient; import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeService; +import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudTemplate; import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudContextModule; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; import com.google.inject.Provides; /** @@ -48,8 +70,70 @@ public class HostingDotComVCloudComputeServiceContextModule extends @Provides @Singleton ComputeServiceContext provideContext(ComputeService computeService, - RestContext context) { - return new ComputeServiceContextImpl( + RestContext context) { + return new ComputeServiceContextImpl( computeService, context); } + + private static class LogHolder { + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + } + + @Provides + @Singleton + Set provideImages(VCloudClient client, LogHolder holder) { + Set images = Sets.newLinkedHashSet(); + holder.logger.debug(">> providing images"); + Catalog response = client.getDefaultCatalog(); + String vDC = client.getDefaultVDC().getId(); + for (NamedResource resource : response.values()) { + if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) { + + CatalogItem item = client.getCatalogItem(resource.getId()); + OperatingSystem myOs = OperatingSystem.UNKNOWN; + for (OperatingSystem os : OperatingSystem.values()) { + if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) { + myOs = os; + } + } + Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32 + : Architecture.X86_64; + if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) { + VAppTemplate template = client.getVAppTemplate(item.getEntity().getId()); + images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null, + vDC, arch)); + } + } + } + holder.logger.debug("<< images(%d)", images.size()); + return images; + } + + @Provides + @Singleton + Set provideSizes(HostingDotComVCloudClient client, Set images, + LogHolder holder) { + return ImmutableSet. of(new SizeImpl(1, 512, (int) (10l * 1025 * 1024), ImmutableSet + . of(Architecture.X86_32, Architecture.X86_64))); + } + + @Provides + @Singleton + Set provideTemplates(HostingDotComVCloudClient client, + Set images, Set 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 HostingDotComVCloudTemplate(client, images, sizes, vDC, size, image + .getOperatingSystem(), image)); + } + } + holder.logger.debug("<< templates(%d)", templates.size()); + return templates; + } + } diff --git a/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClientLiveTest.java b/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClientLiveTest.java index 8065c85b27..4b33b0b728 100644 --- a/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClientLiveTest.java +++ b/vcloud/hostingdotcom/src/test/java/org/jclouds/vcloud/hostingdotcom/compute/HostingDotComVCloudComputeClientLiveTest.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.vcloud.domain.ResourceType; @@ -73,13 +73,9 @@ public class HostingDotComVCloudComputeClientLiveTest { } } - private Map expectationMap = ImmutableMap. builder() - .put(Image.CENTOS_53, - new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( - Image.RHEL_53, - new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( - Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put( - Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")) + private Map expectationMap = ImmutableMap + . builder().put(OperatingSystem.CENTOS, + new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")) .build(); private Predicate addressTester; @@ -87,7 +83,7 @@ public class HostingDotComVCloudComputeClientLiveTest { @Test(enabled = true) public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, IOException { - Image toTest = Image.CENTOS_53; + OperatingSystem toTest = OperatingSystem.CENTOS; String serverName = getCompatibleServerName(toTest); int processorCount = 1; @@ -95,7 +91,8 @@ public class HostingDotComVCloudComputeClientLiveTest { long disk = 10 * 1025 * 1024; Map properties = ImmutableMap.of("foo", "bar"); - id = client.start(serverName, toTest, processorCount, memory, disk, properties).get("id"); + id = client.start(hostingClient.getDefaultVDC().getId(), serverName, "3", processorCount, + memory, disk, properties).get("id"); Expectation expectation = expectationMap.get(toTest); VApp vApp = hostingClient.getVApp(id); @@ -104,7 +101,7 @@ public class HostingDotComVCloudComputeClientLiveTest { assertEquals(vApp.getStatus(), VAppStatus.ON); } - private String getCompatibleServerName(Image toTest) { + private String getCompatibleServerName(OperatingSystem toTest) { String serverName = CaseFormat.UPPER_UNDERSCORE .to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0, toTest.toString().length() <= 15 ? toTest.toString().length() : 14); @@ -148,8 +145,8 @@ public class HostingDotComVCloudComputeClientLiveTest { String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); Injector injector = new HostingDotComVCloudContextBuilder( - new HostingDotComVCloudPropertiesBuilder(account, key).build()) - .withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector(); + new HostingDotComVCloudPropertiesBuilder(account, key).build()).withModules( + new Log4JLoggingModule(), new JschSshClientModule()).buildInjector(); client = injector.getInstance(HostingDotComVCloudComputeClient.class); hostingClient = injector.getInstance(HostingDotComVCloudClient.class); addressTester = injector.getInstance(Key.get(new TypeLiteral>() { 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 380d849d22..0b30391f35 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 @@ -20,23 +20,28 @@ package org.jclouds.vcloud.hostingdotcom.compute; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.domain.OperatingSystem.CENTOS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.io.IOException; import java.net.InetSocketAddress; +import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ComputeServiceContextFactory; 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.Profile; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.SocketOpen; @@ -48,6 +53,7 @@ import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; import com.google.inject.Guice; import com.google.inject.Injector; @@ -59,30 +65,35 @@ import com.google.inject.Injector; */ @Test(groups = "live", enabled = true, sequential = true, testName = "compute.HostingDotComVCloudComputeServiceLiveTest") public class HostingDotComVCloudComputeServiceLiveTest { + private static final String service = "hostingdotcom"; + private static final OperatingSystem testOS = CENTOS; protected SshClient.Factory sshFactory; - private String nodePrefix = System.getProperty("user.name"); + private String nodeName = service; private RetryablePredicate socketTester; private CreateNodeResponse node; private ComputeServiceContext context; + private ComputeService client; @BeforeGroups(groups = { "live" }) - public void setupClient() throws InterruptedException, ExecutionException, TimeoutException { + public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, + IOException { String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); - context = HostingDotComVCloudComputeServiceContextFactory.createContext(user, password, - new Log4JLoggingModule()); + context = new ComputeServiceContextFactory().createContext(service, user, password, + ImmutableSet.of(new Log4JLoggingModule()), new Properties()); Injector injector = Guice.createInjector(new JschSshClientModule()); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); injector.injectMembers(socketOpen); // add logger + client = context.getComputeService(); } public void testCreate() throws Exception { - node = context.getComputeService().startNodeInLocation("default", nodePrefix, - Profile.SMALLEST, Image.UBUNTU_90); + Template template = client.createTemplateInLocation("default").os(testOS).smallest(); + node = client.runNode(nodeName, template); assertNotNull(node.getId()); assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginType(), LoginType.SSH); @@ -97,7 +108,7 @@ public class HostingDotComVCloudComputeServiceLiveTest { @Test(dependsOnMethods = "testCreate") public void testGet() throws Exception { - NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); + NodeMetadata metadata = client.getNodeMetadata(node); assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginType(), node.getLoginType()); @@ -107,13 +118,27 @@ public class HostingDotComVCloudComputeServiceLiveTest { } public void testList() throws Exception { - for (ComputeMetadata node : context.getComputeService().listNodes()) { + for (ComputeMetadata node : client.listNodes()) { assert node.getId() != null; assert node.getLocation() != null; assertEquals(node.getType(), ComputeType.NODE); } } + public void testListTemplates() throws Exception { + for (Template template : client.listTemplates()) { + assert template.getImage() != null; + System.out.println(template); + } + } + + public void testListSizes() throws Exception { + for (Size size : client.listSizes()) { + assert size.getCores() != null; + System.out.println(size); + } + } + private void sshPing() throws IOException { try { doCheckKey(); @@ -147,7 +172,7 @@ public class HostingDotComVCloudComputeServiceLiveTest { @AfterTest void cleanup() throws InterruptedException, ExecutionException, TimeoutException { if (node != null) - context.getComputeService().destroyNode(node); + client.destroyNode(node); context.close(); } } diff --git a/vcloud/hostingdotcom/src/test/resources/log4j.xml b/vcloud/hostingdotcom/src/test/resources/log4j.xml index aea2cf3bf8..467eb9a024 100755 --- a/vcloud/hostingdotcom/src/test/resources/log4j.xml +++ b/vcloud/hostingdotcom/src/test/resources/log4j.xml @@ -1,32 +1,31 @@ - + 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. + ==================================================================== + --> - + + debug="false"> @@ -43,37 +42,35 @@ - - - - + + + + - - + + - + - - - + + + + + + + - - - - - - @@ -89,70 +86,60 @@ - - - - - - - - - - - - - - + - - + + + + + + + + + + + + + + - - + + - - - - - - - - - + - - + + - + - - + - - - - - - - + + + + + + + \ No newline at end of file diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClient.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClient.java index 5eca75e400..1fb0128cb8 100644 --- a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClient.java +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClient.java @@ -31,7 +31,7 @@ import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; -import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; import org.jclouds.vcloud.domain.Task; @@ -68,11 +68,13 @@ public class TerremarkVCloudComputeClient { this.taskTester = successTester; } - private Map imageCatalogIdMap = ImmutableMap. builder().put( - Image.CENTOS_53, "6").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put( - Image.UBUNTU_JEOS_90, "11").put(Image.WEBAPPVM_93, "29").build(); + private Map imageCatalogIdMap = ImmutableMap + . builder().put(OperatingSystem.CENTOS, "6").put( + OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "10").build(); - public String start(String name, Image image, int minCores, int minMegs, + // .put( OperatingSystem.UBUNTU_JEOS_90, "11").put(OperatingSystem.WEBAPPVM_93, "29") + + public String start(String name, OperatingSystem image, int minCores, int minMegs, Map properties) { checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image); return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties); @@ -80,6 +82,12 @@ public class TerremarkVCloudComputeClient { public String start(String name, String templateId, int minCores, int minMegs, Map properties) { + return this.start(tmClient.getDefaultVDC().getId(), name, templateId, minCores, minMegs, + properties); + } + + public String start(String vdc, String name, String templateId, int minCores, int minMegs, + Map properties) { String vDCId = tmClient.getDefaultVDC().getId(); logger .debug( 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 5e4b8dd71f..95cfafca3c 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 @@ -28,6 +28,7 @@ import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.compute.ComputeService; @@ -38,8 +39,8 @@ 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.Profile; import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.reference.ComputeServiceConstants; @@ -65,6 +66,9 @@ public class TerremarkVCloudComputeService implements ComputeService { protected Logger logger = Logger.NULL; private final TerremarkVCloudComputeClient computeClient; private final TerremarkVCloudClient client; + private Set images; + private Set sizes; + private Provider> templates; private static final Map vAppStatusToNodeState = ImmutableMap . builder().put(VAppStatus.OFF, NodeState.TERMINATED).put( @@ -74,21 +78,25 @@ public class TerremarkVCloudComputeService implements ComputeService { @Inject public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient, - TerremarkVCloudComputeClient computeClient) { + TerremarkVCloudComputeClient computeClient, Set images, + Set sizes, Provider> templates) { this.client = tmClient; this.computeClient = computeClient; + this.images = images; + this.sizes = sizes; + this.templates = templates; } @Override - public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, - Image image) { - if (checkNotNull(location, "location").equalsIgnoreCase("default")) - location = client.getDefaultVDC().getId(); - String id = computeClient.start(name, image, 1, 512, ImmutableMap. of()); + public CreateNodeResponse runNode(String name, Template template) { + checkNotNull(template.getImage().getLocation(), "location"); + String id = computeClient.start(template.getImage().getLocation(), name, template.getImage() + .getId(), (int) template.getSize().getCores(), (int) template.getSize().getRam(), + ImmutableMap. of()); VApp vApp = client.getVApp(id); InetAddress publicIp = computeClient .createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443); - return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(), + return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage().getLocation(), vApp.getLocation(), ImmutableMap. of(), vAppStatusToNodeState.get(vApp.getStatus()), ImmutableSet. of(publicIp), vApp.getNetworkToAddresses().values(), 22, LoginType.SSH, new Credentials("vcloud", "p4ssw0rd"), ImmutableMap @@ -99,8 +107,8 @@ public class TerremarkVCloudComputeService implements ComputeService { public NodeMetadata getNodeMetadata(ComputeMetadata node) { checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " + node.getType()); - return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(node.getId(), - "node.id")); + return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull( + node.getId(), "node.id")); } private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) { @@ -133,7 +141,17 @@ public class TerremarkVCloudComputeService implements ComputeService { } @Override - public Map getSizes() { - return null;// TODO + public Template createTemplateInLocation(String location) { + return new TerremarkVCloudTemplate(client, images, sizes, location); + } + + @Override + public Set listSizes() { + return sizes; + } + + @Override + public Set listTemplates() { + return templates.get(); } } \ No newline at end of file diff --git a/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplate.java b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplate.java new file mode 100644 index 0000000000..b3e7283574 --- /dev/null +++ b/vcloud/terremark/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudTemplate.java @@ -0,0 +1,178 @@ +package org.jclouds.vcloud.terremark.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.terremark.TerremarkVCloudClient; + +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +public class TerremarkVCloudTemplate implements Template { + private final TerremarkVCloudClient client; + private final Set images; + private final Set sizes; + private Size size; + private String vDC; + private OperatingSystem operatingSystem; + private transient Image image; + + public TerremarkVCloudTemplate(TerremarkVCloudClient 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); + } + + TerremarkVCloudTemplate(TerremarkVCloudClient client, Set images, + Set sizes, String location) { + this(client, images, sizes, location, null, OperatingSystem.UBUNTU, null); + } + + /** + * {@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 TerremarkVCloudTemplate(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; + TerremarkVCloudTemplate other = (TerremarkVCloudTemplate) 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 "TerremarkVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem + + ", size=" + size + ", vDC=" + vDC + "]"; + } + +} 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 09eaec4906..e2adf14c4b 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 @@ -18,17 +18,42 @@ */ package org.jclouds.vcloud.terremark.compute.config; +import java.util.LinkedHashSet; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Named; import javax.inject.Singleton; 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.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.logging.Logger; import org.jclouds.rest.RestContext; +import org.jclouds.vcloud.VCloudClient; +import org.jclouds.vcloud.VCloudMediaType; +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 org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient; import org.jclouds.vcloud.terremark.TerremarkVCloudClient; import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService; +import org.jclouds.vcloud.terremark.compute.TerremarkVCloudTemplate; import org.jclouds.vcloud.terremark.config.TerremarkVCloudContextModule; +import org.jclouds.vcloud.terremark.domain.ComputeOptions; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; import com.google.inject.Provides; /** @@ -53,4 +78,82 @@ public class TerremarkVCloudComputeServiceContextModule extends TerremarkVCloudC computeService, context); } + private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize(); + + private static class ComputeOptionsToSize implements Function { + + @Override + public Size apply(ComputeOptions from) { + return new SizeImpl(from.getProcessorCount(), (int) from.getMemory(), null, ImmutableSet + . of(Architecture.X86_32, Architecture.X86_64)); + } + + } + + private static class LogHolder { + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + } + + @Provides + @Singleton + Set provideImages(VCloudClient client, LogHolder holder) { + Set images = Sets.newLinkedHashSet(); + holder.logger.debug(">> providing images"); + Catalog response = client.getDefaultCatalog(); + String vDC = client.getDefaultVDC().getId(); + for (NamedResource resource : response.values()) { + if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) { + + CatalogItem item = client.getCatalogItem(resource.getId()); + OperatingSystem myOs = OperatingSystem.UNKNOWN; + for (OperatingSystem os : OperatingSystem.values()) { + if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) { + myOs = os; + } + } + Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32 + : Architecture.X86_64; + if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) { + VAppTemplate template = client.getVAppTemplate(item.getEntity().getId()); + images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null, + vDC, arch)); + } + + } + } + holder.logger.debug("<< images(%d)", images.size()); + return images; + } + + @Provides + @Singleton + Set provideSizes(TerremarkVCloudClient client, Set images, + LogHolder holder) { + Image anyImage = Iterables.get(images, 0); + holder.logger.debug(">> providing sizes"); + LinkedHashSet sizes = Sets.newLinkedHashSet(Iterables.transform(client + .getComputeOptionsOfCatalogItem(anyImage.getId()), sizeConverter)); + holder.logger.debug("<< sizes(%d)", sizes.size()); + return sizes; + } + + @Provides + @Singleton + Set provideTemplates(TerremarkVCloudClient client, + Set images, Set 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 TerremarkVCloudTemplate(client, images, sizes, vDC, size, image + .getOperatingSystem(), image)); + } + } + holder.logger.debug("<< templates(%d)", templates.size()); + return templates; + } + } diff --git a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClientLiveTest.java b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClientLiveTest.java index e94a3e13b8..4f3369f43b 100644 --- a/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClientLiveTest.java +++ b/vcloud/terremark/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeClientLiveTest.java @@ -27,7 +27,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.vcloud.domain.ResourceType; @@ -73,18 +73,20 @@ public class TerremarkVCloudComputeClientLiveTest { } } - private Map expectationMap = ImmutableMap. builder() - .put(Image.CENTOS_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")) - .put(Image.RHEL_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")) - .put(Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put( - Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build(); - + private Map expectationMap = ImmutableMap + . builder().put(OperatingSystem.CENTOS, + new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put( + OperatingSystem.RHEL, + new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put( + OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (64-bit)")) + .build(); + // .put(OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)")) private Predicate addressTester; @Test public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, IOException { - Image toTest = Image.CENTOS_53; + OperatingSystem toTest = OperatingSystem.CENTOS; String serverName = getCompatibleServerName(toTest); int processorCount = 1; @@ -100,7 +102,7 @@ public class TerremarkVCloudComputeClientLiveTest { assertEquals(vApp.getStatus(), VAppStatus.ON); } - private String getCompatibleServerName(Image toTest) { + private String getCompatibleServerName(OperatingSystem toTest) { String serverName = CaseFormat.UPPER_UNDERSCORE .to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0, toTest.toString().length() <= 15 ? toTest.toString().length() : 14); @@ -115,9 +117,8 @@ public class TerremarkVCloudComputeClientLiveTest { @Test(dependsOnMethods = "testGetAnyPrivateAddress") public void testSshLoadBalanceIp() { - InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22, - 80, - 443, 8080); /// error 500 + InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22, 80, + 443, 8080); // / error 500 assert addressTester.apply(publicIp); // client.exec(publicIp, "uname -a"); } 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 eb754b1d0f..a7b12c4924 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 @@ -20,23 +20,29 @@ package org.jclouds.vcloud.terremark.compute; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.domain.OperatingSystem.CENTOS; +import static org.jclouds.compute.domain.OperatingSystem.UBUNTU; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.io.IOException; import java.net.InetSocketAddress; +import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ComputeServiceContextFactory; 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.Profile; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Size; +import org.jclouds.compute.domain.Template; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.SocketOpen; @@ -48,6 +54,7 @@ import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; import com.google.inject.Guice; import com.google.inject.Injector; @@ -59,30 +66,35 @@ import com.google.inject.Injector; */ @Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest") public class TerremarkVCloudComputeServiceLiveTest { + private static final String service = "terremark"; + private static final OperatingSystem testOS = UBUNTU; protected SshClient.Factory sshFactory; - private String nodePrefix = System.getProperty("user.name"); + private String nodeName = service; private RetryablePredicate socketTester; private CreateNodeResponse node; private ComputeServiceContext context; + private ComputeService client; @BeforeGroups(groups = { "live" }) - public void setupClient() throws InterruptedException, ExecutionException, TimeoutException { + public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, + IOException { String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); - context = TerremarkVCloudComputeServiceContextFactory.createContext(user, password, - new Log4JLoggingModule()); + context = new ComputeServiceContextFactory().createContext(service, user, password, + ImmutableSet.of(new Log4JLoggingModule()), new Properties()); Injector injector = Guice.createInjector(new JschSshClientModule()); sshFactory = injector.getInstance(SshClient.Factory.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class); socketTester = new RetryablePredicate(socketOpen, 60, 1, TimeUnit.SECONDS); injector.injectMembers(socketOpen); // add logger + client = context.getComputeService(); } public void testCreate() throws Exception { - node = context.getComputeService().startNodeInLocation("default", nodePrefix, - Profile.SMALLEST, Image.UBUNTU_90); + Template template = client.createTemplateInLocation("default").os(testOS).smallest(); + node = client.runNode(nodeName, template); assertNotNull(node.getId()); assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginType(), LoginType.SSH); @@ -97,7 +109,7 @@ public class TerremarkVCloudComputeServiceLiveTest { @Test(dependsOnMethods = "testCreate") public void testGet() throws Exception { - NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); + NodeMetadata metadata = client.getNodeMetadata(node); assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginType(), node.getLoginType()); @@ -107,13 +119,27 @@ public class TerremarkVCloudComputeServiceLiveTest { } public void testList() throws Exception { - for (ComputeMetadata node : context.getComputeService().listNodes()) { + for (ComputeMetadata node : client.listNodes()) { assert node.getId() != null; assert node.getLocation() != null; assertEquals(node.getType(), ComputeType.NODE); } } + public void testListTemplates() throws Exception { + for (Template template : client.listTemplates()) { + assert template.getImage() != null; + System.out.println(template); + } + } + + public void testListSizes() throws Exception { + for (Size size : client.listSizes()) { + assert size.getCores() != null; + System.out.println(size); + } + } + private void sshPing() throws IOException { try { doCheckKey(); @@ -147,7 +173,7 @@ public class TerremarkVCloudComputeServiceLiveTest { @AfterTest void cleanup() throws InterruptedException, ExecutionException, TimeoutException { if (node != null) - context.getComputeService().destroyNode(node); + client.destroyNode(node); context.close(); } } \ No newline at end of file diff --git a/vcloud/terremark/src/test/resources/log4j.xml b/vcloud/terremark/src/test/resources/log4j.xml index c54a752ef0..af08ea833b 100755 --- a/vcloud/terremark/src/test/resources/log4j.xml +++ b/vcloud/terremark/src/test/resources/log4j.xml @@ -66,6 +66,32 @@ --> + + + + + + + + + + + + + + + + + + + + + + @@ -93,6 +119,11 @@ + + + + +