mirror of https://github.com/apache/jclouds.git
Issue 130: fleshed out compute abstraction and hardened TemplateBuilder design
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2718 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
a17da70588
commit
28aadccb49
|
@ -38,7 +38,7 @@ public class EC2PropertiesBuilder extends HttpPropertiesBuilder {
|
|||
@Override
|
||||
protected Properties defaultProperties() {
|
||||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_EC2_ENDPOINT, "https://ec2.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_EC2_ENDPOINT, "https://ec2.us-east-1.amazonaws.com");
|
||||
properties.setProperty(PROPERTY_AWS_EXPIREINTERVAL, "60");
|
||||
return properties;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import java.net.InetAddress;
|
|||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -43,15 +42,16 @@ import org.jclouds.aws.ec2.domain.KeyPair;
|
|||
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||
import org.jclouds.aws.ec2.options.RunInstancesOptions;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
|
@ -76,22 +76,21 @@ public class EC2ComputeService implements ComputeService {
|
|||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
private final EC2Client ec2Client;
|
||||
private final SortedSet<EC2Size> sizes;
|
||||
private final Provider<Set<EC2Template>> templates;
|
||||
protected final Provider<Set<? extends Image>> images;
|
||||
protected final Provider<Set<? extends Size>> sizes;
|
||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
private final Predicate<RunningInstance> instanceStateRunning;
|
||||
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
|
||||
private final Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
|
||||
|
||||
@Inject
|
||||
public EC2ComputeService(EC2Client client, SortedSet<EC2Size> sizes,
|
||||
Provider<Set<EC2Template>> templates,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
public EC2ComputeService(EC2Client client, Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Predicate<RunningInstance> instanceStateRunning,
|
||||
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
|
||||
this.ec2Client = client;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
this.templates = templates; // delayed intentionally, as generation is slow
|
||||
this.imageAmiIdMap = imageAmiIdMap;
|
||||
this.templateBuilderProvider = templateBuilderProvider;
|
||||
this.instanceStateRunning = instanceStateRunning;
|
||||
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
|
||||
}
|
||||
|
@ -108,20 +107,23 @@ public class EC2ComputeService implements ComputeService {
|
|||
|
||||
@Override
|
||||
public CreateNodeResponse runNode(String name, Template template, RunNodeOptions options) {
|
||||
checkArgument(template instanceof EC2Template,
|
||||
"unexpected template type. should be EC2Template, was: " + template.getClass());
|
||||
EC2Template ec2Template = (EC2Template) template;
|
||||
checkArgument(template.getImage() instanceof EC2Image,
|
||||
"unexpected image type. should be EC2Image, was: " + template.getImage().getClass());
|
||||
checkArgument(template.getSize() instanceof EC2Size,
|
||||
"unexpected image type. should be EC2Size, was: " + template.getSize().getClass());
|
||||
EC2Image ec2Image = EC2Image.class.cast(template.getImage());
|
||||
EC2Size ec2Size = EC2Size.class.cast(template.getSize());
|
||||
|
||||
KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name);
|
||||
Region region = ec2Image.getImage().getRegion();
|
||||
KeyPair keyPair = createKeyPairInRegion(region, name);
|
||||
String securityGroupName = name;
|
||||
createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, options
|
||||
.getOpenPorts());
|
||||
createSecurityGroupInRegion(region, securityGroupName, options.getOpenPorts());
|
||||
|
||||
logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)",
|
||||
ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize()
|
||||
.getInstanceType(), keyPair.getKeyName(), securityGroupName);
|
||||
region, ec2Image.getId(), ec2Size.getInstanceType(), keyPair.getKeyName(),
|
||||
securityGroupName);
|
||||
RunInstancesOptions instanceOptions = withKeyName(keyPair.getKeyName())// key
|
||||
.asType(ec2Template.getSize().getInstanceType())// instance size
|
||||
.asType(ec2Size.getInstanceType())// instance size
|
||||
.withSecurityGroup(securityGroupName)// group I created above
|
||||
.withAdditionalInfo(name);
|
||||
|
||||
|
@ -129,36 +131,24 @@ public class EC2ComputeService implements ComputeService {
|
|||
instanceOptions.withUserData(options.getRunScript());
|
||||
|
||||
RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices()
|
||||
.runInstancesInRegion(ec2Template.getRegion(), null, ec2Template.getImage().getId(),
|
||||
1, 1, instanceOptions));
|
||||
.runInstancesInRegion(region, null, ec2Image.getId(), 1, 1, instanceOptions));
|
||||
logger.debug("<< started instance(%s)", runningInstance.getId());
|
||||
instanceStateRunning.apply(runningInstance);
|
||||
logger.debug("<< running instance(%s)", runningInstance.getId());
|
||||
|
||||
// refresh to get IP address
|
||||
runningInstance = getOnlyRunningInstanceInRegion(ec2Template.getRegion(), runningInstance
|
||||
.getId());
|
||||
runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId());
|
||||
|
||||
Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet
|
||||
.<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress());
|
||||
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
|
||||
.<InetAddress> of()
|
||||
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
|
||||
return new CreateNodeResponseImpl(
|
||||
runningInstance.getId(),
|
||||
name,
|
||||
runningInstance.getRegion().toString(),
|
||||
null,
|
||||
ImmutableMap.<String, String> of(),
|
||||
instanceToNodeState.get(runningInstance.getInstanceState()),
|
||||
publicAddresses,
|
||||
privateAddresses,
|
||||
22,
|
||||
return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion()
|
||||
.toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState
|
||||
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22,
|
||||
LoginType.SSH,
|
||||
new Credentials(
|
||||
ec2Template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU ? "ubuntu"
|
||||
: "root", keyPair.getKeyMaterial()), ImmutableMap
|
||||
.<String, String> of());
|
||||
new Credentials("root", keyPair.getKeyMaterial()), ImmutableMap.<String, String> of());
|
||||
}
|
||||
|
||||
private KeyPair createKeyPairInRegion(Region region, String name) {
|
||||
|
@ -316,17 +306,18 @@ public class EC2ComputeService implements ComputeService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<EC2Size> listSizes() {
|
||||
return sizes;
|
||||
public Set<? extends Size> listSizes() {
|
||||
return sizes.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<EC2Template> listTemplates() {
|
||||
return templates.get();
|
||||
public Set<? extends Image> listImages() {
|
||||
return images.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return new EC2Template(ec2Client, imageAmiIdMap, location);
|
||||
public TemplateBuilder templateBuilder() {
|
||||
return templateBuilderProvider.get();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.aws.ec2.compute;
|
||||
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2Image implements Image {
|
||||
private final org.jclouds.aws.ec2.domain.Image image;
|
||||
private final OperatingSystem os;
|
||||
private final String osVersion;
|
||||
private final String version;
|
||||
|
||||
public EC2Image(org.jclouds.aws.ec2.domain.Image image, OperatingSystem os, String osVersion,
|
||||
String version) {
|
||||
this.image = image;
|
||||
this.os = os;
|
||||
this.osVersion = osVersion;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Architecture getArchitecture() {
|
||||
return getImage().getArchitecture() == org.jclouds.aws.ec2.domain.Image.Architecture.I386 ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return getImage().getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return getImage().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocation() {
|
||||
return getImage().getRegion().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatingSystem getOperatingSystem() {
|
||||
return os;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOperatingSystemVersion() {
|
||||
return osVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public org.jclouds.aws.ec2.domain.Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||
result = prime * result + ((os == null) ? 0 : os.hashCode());
|
||||
result = prime * result + ((osVersion == null) ? 0 : osVersion.hashCode());
|
||||
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
EC2Image other = (EC2Image) obj;
|
||||
if (image == null) {
|
||||
if (other.image != null)
|
||||
return false;
|
||||
} else if (!image.equals(other.image))
|
||||
return false;
|
||||
if (os == null) {
|
||||
if (other.os != null)
|
||||
return false;
|
||||
} else if (!os.equals(other.os))
|
||||
return false;
|
||||
if (osVersion == null) {
|
||||
if (other.osVersion != null)
|
||||
return false;
|
||||
} else if (!osVersion.equals(other.osVersion))
|
||||
return false;
|
||||
if (version == null) {
|
||||
if (other.version != null)
|
||||
return false;
|
||||
} else if (!version.equals(other.version))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[id=" + getId() + ", version=" + version + ", location=" + getLocation()
|
||||
+ ", architecture=" + getArchitecture() + ", operatingSystem="
|
||||
+ getOperatingSystem() + ", operatingSystemVersion=" + getOperatingSystemVersion()
|
||||
+ ", description=" + getDescription() + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -38,7 +38,7 @@ public class EC2Size extends SizeImpl {
|
|||
|
||||
EC2Size(InstanceType instanceType, Integer cores, Integer ram, Integer disk,
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
super(cores, ram, disk, supportedArchitectures);
|
||||
super(instanceType.toString(), cores, ram, disk, supportedArchitectures);
|
||||
this.instanceType = instanceType;
|
||||
}
|
||||
|
||||
|
@ -85,4 +85,29 @@ public class EC2Size extends SizeImpl {
|
|||
public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20, 7168, 1690,
|
||||
ImmutableSet.of(Architecture.X86_64));
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
EC2Size other = (EC2Size) obj;
|
||||
if (instanceType == null) {
|
||||
if (other.instanceType != null)
|
||||
return false;
|
||||
} else if (!instanceType.equals(other.instanceType))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,233 +0,0 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* 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<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
|
||||
private EC2Size size;
|
||||
private OperatingSystem operatingSystem;
|
||||
private Region region;
|
||||
private transient Image image;
|
||||
|
||||
public EC2Template(EC2Client client,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> 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<Architecture, Map<OperatingSystem, Map<Region, String>>> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,33 +18,40 @@
|
|||
*/
|
||||
package org.jclouds.aws.ec2.compute.config;
|
||||
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.ownedBy;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2;
|
||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.compute.EC2ComputeService;
|
||||
import org.jclouds.aws.ec2.compute.EC2Image;
|
||||
import org.jclouds.aws.ec2.compute.EC2Size;
|
||||
import org.jclouds.aws.ec2.compute.EC2Template;
|
||||
import org.jclouds.aws.ec2.config.EC2ContextModule;
|
||||
import org.jclouds.aws.ec2.util.EC2Utils;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.ResourceLocation;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RestContext;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Provides;
|
||||
|
||||
|
@ -70,61 +77,55 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
SortedSet<EC2Size> provideSizes() {
|
||||
return ImmutableSortedSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
Set<? extends Size> provideSizes() {
|
||||
return ImmutableSet.of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
|
||||
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@ResourceLocation
|
||||
String getRegion(@EC2 Region region) {
|
||||
return region.value();
|
||||
}
|
||||
|
||||
private static class LogHolder {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Set<EC2Template> provideTemplates(EC2Client client, SortedSet<EC2Size> sizes,
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
|
||||
LogHolder holder) {
|
||||
Set<EC2Template> templates = Sets.newHashSet();
|
||||
holder.logger.debug(">> generating templates");
|
||||
for (EC2Size size : sizes) {
|
||||
for (Architecture architecture : imageAmiIdMap.keySet()) {
|
||||
if (size.supportsArchitecture(architecture)) {
|
||||
for (OperatingSystem operatingSystem : imageAmiIdMap.get(architecture).keySet()) {
|
||||
for (Region region : imageAmiIdMap.get(architecture).get(operatingSystem)
|
||||
.keySet()) {
|
||||
String ami = imageAmiIdMap.get(architecture).get(operatingSystem).get(region);
|
||||
templates.add(new EC2Template(client, imageAmiIdMap, size, operatingSystem,
|
||||
region, EC2Utils.newImage(client, region, operatingSystem,
|
||||
architecture, ami)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< templates(%d)", templates.size());
|
||||
return templates;
|
||||
}
|
||||
// alestic-32-eu-west-1/debian-4.0-etch-base-20081130.manifest.xml
|
||||
public static final Pattern ALESTIC_PATTERN = Pattern
|
||||
.compile(".*/([^-]*)-([^-]*)-.*-(.*)\\.manifest\\.xml");
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> provideimageAmiIdMap() {
|
||||
return ImmutableMap.<Architecture, Map<OperatingSystem, Map<Region, String>>> of(
|
||||
Architecture.X86_32,//
|
||||
ImmutableMap.<OperatingSystem, Map<Region, String>> 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.<OperatingSystem, Map<Region, String>> builder().put(
|
||||
OperatingSystem.UBUNTU,
|
||||
ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1,
|
||||
"ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e",
|
||||
Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami
|
||||
protected Set<? extends Image> provideImages(final EC2Client sync, Map<Region, URI> regionMap,
|
||||
LogHolder holder) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
for (final Region region : regionMap.keySet()) {
|
||||
for (final org.jclouds.aws.ec2.domain.Image from : sync.getAMIServices()
|
||||
.describeImagesInRegion(region, ownedBy("063491364108"))) {
|
||||
OperatingSystem os = null;
|
||||
String osVersion = "";
|
||||
String version = "";
|
||||
|
||||
Matcher matcher = ALESTIC_PATTERN.matcher(from.getImageLocation());
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
os = OperatingSystem.fromValue(matcher.group(1));
|
||||
osVersion = matcher.group(2);
|
||||
version = matcher.group(3);
|
||||
} catch (IllegalArgumentException e) {
|
||||
holder.logger.debug("<< didn't match os(%s)", matcher.group(1));
|
||||
}
|
||||
}
|
||||
images.add(new EC2Image(from, os, osVersion, version));
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< images(%d)", images.size());
|
||||
return images;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ import org.jclouds.rest.ConfiguresRestClient;
|
|||
import org.jclouds.rest.RestClientFactory;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -92,6 +93,16 @@ public class EC2RestClientModule extends AbstractModule {
|
|||
bindRetryHandlers();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@EC2
|
||||
Region provideCurrentRegion(Map<Region, URI> regionMap, @EC2 URI currentUri) {
|
||||
ImmutableBiMap<URI, Region> map = ImmutableBiMap.copyOf(regionMap).inverse();
|
||||
Region region = map.get(currentUri);
|
||||
assert region != null : currentUri + " not in " + map;
|
||||
return region;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Map<Region, URI> provideRegions(AvailabilityZoneAndRegionClient client) {
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.jclouds.concurrent.Timeout;
|
|||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
|
||||
@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS)
|
||||
public interface InstanceClient {
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,30 +20,16 @@ package org.jclouds.aws.ec2.util;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||
|
||||
import org.jclouds.aws.domain.Region;
|
||||
import org.jclouds.aws.ec2.EC2Client;
|
||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.internal.ImageImpl;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import com.google.inject.internal.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class EC2Utils {
|
||||
public static Image newImage(EC2Client client, Region region, OperatingSystem os,
|
||||
Architecture architecture, String ami) {
|
||||
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(client.getAMIServices()
|
||||
.describeImagesInRegion(region, imageIds(ami)));
|
||||
return new ImageImpl(ami, image.getDescription(), os, null, region.toString(), architecture);
|
||||
}
|
||||
|
||||
public static void indexStringArrayToFormValuesWithPrefix(GeneratedHttpRequest<?> request,
|
||||
String prefix, Object input) {
|
||||
|
|
|
@ -46,7 +46,6 @@ public class QueueHandler extends ParseSax.HandlerWithResult<Queue> {
|
|||
@Inject
|
||||
QueueHandler(Map<Region, URI> regionMap) {
|
||||
this.regionBiMap = ImmutableBiMap.copyOf(regionMap);
|
||||
|
||||
}
|
||||
|
||||
public Queue getResult() {
|
||||
|
|
|
@ -49,7 +49,7 @@ public class EC2ContextBuilderTest {
|
|||
public void testNewBuilder() {
|
||||
EC2ContextBuilder builder = newBuilder();
|
||||
assertEquals(builder.getProperties().getProperty(EC2Constants.PROPERTY_EC2_ENDPOINT),
|
||||
"https://ec2.amazonaws.com");
|
||||
"https://ec2.us-east-1.amazonaws.com");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_ACCESSKEYID), "id");
|
||||
assertEquals(builder.getProperties().getProperty(PROPERTY_AWS_SECRETACCESSKEY), "secret");
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class EC2ContextBuilderTest {
|
|||
RestContext<EC2AsyncClient, EC2Client> context = newBuilder().buildContext();
|
||||
assertEquals(context.getClass(), RestContextImpl.class);
|
||||
assertEquals(context.getAccount(), "id");
|
||||
assertEquals(context.getEndPoint(), URI.create("https://ec2.amazonaws.com"));
|
||||
assertEquals(context.getEndPoint(), URI.create("https://ec2.us-east-1.amazonaws.com"));
|
||||
}
|
||||
|
||||
public void testBuildInjector() {
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.jclouds.aws.ec2.compute;
|
|||
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
|
||||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -37,7 +39,10 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
|||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "ec2";
|
||||
testOS = UBUNTU;
|
||||
}
|
||||
|
||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||
return templateBuilder.os(UBUNTU).smallest().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,13 +19,14 @@
|
|||
package org.jclouds.compute;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
|
||||
/**
|
||||
|
@ -36,27 +37,19 @@ import org.jclouds.compute.options.RunNodeOptions;
|
|||
*/
|
||||
public interface ComputeService {
|
||||
/**
|
||||
* Creates a new template in the specified location.
|
||||
*
|
||||
* @param location
|
||||
* where the template is valid for
|
||||
* Makes a new template builder for this service
|
||||
*/
|
||||
Template createTemplateInLocation(String location);
|
||||
TemplateBuilder templateBuilder();
|
||||
|
||||
/**
|
||||
* List all sizes available to the current user
|
||||
*/
|
||||
SortedSet<? extends Size> listSizes();
|
||||
Set<? extends Size> listSizes();
|
||||
|
||||
/**
|
||||
* List all images available to the current user
|
||||
*/
|
||||
// Set<? extends Image> listImages();
|
||||
|
||||
/**
|
||||
* List all templates available to the current user
|
||||
*/
|
||||
Set<? extends Template> listTemplates();
|
||||
Set<? extends Image> listImages();
|
||||
|
||||
/**
|
||||
* List all nodes available to the current user
|
||||
|
@ -68,6 +61,7 @@ public interface ComputeService {
|
|||
*
|
||||
*/
|
||||
CreateNodeResponse runNode(String name, Template template);
|
||||
|
||||
CreateNodeResponse runNode(String name, Template template, RunNodeOptions options);
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,6 +46,11 @@ public interface Image {
|
|||
*/
|
||||
OperatingSystem getOperatingSystem();
|
||||
|
||||
/**
|
||||
* Version of the operating system
|
||||
*/
|
||||
String getOperatingSystemVersion();
|
||||
|
||||
/**
|
||||
* Version of the image
|
||||
*/
|
||||
|
|
|
@ -23,11 +23,28 @@
|
|||
*/
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.CaseFormat;
|
||||
|
||||
/**
|
||||
* Running Operating system
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum OperatingSystem {
|
||||
CENTOS, RHEL, UBUNTU, JEOS, WINDOWS, UNKNOWN;
|
||||
CENTOS, RHEL, FEDORA, DEBIAN, UBUNTU, JEOS, WINDOWS;
|
||||
public String value() {
|
||||
return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static OperatingSystem fromValue(String operatingSystem) {
|
||||
return valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(
|
||||
operatingSystem, "region")));
|
||||
}
|
||||
}
|
|
@ -23,13 +23,23 @@
|
|||
*/
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* Size of a node.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ImplementedBy(SizeImpl.class)
|
||||
public interface Size extends Comparable<Size> {
|
||||
|
||||
/**
|
||||
* unique identifier of this configuration.
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Amount of virtual or physical cores provided
|
||||
*/
|
||||
|
|
|
@ -24,32 +24,6 @@ package org.jclouds.compute.domain;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public interface Template extends Cloneable {
|
||||
|
||||
/**
|
||||
* configure this template to the smallest size.
|
||||
*/
|
||||
Template smallest();
|
||||
|
||||
/**
|
||||
* configure this template to the fastest size.
|
||||
*/
|
||||
Template fastest();
|
||||
|
||||
/**
|
||||
* configure this template to the largest size.
|
||||
*/
|
||||
Template biggest();
|
||||
|
||||
/**
|
||||
* Configure this template to use a specific operating system image.
|
||||
*/
|
||||
Template os(OperatingSystem os);
|
||||
|
||||
/**
|
||||
* Configure this template to start in a specific location
|
||||
*/
|
||||
Template inLocation(String location);
|
||||
|
||||
/**
|
||||
* Image that suits the requirements.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.compute.domain;
|
||||
|
||||
import org.jclouds.compute.internal.TemplateBuilderImpl;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
* Creates a customized template based on requirements.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ImplementedBy(TemplateBuilderImpl.class)
|
||||
public interface TemplateBuilder {
|
||||
/**
|
||||
* Configure this template to require the minimum size of the parameter.
|
||||
*/
|
||||
TemplateBuilder fromSize(Size size);
|
||||
|
||||
/**
|
||||
* Configure this template to fuzzy-match on the image parameter
|
||||
*/
|
||||
TemplateBuilder fromImage(Image image);
|
||||
|
||||
/**
|
||||
* Configure this template to match the resources of the template parameter.
|
||||
*/
|
||||
TemplateBuilder fromTemplate(Template image);
|
||||
|
||||
/**
|
||||
* configure this template to the smallest size.
|
||||
*/
|
||||
TemplateBuilder smallest();
|
||||
|
||||
/**
|
||||
* configure this template to the fastest size.
|
||||
*/
|
||||
TemplateBuilder fastest();
|
||||
|
||||
/**
|
||||
* configure this template to the largest size.
|
||||
*/
|
||||
TemplateBuilder biggest();
|
||||
|
||||
/**
|
||||
* Configure this template to use a specific operating system image.
|
||||
*/
|
||||
TemplateBuilder os(OperatingSystem os);
|
||||
|
||||
/**
|
||||
* Configure this template to start in a specific location
|
||||
*/
|
||||
TemplateBuilder location(String location);
|
||||
|
||||
/**
|
||||
* Configure this template to require a specific architecture
|
||||
*/
|
||||
TemplateBuilder architecture(Architecture architecture);
|
||||
|
||||
/**
|
||||
* Configure this template to require a specific imageId.
|
||||
* <p/>
|
||||
* Note that image Ids are often scoped to {@code location}
|
||||
*/
|
||||
TemplateBuilder imageId(String imageId);
|
||||
|
||||
/**
|
||||
* Configure this template to require a specific sizeId.
|
||||
*/
|
||||
TemplateBuilder sizeId(String sizeId);
|
||||
|
||||
/**
|
||||
* Configure this template to have an operating system version that matches the regular
|
||||
* expression
|
||||
*/
|
||||
TemplateBuilder osVersionMatches(String osVersionRegex);
|
||||
|
||||
/**
|
||||
* Configure this template to have an image version that matches the regular expression
|
||||
*/
|
||||
TemplateBuilder imageVersionMatches(String imageVersionRegex);
|
||||
|
||||
/**
|
||||
* Configure this template to have a description that matches the regular expression
|
||||
*/
|
||||
TemplateBuilder imageDescriptionMatches(String descriptionRegex);
|
||||
|
||||
/**
|
||||
* Configure this template to require the minimum cores below
|
||||
*/
|
||||
TemplateBuilder minCores(int minCores);
|
||||
|
||||
/**
|
||||
* Configure this template to require the minimum ram in megabytes below
|
||||
*/
|
||||
TemplateBuilder minRam(int megabytes);
|
||||
|
||||
/**
|
||||
* Generate an immutable template from the current builder.
|
||||
*/
|
||||
Template build();
|
||||
}
|
|
@ -34,21 +34,12 @@ public class ImageImpl implements Image {
|
|||
|
||||
private final String id;
|
||||
private final String description;
|
||||
private final OperatingSystem operatingSystem;
|
||||
private final String version;
|
||||
private final OperatingSystem operatingSystem;
|
||||
private final String operatingSystemVersion;
|
||||
private final String location;
|
||||
private final Architecture architecture;
|
||||
|
||||
public ImageImpl(String id, String description, OperatingSystem operatingSystem, String version,
|
||||
String location, Architecture architecture) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.operatingSystem = operatingSystem;
|
||||
this.version = version;
|
||||
this.location = location;
|
||||
this.architecture = architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -65,6 +56,17 @@ public class ImageImpl implements Image {
|
|||
return result;
|
||||
}
|
||||
|
||||
public ImageImpl(String id, String description, String version, OperatingSystem operatingSystem,
|
||||
String operatingSystemVersion, String location, Architecture architecture) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.version = version;
|
||||
this.operatingSystem = operatingSystem;
|
||||
this.operatingSystemVersion = operatingSystemVersion;
|
||||
this.location = location;
|
||||
this.architecture = architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -110,14 +112,12 @@ public class ImageImpl implements Image {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImageImpl [architecture=" + architecture + ", description=" + description + ", id="
|
||||
+ id + ", location=" + location + ", operatingSystem=" + operatingSystem
|
||||
+ ", version=" + version + "]";
|
||||
return "[id=" + id + ", version=" + version + ", location=" + location + ", architecture="
|
||||
+ architecture + ", operatingSystem=" + operatingSystem
|
||||
+ ", operatingSystemVersion=" + operatingSystemVersion + ", description="
|
||||
+ description + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,4 +168,12 @@ public class ImageImpl implements Image {
|
|||
return architecture;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getOperatingSystemVersion() {
|
||||
return operatingSystemVersion;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,13 +31,15 @@ import com.google.common.collect.Sets;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class SizeImpl implements Size {
|
||||
|
||||
private String id;
|
||||
private final int cores;
|
||||
private final int ram;
|
||||
private final int disk;
|
||||
private final Set<Architecture> supportedArchitectures = Sets.newHashSet();
|
||||
|
||||
public SizeImpl(int cores, int ram, int disk, Iterable<Architecture> supportedArchitectures) {
|
||||
public SizeImpl(String id, int cores, int ram, int disk,
|
||||
Iterable<Architecture> supportedArchitectures) {
|
||||
this.id = id;
|
||||
this.cores = cores;
|
||||
this.ram = ram;
|
||||
this.disk = disk;
|
||||
|
@ -74,6 +76,7 @@ public class SizeImpl implements Size {
|
|||
int result = 1;
|
||||
result = prime * result + cores;
|
||||
result = prime * result + disk;
|
||||
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||
result = prime * result + ram;
|
||||
result = prime * result
|
||||
+ ((supportedArchitectures == null) ? 0 : supportedArchitectures.hashCode());
|
||||
|
@ -93,6 +96,11 @@ public class SizeImpl implements Size {
|
|||
return false;
|
||||
if (disk != other.disk)
|
||||
return false;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
if (ram != other.ram)
|
||||
return false;
|
||||
if (supportedArchitectures == null) {
|
||||
|
@ -108,12 +116,10 @@ public class SizeImpl implements Size {
|
|||
this.getRam(), that.getRam()).compare(this.getDisk(), that.getDisk()).result();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Size [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]";
|
||||
return "[id=" + id + ", cores=" + cores + ", ram=" + ram + ", disk=" + disk
|
||||
+ ", supportedArchitectures=" + supportedArchitectures + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,4 +129,12 @@ public class SizeImpl implements Size {
|
|||
public boolean supportsArchitecture(Architecture architecture) {
|
||||
return supportedArchitectures.contains(architecture);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
package org.jclouds.compute.domain.internal;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class TemplateImpl implements Template {
|
||||
|
||||
private final Image image;
|
||||
private final Size size;
|
||||
|
||||
protected TemplateImpl(Image image, Size size) {
|
||||
this.image = image;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
TemplateImpl other = (TemplateImpl) obj;
|
||||
if (image == null) {
|
||||
if (other.image != null)
|
||||
return false;
|
||||
} else if (!image.equals(other.image))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TemplateImpl [image=" + image + ", size=" + size + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return new TemplateImpl(image, size);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,413 @@
|
|||
package org.jclouds.compute.internal;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.compute.domain.Architecture;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.domain.internal.TemplateImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.ResourceLocation;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class TemplateBuilderImpl implements TemplateBuilder {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Size> sizes;
|
||||
private String location;
|
||||
private OperatingSystem os;
|
||||
private Architecture arch;
|
||||
private String imageId;
|
||||
private String sizeId;
|
||||
|
||||
private String osVersion;
|
||||
private String imageVersion;
|
||||
private String imageDescription;
|
||||
|
||||
private int minCores;
|
||||
private int minRam;
|
||||
|
||||
private boolean biggest;
|
||||
private boolean fastest;
|
||||
|
||||
@Inject
|
||||
public TemplateBuilderImpl(@ResourceLocation String location, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes) {
|
||||
this.location = location;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
}
|
||||
|
||||
private final Predicate<Image> imageIdPredicate = new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (imageId != null) {
|
||||
returnVal = imageId.equals(input.getId());
|
||||
// match our input params so that the later predicates pass.
|
||||
if (returnVal) {
|
||||
fromImage(input);
|
||||
}
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
|
||||
private final Predicate<Image> locationPredicate = new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (location != null)
|
||||
returnVal = location.equals(input.getLocation());
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
|
||||
private final Predicate<Image> osPredicate = new Predicate<Image>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (os != null)
|
||||
returnVal = os.equals(input.getOperatingSystem());
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
};
|
||||
private final Predicate<Image> imageArchPredicate = new Predicate<Image>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (arch != null)
|
||||
returnVal = arch.equals(input.getArchitecture());
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
};
|
||||
private final Predicate<Image> osVersionPredicate = new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (osVersion != null) {
|
||||
if (input.getOperatingSystemVersion() == null)
|
||||
returnVal = false;
|
||||
else
|
||||
returnVal = input.getOperatingSystemVersion().matches(osVersion);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
private final Predicate<Image> imageVersionPredicate = new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (imageVersion != null) {
|
||||
if (input.getVersion() == null)
|
||||
returnVal = false;
|
||||
else
|
||||
returnVal = input.getVersion().matches(imageVersion);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
private final Predicate<Image> imageDescriptionPredicate = new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
boolean returnVal = true;
|
||||
if (imageDescription != null) {
|
||||
if (input.getDescription() == null)
|
||||
returnVal = false;
|
||||
else
|
||||
returnVal = input.getDescription().matches(imageDescription);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
|
||||
private final Predicate<Size> sizeIdPredicate = new Predicate<Size>() {
|
||||
@Override
|
||||
public boolean apply(Size input) {
|
||||
boolean returnVal = true;
|
||||
if (sizeId != null) {
|
||||
returnVal = sizeId.equals(input.getId());
|
||||
// match our input params so that the later predicates pass.
|
||||
if (returnVal) {
|
||||
fromSize(input);
|
||||
}
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
|
||||
private final Predicate<Image> imagePredicate = Predicates.and(imageIdPredicate,
|
||||
locationPredicate, osPredicate, imageArchPredicate, osVersionPredicate,
|
||||
imageVersionPredicate, imageDescriptionPredicate);
|
||||
|
||||
private final Predicate<Size> sizeArchPredicate = new Predicate<Size>() {
|
||||
@Override
|
||||
public boolean apply(Size input) {
|
||||
boolean returnVal = false;
|
||||
if (arch != null)
|
||||
returnVal = input.supportsArchitecture(arch);
|
||||
return returnVal;
|
||||
}
|
||||
};
|
||||
|
||||
private final Predicate<Size> sizeCoresPredicate = new Predicate<Size>() {
|
||||
@Override
|
||||
public boolean apply(Size input) {
|
||||
return input.getCores() >= TemplateBuilderImpl.this.minCores;
|
||||
}
|
||||
};
|
||||
|
||||
private final Predicate<Size> sizeRamPredicate = new Predicate<Size>() {
|
||||
@Override
|
||||
public boolean apply(Size input) {
|
||||
return input.getRam() >= TemplateBuilderImpl.this.minRam;
|
||||
}
|
||||
};
|
||||
private final Predicate<Size> sizePredicate = Predicates.and(sizeIdPredicate, sizeArchPredicate,
|
||||
sizeCoresPredicate, sizeRamPredicate);
|
||||
|
||||
static final Ordering<Size> DEFAULT_SIZE_ORDERING = new Ordering<Size>() {
|
||||
public int compare(Size left, Size right) {
|
||||
return ComparisonChain.start().compare(left.getCores(), right.getCores()).compare(
|
||||
left.getRam(), right.getRam()).compare(left.getDisk(), right.getDisk()).result();
|
||||
}
|
||||
};
|
||||
static final Ordering<Size> BY_CORES_ORDERING = new Ordering<Size>() {
|
||||
public int compare(Size left, Size right) {
|
||||
return Ints.compare(left.getCores(), right.getCores());
|
||||
}
|
||||
};
|
||||
static final Ordering<Image> DEFAULT_IMAGE_ORDERING = new Ordering<Image>() {
|
||||
public int compare(Image left, Image right) {
|
||||
return ComparisonChain.start().compare(left.getOperatingSystemVersion(),
|
||||
right.getOperatingSystemVersion()).compare(left.getVersion(), right.getVersion())
|
||||
.result();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder fromTemplate(Template template) {
|
||||
fromSize(template.getSize());
|
||||
fromImage(template.getImage());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder fromSize(Size size) {
|
||||
this.minCores = size.getCores();
|
||||
this.minRam = size.getRam();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder fromImage(Image image) {
|
||||
if (image.getLocation() != null)
|
||||
this.location = image.getLocation();
|
||||
if (image.getOperatingSystem() != null)
|
||||
this.os = image.getOperatingSystem();
|
||||
if (image.getOperatingSystemVersion() != null)
|
||||
this.osVersion = image.getOperatingSystemVersion();
|
||||
if (image.getVersion() != null)
|
||||
this.imageVersion = image.getVersion();
|
||||
if (image.getArchitecture() != null)
|
||||
this.arch = image.getArchitecture();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder smallest() {
|
||||
this.biggest = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder biggest() {
|
||||
this.biggest = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder fastest() {
|
||||
this.fastest = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder location(String location) {
|
||||
this.location = location;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder os(OperatingSystem os) {
|
||||
this.os = os;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder architecture(Architecture architecture) {
|
||||
this.arch = architecture;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template build() {
|
||||
logger.debug(">> searching params(%s)", this);
|
||||
Image image;
|
||||
try {
|
||||
image = DEFAULT_IMAGE_ORDERING.max(Iterables.filter(images, imagePredicate));
|
||||
} catch (NoSuchElementException exception) {
|
||||
throw new NoSuchElementException("image didn't match: " + toString() + "\n" + images);
|
||||
}
|
||||
logger.debug("<< matched image(%s)", image);
|
||||
// ensure we have an architecture matching
|
||||
this.arch = image.getArchitecture();
|
||||
|
||||
Ordering<Size> sizeOrdering = DEFAULT_SIZE_ORDERING;
|
||||
if (!biggest)
|
||||
sizeOrdering = sizeOrdering.reverse();
|
||||
if (fastest)
|
||||
sizeOrdering = Ordering.compound(ImmutableList.of(BY_CORES_ORDERING, sizeOrdering));
|
||||
Size size;
|
||||
try {
|
||||
size = sizeOrdering.max(Iterables.filter(sizes, sizePredicate));
|
||||
} catch (NoSuchElementException exception) {
|
||||
throw new NoSuchElementException("size didn't match: " + toString() + "\n" + sizes);
|
||||
}
|
||||
logger.debug("<< matched size(%s)", size);
|
||||
return new TemplateImpl(image, size) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder imageId(String imageId) {
|
||||
this.imageId = imageId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder imageDescriptionMatches(String descriptionRegex) {
|
||||
this.imageDescription = descriptionRegex;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder imageVersionMatches(String imageVersionRegex) {
|
||||
this.imageVersion = imageVersionRegex;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder minCores(int minCores) {
|
||||
this.minCores = minCores;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder minRam(int megabytes) {
|
||||
this.minRam = megabytes;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder osVersionMatches(String osVersionRegex) {
|
||||
this.osVersion = osVersionRegex;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public TemplateBuilder sizeId(String sizeId) {
|
||||
this.sizeId = sizeId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[arch=" + arch + ", biggest=" + biggest + ", fastest=" + fastest
|
||||
+ ", imageDescription=" + imageDescription + ", imageId=" + imageId
|
||||
+ ", imageVersion=" + imageVersion + ", location=" + location + ", minCores="
|
||||
+ minCores + ", minRam=" + minRam + ", os=" + os + ", osVersion=" + osVersion
|
||||
+ ", sizeId=" + sizeId + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -24,3 +24,5 @@ hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.compute.HostingDot
|
|||
hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder
|
||||
ec2.contextbuilder=org.jclouds.aws.ec2.compute.EC2ComputeServiceContextBuilder
|
||||
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
|
||||
# example of where to change your endpoint
|
||||
# ec2.endpoint=https://ec2.us-west-1.amazonaws.com
|
|
@ -32,11 +32,13 @@ import java.util.concurrent.TimeoutException;
|
|||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
@ -70,7 +72,6 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
abstract public void setServiceDefaults();
|
||||
|
||||
protected String service;
|
||||
protected OperatingSystem testOS;
|
||||
protected SshClient.Factory sshFactory;
|
||||
protected RunNodeOptions options = RunNodeOptions.Builder.openPorts(22);
|
||||
private String nodeName;
|
||||
|
@ -81,23 +82,12 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
protected ComputeService client;
|
||||
protected String user;
|
||||
protected String password;
|
||||
private Template template;
|
||||
|
||||
@BeforeGroups(groups = { "live" })
|
||||
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
|
||||
IOException {
|
||||
checkNotNull(testOS, "testOS");
|
||||
nodeName = checkNotNull(service, "service");
|
||||
if (canRunScript())
|
||||
options.runScript(new ScriptBuilder()
|
||||
// update add dns and install jdk
|
||||
.addStatement(
|
||||
Statements.exec("echo nameserver 208.67.222.222 >> /etc/resolv.conf"))
|
||||
.addStatement(Statements.exec("apt-get update"))//
|
||||
.addStatement(Statements.exec("apt-get upgrade -y"))//
|
||||
.addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))//
|
||||
.addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))//
|
||||
.addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))//
|
||||
.build(OsFamily.UNIX).getBytes());
|
||||
user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
|
||||
password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
|
||||
context = new ComputeServiceContextFactory().createContext(service, user, password,
|
||||
|
@ -110,12 +100,14 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
client = context.getComputeService();
|
||||
}
|
||||
|
||||
private boolean canRunScript() {
|
||||
return testOS == OperatingSystem.UBUNTU || testOS == OperatingSystem.JEOS;
|
||||
private boolean canRunScript(Template template) {
|
||||
return template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU
|
||||
|| template.getImage().getOperatingSystem() == OperatingSystem.JEOS;
|
||||
}
|
||||
|
||||
abstract protected Module getSshModule();
|
||||
|
||||
@Test(enabled = false)
|
||||
public void testCreate() throws Exception {
|
||||
try {
|
||||
client.destroyNode(Iterables.find(client.listNodes(), new Predicate<ComputeMetadata>() {
|
||||
|
@ -129,7 +121,19 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
} catch (NoSuchElementException e) {
|
||||
|
||||
}
|
||||
Template template = client.createTemplateInLocation("default").os(testOS).smallest();
|
||||
template = buildTemplate(client.templateBuilder());
|
||||
|
||||
if (canRunScript(template))
|
||||
options.runScript(new ScriptBuilder()
|
||||
// update add dns and install jdk
|
||||
.addStatement(
|
||||
Statements.exec("echo nameserver 208.67.222.222 >> /etc/resolv.conf"))
|
||||
.addStatement(Statements.exec("apt-get update"))//
|
||||
.addStatement(Statements.exec("apt-get upgrade -y"))//
|
||||
.addStatement(Statements.exec("apt-get install -y openjdk-6-jdk"))//
|
||||
.addStatement(Statements.exec("wget -qO/usr/bin/runurl run.alestic.com/runurl"))//
|
||||
.addStatement(Statements.exec("chmod 755 /usr/bin/runurl"))//
|
||||
.build(OsFamily.UNIX).getBytes());
|
||||
node = client.runNode(nodeName, template, options);
|
||||
assertNotNull(node.getId());
|
||||
assertEquals(node.getLoginPort(), 22);
|
||||
|
@ -142,7 +146,9 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
sshPing();
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
protected abstract Template buildTemplate(TemplateBuilder templateBuilder);
|
||||
|
||||
@Test(enabled = false, dependsOnMethods = "testCreate")
|
||||
public void testGet() throws Exception {
|
||||
NodeMetadata metadata = client.getNodeMetadata(node);
|
||||
assertEquals(metadata.getId(), node.getId());
|
||||
|
@ -153,7 +159,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
||||
}
|
||||
|
||||
public void testList() throws Exception {
|
||||
public void testListNodes() throws Exception {
|
||||
for (ComputeMetadata node : client.listNodes()) {
|
||||
assert node.getId() != null;
|
||||
assert node.getLocation() != null;
|
||||
|
@ -161,9 +167,10 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
}
|
||||
}
|
||||
|
||||
public void testListTemplates() throws Exception {
|
||||
for (Template template : client.listTemplates()) {
|
||||
assert template.getImage() != null;
|
||||
public void testListImages() throws Exception {
|
||||
for (Image image : client.listImages()) {
|
||||
assert image.getId() != null : image;
|
||||
assert image.getLocation() != null : image;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +204,7 @@ public abstract class BaseComputeServiceLiveTest {
|
|||
ssh.connect();
|
||||
ExecResponse hello = ssh.exec("echo hello");
|
||||
assertEquals(hello.getOutput().trim(), "hello");
|
||||
if (canRunScript())
|
||||
if (canRunScript(template))
|
||||
System.out.println(ssh.exec("java -version"));
|
||||
} finally {
|
||||
if (ssh != null)
|
||||
|
|
|
@ -18,15 +18,22 @@
|
|||
*/
|
||||
package org.jclouds.concurrent;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.ExecutionList;
|
||||
import com.google.common.util.concurrent.ForwardingFuture;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -38,6 +45,37 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
*/
|
||||
@Singleton
|
||||
public class ConcurrentUtils {
|
||||
|
||||
public static void pollResponsesAndLogWhenComplete(int total, String description, Logger logger,
|
||||
Set<Future<Void>> responses) throws InterruptedException, TimeoutException,
|
||||
ExecutionException {
|
||||
int complete = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
long timeOut = 180 * 1000;
|
||||
do {
|
||||
Set<Future<Void>> retries = Sets.newHashSet();
|
||||
for (Future<Void> future : responses) {
|
||||
try {
|
||||
future.get(100, TimeUnit.MILLISECONDS);
|
||||
complete++;
|
||||
} catch (ExecutionException e) {
|
||||
Throwables.propagate(e);
|
||||
} catch (TimeoutException e) {
|
||||
retries.add(future);
|
||||
}
|
||||
}
|
||||
responses = Sets.newHashSet(retries);
|
||||
} while (responses.size() > 0 && System.currentTimeMillis() < start + timeOut);
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
if (duration > timeOut)
|
||||
throw new TimeoutException(String.format("TIMEOUT: %s(%d/%d) rate: %f %s/second",
|
||||
description, complete, total, ((double) complete) / (duration / 1000.0),
|
||||
description));
|
||||
for (Future<Void> future : responses)
|
||||
future.get(30, TimeUnit.SECONDS);
|
||||
logger.debug("<< %s(%d)", description, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an exception into an object, which is useful for transforming to null or false.
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package org.jclouds.domain;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
/**
|
||||
* Related to the location of a resource
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*
|
||||
*/
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Qualifier
|
||||
public @interface ResourceLocation {
|
||||
|
||||
}
|
|
@ -36,12 +36,14 @@ import org.jclouds.compute.ComputeService;
|
|||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.ComputeType;
|
||||
import org.jclouds.compute.domain.CreateNodeResponse;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.LoginType;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
|
@ -145,18 +147,18 @@ public class RimuHostingComputeService implements ComputeService {
|
|||
rhClient.destroyServer(new Long(node.getId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<? extends Size> listSizes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Template> listTemplates() {
|
||||
public Set<? extends Image> listImages() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateBuilder templateBuilder() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
*/
|
||||
package org.jclouds.rimuhosting.miro.compute;
|
||||
|
||||
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
|
||||
import static org.jclouds.compute.domain.OperatingSystem.JEOS;
|
||||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -34,7 +36,10 @@ public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTes
|
|||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "rimuhosting";
|
||||
testOS = UBUNTU;
|
||||
}
|
||||
|
||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||
return templateBuilder.os(JEOS).osVersionMatches(".*9.04.*").smallest().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
</compute>
|
||||
</target>
|
||||
|
||||
<property name="location" value="default" />
|
||||
<property name="location" value="" />
|
||||
<target name="create" description="create the node ${nodename}">
|
||||
<property name="os" value="UBUNTU" />
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.jclouds.compute.ComputeServiceContext;
|
|||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
|
@ -75,11 +76,11 @@ public class ComputeTaskUtils {
|
|||
try {
|
||||
Properties props = new Properties();
|
||||
props.putAll(projectProvider.get().getProperties());
|
||||
return new ComputeServiceContextFactory().createContext(from, ImmutableSet.of(
|
||||
(Module) new AntLoggingModule(projectProvider.get(),
|
||||
return new ComputeServiceContextFactory().createContext(from,
|
||||
ImmutableSet
|
||||
.of((Module) new AntLoggingModule(projectProvider.get(),
|
||||
ComputeServiceConstants.COMPUTE_LOGGER),
|
||||
new JschSshClientModule()),
|
||||
props);
|
||||
new JschSshClientModule()), props);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -90,13 +91,15 @@ public class ComputeTaskUtils {
|
|||
}
|
||||
|
||||
static Template createTemplateFromElement(NodeElement nodeElement, ComputeService computeService) {
|
||||
Template template = computeService.createTemplateInLocation(nodeElement.getLocation());
|
||||
template.os(OperatingSystem.valueOf(nodeElement.getOs()));
|
||||
addSizeFromElementToTemplate(nodeElement, template);
|
||||
return template;
|
||||
TemplateBuilder templateBuilder = computeService.templateBuilder();
|
||||
if (nodeElement.getLocation() != null && !"".equals(nodeElement.getLocation()))
|
||||
templateBuilder.location(nodeElement.getLocation());
|
||||
templateBuilder.os(OperatingSystem.valueOf(nodeElement.getOs()));
|
||||
addSizeFromElementToTemplate(nodeElement, templateBuilder);
|
||||
return templateBuilder.build();
|
||||
}
|
||||
|
||||
static void addSizeFromElementToTemplate(NodeElement nodeElement, Template template) {
|
||||
static void addSizeFromElementToTemplate(NodeElement nodeElement, TemplateBuilder template) {
|
||||
if (nodeElement.getSize().equalsIgnoreCase("smallest")) {
|
||||
template.smallest();
|
||||
} else if (nodeElement.getSize().equalsIgnoreCase("fastest")) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public class NodeElement {
|
|||
private String hostproperty;
|
||||
private String idproperty;
|
||||
private String usernameproperty;
|
||||
private String location = "default";
|
||||
private String location;
|
||||
private File runscript;
|
||||
|
||||
public String getLocation() {
|
||||
|
|
|
@ -28,7 +28,6 @@ import java.net.InetAddress;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
|
@ -45,6 +44,7 @@ import org.jclouds.compute.domain.NodeMetadata;
|
|||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
import org.jclouds.compute.options.RunNodeOptions;
|
||||
|
@ -76,9 +76,9 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
|
|||
protected Logger logger = Logger.NULL;
|
||||
private final VCloudClient client;
|
||||
protected final Provider<Set<? extends Image>> images;
|
||||
protected final Provider<SortedSet<? extends Size>> sizes;
|
||||
private final Provider<Set<? extends VCloudTemplate>> templates;
|
||||
|
||||
protected final Provider<Set<? extends Size>> sizes;
|
||||
protected final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
private final Predicate<String> taskTester;
|
||||
@Inject(optional = true)
|
||||
private SshClient.Factory sshFactory;
|
||||
private Predicate<InetSocketAddress> socketTester;
|
||||
|
@ -90,15 +90,15 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
|
|||
NodeState.PENDING).build();
|
||||
|
||||
@Inject
|
||||
public VCloudComputeService(VCloudClient client, Provider<Set<? extends Image>> images,
|
||||
Provider<SortedSet<? extends Size>> sizes,
|
||||
Provider<Set<? extends VCloudTemplate>> templates, Predicate<String> successTester,
|
||||
Predicate<InetSocketAddress> socketTester) {
|
||||
public VCloudComputeService(VCloudClient client,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Predicate<String> successTester, Predicate<InetSocketAddress> socketTester) {
|
||||
this.taskTester = successTester;
|
||||
this.client = client;
|
||||
this.images = images;
|
||||
this.sizes = sizes;
|
||||
this.templates = templates;
|
||||
this.templateBuilderProvider = templateBuilderProvider;
|
||||
this.socketTester = socketTester;
|
||||
}
|
||||
|
||||
|
@ -204,22 +204,20 @@ public class VCloudComputeService implements ComputeService, VCloudComputeClient
|
|||
}
|
||||
|
||||
@Override
|
||||
public Template createTemplateInLocation(String location) {
|
||||
return new VCloudTemplate(client, images.get(), sizes.get(), location);
|
||||
public TemplateBuilder templateBuilder() {
|
||||
return templateBuilderProvider.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<? extends Size> listSizes() {
|
||||
public Set<? extends Size> listSizes() {
|
||||
return sizes.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends Template> listTemplates() {
|
||||
return templates.get();
|
||||
public Set<? extends Image> listImages() {
|
||||
return images.get();
|
||||
}
|
||||
|
||||
private final Predicate<String> taskTester;
|
||||
|
||||
public Map<String, String> start(String vDCId, String name, String templateId, int minCores,
|
||||
int minMegs, Long diskSize, Map<String, String> properties, int... portsToOpen) {
|
||||
logger
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
package org.jclouds.vcloud.compute;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class VCloudTemplate implements Template {
|
||||
private final VCloudClient client;
|
||||
private final Set<? extends Image> images;
|
||||
private final Set<? extends Size> sizes;
|
||||
private Size size;
|
||||
private String vDC;
|
||||
private OperatingSystem operatingSystem;
|
||||
private transient Image image;
|
||||
|
||||
public VCloudTemplate(VCloudClient client,
|
||||
Set<? extends Image> images, Set<? extends Size> 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<? extends Image> images, OperatingSystem operatingSystem) {
|
||||
for (Image image : images) {
|
||||
if (image.getOperatingSystem() == operatingSystem)
|
||||
return image;
|
||||
}
|
||||
throw new RuntimeException("no configured image matches os: " + operatingSystem);
|
||||
}
|
||||
|
||||
VCloudTemplate(VCloudClient client, Set<? extends Image> images,
|
||||
Set<? extends Size> sizes, String location) {
|
||||
this(client, images, sizes, location, null, OperatingSystem.CENTOS, null);// note the default
|
||||
// os
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template smallest() {
|
||||
this.size = Iterables.get(sizes, 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template biggest() {
|
||||
this.size = Iterables.getLast(sizes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template fastest() {
|
||||
this.size = Iterables.getLast(sizes);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template inLocation(String location) {
|
||||
if (location.equalsIgnoreCase("default"))
|
||||
location = client.getDefaultVDC().getId();
|
||||
this.vDC = location;// TODO match vdc on template as well arch
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Template os(OperatingSystem os) {
|
||||
this.operatingSystem = os;
|
||||
this.image = resolveTemplate(images, operatingSystem);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
return new VCloudTemplate(client, images, sizes, vDC, size, operatingSystem,
|
||||
image);
|
||||
}
|
||||
|
||||
public String getvDC() {
|
||||
return vDC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((image == null) ? 0 : image.hashCode());
|
||||
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
|
||||
result = prime * result + ((size == null) ? 0 : size.hashCode());
|
||||
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
VCloudTemplate other = (VCloudTemplate) obj;
|
||||
if (image == null) {
|
||||
if (other.image != null)
|
||||
return false;
|
||||
} else if (!image.equals(other.image))
|
||||
return false;
|
||||
if (operatingSystem == null) {
|
||||
if (other.operatingSystem != null)
|
||||
return false;
|
||||
} else if (!operatingSystem.equals(other.operatingSystem))
|
||||
return false;
|
||||
if (size == null) {
|
||||
if (other.size != null)
|
||||
return false;
|
||||
} else if (!size.equals(other.size))
|
||||
return false;
|
||||
if (vDC == null) {
|
||||
if (other.vDC != null)
|
||||
return false;
|
||||
} else if (!vDC.equals(other.vDC))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
|
||||
+ ", size=" + size + ", vDC=" + vDC + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -19,12 +19,10 @@
|
|||
package org.jclouds.vcloud.compute.config;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
@ -41,6 +39,8 @@ import org.jclouds.compute.domain.internal.ImageImpl;
|
|||
import org.jclouds.compute.domain.internal.SizeImpl;
|
||||
import org.jclouds.compute.internal.ComputeServiceContextImpl;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.concurrent.ConcurrentUtils;
|
||||
import org.jclouds.domain.ResourceLocation;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.vcloud.VCloudAsyncClient;
|
||||
|
@ -48,16 +48,13 @@ import org.jclouds.vcloud.VCloudClient;
|
|||
import org.jclouds.vcloud.VCloudMediaType;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeService;
|
||||
import org.jclouds.vcloud.compute.VCloudTemplate;
|
||||
import org.jclouds.vcloud.config.VCloudContextModule;
|
||||
import org.jclouds.vcloud.domain.Catalog;
|
||||
import org.jclouds.vcloud.domain.CatalogItem;
|
||||
import org.jclouds.vcloud.domain.NamedResource;
|
||||
import org.jclouds.vcloud.domain.VAppTemplate;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -93,6 +90,13 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
return new ComputeServiceContextImpl<VCloudAsyncClient, VCloudClient>(computeService, context);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@ResourceLocation
|
||||
String getVDC(VCloudClient client) {
|
||||
return client.getDefaultVDC().getId();
|
||||
}
|
||||
|
||||
protected static class LogHolder {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
|
@ -101,13 +105,12 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends Image> provideImages(final VCloudClient client, LogHolder holder,
|
||||
ExecutorService executor) throws InterruptedException, ExecutionException,
|
||||
TimeoutException {
|
||||
protected Set<? extends Image> provideImages(final VCloudClient client,
|
||||
final @ResourceLocation String vDC, LogHolder holder, ExecutorService executor)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
final Set<Image> images = Sets.newHashSet();
|
||||
holder.logger.debug(">> providing images");
|
||||
Catalog response = client.getDefaultCatalog();
|
||||
final String vDC = client.getDefaultVDC().getId();
|
||||
Set<Future<Void>> responses = Sets.newHashSet();
|
||||
|
||||
for (final NamedResource resource : response.values()) {
|
||||
|
@ -117,9 +120,9 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
responses.add(executor.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
OperatingSystem myOs = OperatingSystem.UNKNOWN;
|
||||
OperatingSystem myOs = null;
|
||||
for (OperatingSystem os : OperatingSystem.values()) {
|
||||
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(
|
||||
if (resource.getName().toLowerCase().replaceAll("\\s", "").indexOf(
|
||||
os.toString()) != -1) {
|
||||
myOs = os;
|
||||
}
|
||||
|
@ -127,73 +130,31 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
|
|||
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
|
||||
: Architecture.X86_64;
|
||||
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
|
||||
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs,
|
||||
null, vDC, arch));
|
||||
images.add(new ImageImpl(resource.getId(), template.getName(), "", myOs,
|
||||
template.getName(), vDC, arch));
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
pollResponsesAndLogWhenComplete(images.size(), "images", holder, responses);
|
||||
ConcurrentUtils.pollResponsesAndLogWhenComplete(images.size(), "images", holder.logger,
|
||||
responses);
|
||||
return images;
|
||||
}
|
||||
|
||||
protected void pollResponsesAndLogWhenComplete(int total, String description, LogHolder holder,
|
||||
Set<Future<Void>> responses) throws InterruptedException, TimeoutException,
|
||||
ExecutionException {
|
||||
int complete = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
long timeOut = 60 * 1000;
|
||||
do {
|
||||
Set<Future<Void>> retries = Sets.newHashSet();
|
||||
for (Future<Void> future : responses) {
|
||||
try {
|
||||
future.get(100, TimeUnit.MILLISECONDS);
|
||||
complete++;
|
||||
} catch (ExecutionException e) {
|
||||
Throwables.propagate(e);
|
||||
} catch (TimeoutException e) {
|
||||
retries.add(future);
|
||||
}
|
||||
}
|
||||
responses = Sets.newHashSet(retries);
|
||||
} while (responses.size() > 0 && System.currentTimeMillis() < start + timeOut);
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
if (duration > timeOut)
|
||||
throw new TimeoutException(String.format("TIMEOUT: %s(%d/%d) rate: %f %s/second%n",
|
||||
description, complete, total, ((double) complete) / (duration / 1000.0),
|
||||
description));
|
||||
for (Future<Void> future : responses)
|
||||
future.get(30, TimeUnit.SECONDS);
|
||||
holder.logger.debug("<< %s(%d) rate: %f %s/second%n", description, total, ((double) complete)
|
||||
/ (duration / 1000.0), description);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected SortedSet<? extends Size> provideSizes(VCloudClient client,
|
||||
Set<? extends Image> images, LogHolder holder, ExecutorService executor)
|
||||
throws InterruptedException, TimeoutException, ExecutionException {
|
||||
return ImmutableSortedSet.of(new SizeImpl(1, 512, 10, ImmutableSet.<Architecture> of(
|
||||
Architecture.X86_32, Architecture.X86_64)));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected Set<? extends VCloudTemplate> provideTemplates(VCloudClient client,
|
||||
Set<? extends Image> images, SortedSet<? extends Size> sizes, LogHolder holder) {
|
||||
Set<VCloudTemplate> templates = Sets.newHashSet();
|
||||
holder.logger.debug(">> generating templates");
|
||||
String vDC = client.getDefaultVDC().getId();
|
||||
for (Size size : sizes) {
|
||||
for (Image image : images) {
|
||||
templates.add(new VCloudTemplate(client, images, sizes, vDC, size, image
|
||||
.getOperatingSystem(), image));
|
||||
}
|
||||
}
|
||||
holder.logger.debug("<< templates(%d)", templates.size());
|
||||
return templates;
|
||||
protected Set<? extends Size> provideSizes(VCloudClient client, Set<? extends Image> images,
|
||||
LogHolder holder, ExecutorService executor) throws InterruptedException,
|
||||
TimeoutException, ExecutionException {
|
||||
Set<Size> sizes = Sets.newHashSet();
|
||||
for (int cpus : new int[] { 1, 2, 4 })
|
||||
for (int ram : new int[] { 512, 1024, 2048, 4096, 8192, 16384 })
|
||||
sizes.add(new SizeImpl(String.format("cpu=%d,ram=%s,disk=%d", cpus, ram, 10), cpus,
|
||||
ram, 10, ImmutableSet.<Architecture> of(Architecture.X86_32,
|
||||
Architecture.X86_64)));
|
||||
return sizes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
@ -13,9 +12,9 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.vcloud.VCloudClient;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeService;
|
||||
import org.jclouds.vcloud.compute.VCloudTemplate;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.hostingdotcom.domain.HostingDotComVApp;
|
||||
|
||||
|
@ -29,11 +28,11 @@ import com.google.common.collect.ImmutableMap;
|
|||
public class HostingDotComVCloudComputeService extends VCloudComputeService {
|
||||
|
||||
@Inject
|
||||
public HostingDotComVCloudComputeService(VCloudClient client,
|
||||
Provider<Set<? extends Image>> images, Provider<SortedSet<? extends Size>> sizes,
|
||||
Provider<Set<? extends VCloudTemplate>> templates, Predicate<String> successTester,
|
||||
Predicate<InetSocketAddress> socketTester) {
|
||||
super(client, images, sizes, templates, successTester, socketTester);
|
||||
HostingDotComVCloudComputeService(VCloudClient client,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Predicate<String> successTester, Predicate<InetSocketAddress> socketTester) {
|
||||
super(client, templateBuilderProvider, images, sizes, successTester, socketTester);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,8 @@ package org.jclouds.vcloud.hostingdotcom.compute;
|
|||
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
|
||||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -37,7 +39,10 @@ public class HostingDotComVCloudComputeServiceLiveTest extends BaseComputeServic
|
|||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "hostingdotcom";
|
||||
testOS = CENTOS;
|
||||
}
|
||||
|
||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||
return templateBuilder.os(CENTOS).smallest().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,10 +34,10 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.Size;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeService;
|
||||
import org.jclouds.vcloud.compute.VCloudTemplate;
|
||||
import org.jclouds.vcloud.domain.VApp;
|
||||
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
|
||||
import org.jclouds.vcloud.terremark.domain.InternetService;
|
||||
|
@ -62,10 +62,10 @@ public class TerremarkVCloudComputeService extends VCloudComputeService {
|
|||
|
||||
@Inject
|
||||
public TerremarkVCloudComputeService(TerremarkVCloudClient client,
|
||||
Provider<Set<? extends Image>> images, Provider<SortedSet<? extends Size>> sizes,
|
||||
Provider<Set<? extends VCloudTemplate>> templates, Predicate<String> successTester,
|
||||
Predicate<InetSocketAddress> socketTester) {
|
||||
super(client, images, sizes, templates, successTester, socketTester);
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<Set<? extends Image>> images, Provider<Set<? extends Size>> sizes,
|
||||
Predicate<String> successTester, Predicate<InetSocketAddress> socketTester) {
|
||||
super(client, templateBuilderProvider, images, sizes, successTester, socketTester);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
|
|||
private static class ComputeOptionsToSize implements Function<ComputeOptions, Size> {
|
||||
@Override
|
||||
public Size apply(ComputeOptions from) {
|
||||
return new SizeImpl(from.getProcessorCount(), from.getMemory(), 10, ImmutableSet
|
||||
.<Architecture> of(Architecture.X86_32, Architecture.X86_64));
|
||||
return new SizeImpl(from.toString(), from.getProcessorCount(), from.getMemory(), 10,
|
||||
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ import static org.jclouds.compute.domain.OperatingSystem.JEOS;
|
|||
|
||||
import org.jclouds.compute.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||
import org.jclouds.vcloud.compute.VCloudComputeClient;
|
||||
|
@ -39,11 +41,15 @@ import org.testng.annotations.Test;
|
|||
*/
|
||||
@Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
|
||||
public class TerremarkVCloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setServiceDefaults() {
|
||||
service = "terremark";
|
||||
testOS = JEOS;
|
||||
}
|
||||
|
||||
protected Template buildTemplate(TemplateBuilder templateBuilder) {
|
||||
return templateBuilder.os(JEOS).osVersionMatches(".*9.04.*").smallest().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue