Issue 130: properly modeled node and templates

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2702 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-20 11:34:24 +00:00
parent 2c373ed68e
commit 2e213ae223
38 changed files with 1936 additions and 508 deletions

View File

@ -24,7 +24,6 @@ import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyNam
import static org.jclouds.scriptbuilder.domain.Statements.exec; import static org.jclouds.scriptbuilder.domain.Statements.exec;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
@ -32,26 +31,26 @@ import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.domain.Region; import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.domain.InstanceState; import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.IpProtocol; import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair; import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.RunningInstance; import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
@ -62,7 +61,6 @@ import org.jclouds.scriptbuilder.ScriptBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily; import org.jclouds.scriptbuilder.domain.OsFamily;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
@ -78,67 +76,40 @@ public class EC2ComputeService implements ComputeService {
@Named(ComputeServiceConstants.COMPUTE_LOGGER) @Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final EC2Client ec2Client; private final EC2Client ec2Client;
private final Set<EC2Size> sizes;
private final Provider<Set<EC2Template>> templates;
private final Predicate<RunningInstance> instanceStateRunning; private final Predicate<RunningInstance> instanceStateRunning;
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata; private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
private final Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
@Inject @Inject
public EC2ComputeService(EC2Client tmClient, Predicate<RunningInstance> instanceStateRunning, public EC2ComputeService(EC2Client client, Set<EC2Size> sizes,
Provider<Set<EC2Template>> templates,
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
Predicate<RunningInstance> instanceStateRunning,
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) { RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
this.ec2Client = tmClient; this.ec2Client = client;
this.sizes = sizes;
this.templates = templates; // delayed intentionally, as generation is slow
this.imageAmiIdMap = imageAmiIdMap;
this.instanceStateRunning = instanceStateRunning; this.instanceStateRunning = instanceStateRunning;
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata; this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
} }
private Map<InstanceType, Map<Image, Map<Region, String>>> imageAmiIdMap = ImmutableMap
.<InstanceType, Map<Image, Map<Region, String>>> of(InstanceType.M1_SMALL,//
ImmutableMap.<Image, Map<Region, String>> builder().put(
Image.UBUNTU_90,
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
Region.EU_WEST_1, "ami-a62a01d2")).put(
Image.RHEL_53,
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
"ami-368b685f")).build(),//
InstanceType.C1_MEDIUM,//
ImmutableMap.<Image, Map<Region, String>> builder().put(
Image.UBUNTU_90,
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
Region.EU_WEST_1, "ami-a62a01d2")).put(
Image.RHEL_53,
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
"ami-368b685f")).build(), //
InstanceType.C1_XLARGE,//
ImmutableMap.<Image, Map<Region, String>> builder().put(
Image.UBUNTU_90,
ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1,
"ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e",
Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami
private Map<Profile, InstanceType> profileInstanceTypeMap = ImmutableMap
.<Profile, InstanceType> builder().put(Profile.SMALLEST, InstanceType.M1_SMALL).put(
Profile.MEDIUM, InstanceType.C1_MEDIUM).put(Profile.FASTEST,
InstanceType.C1_XLARGE).build();
private static Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap private static Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING) .<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING)
.put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN, .put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN,
NodeState.PENDING).put(InstanceState.TERMINATED, NodeState.TERMINATED).build(); NodeState.PENDING).put(InstanceState.TERMINATED, NodeState.TERMINATED).build();
@Override @Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, public CreateNodeResponse runNode(String name, Template template) {
Image image) { checkArgument(template instanceof EC2Template,
Region region = Region.fromValue(location); "unexpected template type. should be EC2Template, was: " + template.getClass());
EC2Template ec2Template = (EC2Template) template;
InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile), KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name);
"profile not supported: " + profile);
String ami = checkNotNull(checkNotNull(
checkNotNull(imageAmiIdMap.get(type), "type not supported: " + type).get(image),
"image not supported: " + image).get(region), "region not supported: " + region);
KeyPair keyPair = createKeyPairInRegion(region, name);
String securityGroupName = name; String securityGroupName = name;
createSecurityGroupInRegion(region, securityGroupName, 22, 80, 8080, 443); createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, 22, 80, 8080, 443);
String script = new ScriptBuilder() // update and install jdk String script = new ScriptBuilder() // update and install jdk
.addStatement(exec("apt-get update"))// .addStatement(exec("apt-get update"))//
@ -149,14 +120,13 @@ public class EC2ComputeService implements ComputeService {
.build(OsFamily.UNIX); .build(OsFamily.UNIX);
logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)", logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)",
region, ami, type, keyPair.getKeyName(), securityGroupName); ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize()
.getInstanceType(), keyPair.getKeyName(), securityGroupName);
RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices() RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices()
.runInstancesInRegion(region, null, ami, 1, 1, withKeyName(keyPair.getKeyName())// key .runInstancesInRegion(ec2Template.getRegion(), null, ec2Template.getImage().getId(),
// I 1, 1, withKeyName(keyPair.getKeyName())// key
// created .asType(ec2Template.getSize().getInstanceType())// instance size
// above
.asType(type)// instance size
.withSecurityGroup(securityGroupName)// group I created above .withSecurityGroup(securityGroupName)// group I created above
.withAdditionalInfo(name)// description .withAdditionalInfo(name)// description
.withUserData(script.getBytes()) // script to run as root .withUserData(script.getBytes()) // script to run as root
@ -166,18 +136,29 @@ public class EC2ComputeService implements ComputeService {
logger.debug("<< running instance(%s)", runningInstance.getId()); logger.debug("<< running instance(%s)", runningInstance.getId());
// refresh to get IP address // refresh to get IP address
runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId()); runningInstance = getOnlyRunningInstanceInRegion(ec2Template.getRegion(), runningInstance
.getId());
Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet
.<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress()); .<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress());
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
.<InetAddress> of() .<InetAddress> of()
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress()); : ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion() return new CreateNodeResponseImpl(
.toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState runningInstance.getId(),
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22, name,
LoginType.SSH, new Credentials(image == Image.UBUNTU_90 ? "ubuntu" : "root", keyPair runningInstance.getRegion().toString(),
.getKeyMaterial()), ImmutableMap.<String, String> of()); 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());
} }
private KeyPair createKeyPairInRegion(Region region, String name) { private KeyPair createKeyPairInRegion(Region region, String name) {
@ -205,13 +186,13 @@ public class EC2ComputeService implements ComputeService {
try { try {
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name); ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name);
logger.debug("<< created securityGroup(%s)", name); logger.debug("<< created securityGroup(%s)", name);
logger.debug(">> authorizing securityGroup region(%s) name(%s) ports(%s)", region, name,
Joiner.on(',').join(Arrays.asList(ports)));
for (int port : ports) { for (int port : ports) {
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name,
port);
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region, ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region,
name, IpProtocol.TCP, port, port, "0.0.0.0/0"); name, IpProtocol.TCP, port, port, "0.0.0.0/0");
}
logger.debug("<< authorized securityGroup(%s)", name); logger.debug("<< authorized securityGroup(%s)", name);
}
} catch (AWSResponseException e) { } catch (AWSResponseException e) {
if (e.getError().getCode().equals("InvalidGroup.Duplicate")) { if (e.getError().getCode().equals("InvalidGroup.Duplicate")) {
logger.debug("<< reused securityGroup(%s)", name); logger.debug("<< reused securityGroup(%s)", name);
@ -335,7 +316,17 @@ public class EC2ComputeService implements ComputeService {
} }
@Override @Override
public Map<String, Size> getSizes() { public Set<EC2Size> listSizes() {
throw new UnsupportedOperationException(); return sizes;
}
@Override
public Set<EC2Template> listTemplates() {
return templates.get();
}
@Override
public Template createTemplateInLocation(String location) {
return new EC2Template(ec2Client, imageAmiIdMap, location);
} }
} }

View File

@ -0,0 +1,88 @@
/**
*
* 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.aws.ec2.domain.InstanceType;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.internal.SizeImpl;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
public class EC2Size extends SizeImpl {
private final InstanceType instanceType;
EC2Size(InstanceType instanceType, Integer cores, Integer ram, Integer disk,
Iterable<Architecture> supportedArchitectures) {
super(cores, ram, disk, supportedArchitectures);
this.instanceType = instanceType;
}
/**
* Returns the EC2 InstanceType associated with this size.
*/
public InstanceType getInstanceType() {
return instanceType;
}
/**
* @see InstanceType#M1_SMALL
*/
public static final EC2Size M1_SMALL = new EC2Size(InstanceType.M1_SMALL, 1, 1740, 160,
ImmutableSet.of(Architecture.X86_32));
/**
* @see InstanceType#M1_LARGE
*/
public static final EC2Size M1_LARGE = new EC2Size(InstanceType.M1_LARGE, 4, 7680, 850,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#M1_XLARGE
*/
public static final EC2Size M1_XLARGE = new EC2Size(InstanceType.M1_XLARGE, 8, 15360, 1690,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#M2_2XLARGE
*/
public static final EC2Size M2_2XLARGE = new EC2Size(InstanceType.M2_2XLARGE, 13, 35020, 850,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#M2_4XLARGE
*/
public static final EC2Size M2_4XLARGE = new EC2Size(InstanceType.M2_4XLARGE, 26, 70041, 1690,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#C1_MEDIUM
*/
public static final EC2Size C1_MEDIUM = new EC2Size(InstanceType.C1_MEDIUM, 5, 1740, 350,
ImmutableSet.of(Architecture.X86_32));
/**
* @see InstanceType#C1_XLARGE
*/
public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20, 7168, 1690,
ImmutableSet.of(Architecture.X86_64));
}

View File

@ -0,0 +1,233 @@
/**
*
* 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;
}
}

View File

@ -18,17 +18,33 @@
*/ */
package org.jclouds.aws.ec2.compute.config; package org.jclouds.aws.ec2.compute.config;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2AsyncClient; import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client; import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.EC2ComputeService; import org.jclouds.aws.ec2.compute.EC2ComputeService;
import org.jclouds.aws.ec2.compute.EC2Size;
import org.jclouds.aws.ec2.compute.EC2Template;
import org.jclouds.aws.ec2.config.EC2ContextModule; import org.jclouds.aws.ec2.config.EC2ContextModule;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -51,4 +67,63 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
return new ComputeServiceContextImpl<EC2AsyncClient, EC2Client>(computeService, context); return new ComputeServiceContextImpl<EC2AsyncClient, EC2Client>(computeService, context);
} }
@Provides
@Singleton
Set<EC2Size> provideSizes() {
return ImmutableSet.<EC2Size> of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
@Provides
@Singleton
Set<EC2Template> provideTemplates(EC2Client client, Set<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;
}
@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
}
} }

View File

@ -20,16 +20,31 @@ package org.jclouds.aws.ec2.util;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; 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.domain.Region;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.domain.AvailabilityZone; 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 org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.inject.internal.Iterables;
/** /**
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class EC2Utils { 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, public static void indexStringArrayToFormValuesWithPrefix(GeneratedHttpRequest<?> request,
String prefix, Object input) { String prefix, Object input) {
checkArgument(checkNotNull(input, "input") instanceof String[], checkArgument(checkNotNull(input, "input") instanceof String[],

View File

@ -19,6 +19,7 @@
package org.jclouds.aws.ec2.compute; package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
@ -29,15 +30,16 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
@ -61,31 +63,34 @@ import com.google.inject.Injector;
*/ */
@Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest") @Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest")
public class EC2ComputeServiceLiveTest { public class EC2ComputeServiceLiveTest {
private static final String service = "ec2";
protected SshClient.Factory sshFactory; protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name") + ".ec2serv"; private String nodeName = System.getProperty("user.name") + service;
private RetryablePredicate<InetSocketAddress> socketTester; private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node; private CreateNodeResponse node;
private ComputeServiceContext context; private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException { IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = new ComputeServiceContextFactory().createContext("ec2", user, password, context = new ComputeServiceContextFactory().createContext(service, user, password,
ImmutableSet.of(new Log4JLoggingModule()), new Properties()); ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule()); Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
} }
public void testCreate() throws Exception { public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix, Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest();
Profile.SMALLEST, Image.UBUNTU_90); node = client.runNode(nodeName, template);
assertNotNull(node.getId()); assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH); assertEquals(node.getLoginType(), LoginType.SSH);
@ -100,7 +105,7 @@ public class EC2ComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate") @Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception { public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType()); assertEquals(metadata.getLoginType(), node.getLoginType());
@ -110,13 +115,27 @@ public class EC2ComputeServiceLiveTest {
} }
public void testList() throws Exception { public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) { for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null; assert node.getId() != null;
assert node.getLocation() != null; assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE); assertEquals(node.getType(), ComputeType.NODE);
} }
} }
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException { private void sshPing() throws IOException {
try { try {
doCheckKey(); doCheckKey();
@ -150,7 +169,7 @@ public class EC2ComputeServiceLiveTest {
@AfterTest @AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException { void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null) if (node != null)
context.getComputeService().destroyNode(node); client.destroyNode(node);
context.close(); context.close();
} }

View File

@ -46,6 +46,32 @@
</layout> </layout>
</appender> </appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
@ -72,6 +98,12 @@
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!--======================= --> <!--======================= -->
<!-- Setup the Root category --> <!-- Setup the Root category -->
<!-- ======================= --> <!-- ======================= -->

View File

@ -18,15 +18,13 @@
*/ */
package org.jclouds.compute; package org.jclouds.compute;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
/** /**
* Provides portable access to launching compute instances. * Provides portable access to launching compute instances.
@ -35,23 +33,34 @@ import org.jclouds.compute.domain.Size;
* @author Ivan Meredith * @author Ivan Meredith
*/ */
public interface ComputeService { public interface ComputeService {
/**
* Creates a new template in the specified location.
*
* @param location
* where the template is valid for
*/
Template createTemplateInLocation(String location);
/** /**
* List all sizes available to the current user * List all sizes available to the current user
*/ */
Map<String, Size> getSizes(); Set<? extends Size> listSizes();
/**
* List all templates available to the current user
*/
Set<? extends Template> listTemplates();
/** /**
* List all nodes available to the current user * List all nodes available to the current user
*/ */
Set<ComputeMetadata> listNodes(); Set<? extends ComputeMetadata> listNodes();
/** /**
* Create a new node given the name, size, and Image * Create a new node given the name, and template
* *
*/ */
CreateNodeResponse startNodeInLocation(String location, String name, Profile size, Image image); CreateNodeResponse runNode(String name, Template template);
/** /**
* destroy the node. * destroy the node.

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
@ -23,29 +23,19 @@
*/ */
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
import java.util.Map;
/** /**
* Configured operating system used to start nodes. * Architecture of a node
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface Image { public enum Architecture {
/**
* Unique ID provided by the provider (ami-abcd1234, etc)
*
*/
String getId();
/** /**
* Name provided by the provider (Ubuntu 8.1) * 32-bit platform
*
*/ */
String getName(); X86_32,
/** /**
* Other variables present that the provider supports * 64-bit platform
*/ */
Map<String, String> getExtra(); X86_64;
} }

View File

@ -1,26 +1,63 @@
/** /**
* *
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
* *
* ==================================================================== * ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed to the Apache Software Foundation (ASF) under one
* you may not use this file except in compliance with the License. * or more contributor license agreements. See the NOTICE file
* You may obtain a copy of the License at * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing,
* distributed under the License is distributed on an "AS IS" BASIS, * software distributed under the License is distributed on an
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* See the License for the specific language governing permissions and * KIND, either express or implied. See the License for the
* limitations under the License. * specific language governing permissions and limitations
* under the License.
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
/** /**
* Running Operating system
*
* @author Adrian Cole * @author Adrian Cole
*/ */
public enum Image { public interface Image {
CENTOS_53, RHEL_53, UBUNTU_90, UBUNTU_JEOS_90, WEBAPPVM_93
/**
* Unique ID provided by the provider (ami-abcd1234, etc)
*
*/
String getId();
/**
* Description of the image
*/
String getDescription();
/**
* Operating System
*/
OperatingSystem getOperatingSystem();
/**
* Version of the image
*/
String getVersion();
/**
* Geographic location of the image.
*/
String getLocation();
/**
* Operating System
*/
Architecture getArchitecture();
} }

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
* *
* ==================================================================== * ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one * Licensed to the Apache Software Foundation (ASF) under one
@ -24,10 +24,11 @@
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
/** /**
* Running Operating system
*
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface Profile { public enum OperatingSystem {
Image getImage();
Size getSize(); CENTOS, RHEL, UBUNTU, WINDOWS, UNKNOWN;
} }

View File

@ -1,40 +1,34 @@
/** /**
* *
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> * Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
* *
* ==================================================================== * ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed to the Apache Software Foundation (ASF) under one
* you may not use this file except in compliance with the License. * or more contributor license agreements. See the NOTICE file
* You may obtain a copy of the License at * distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing,
* distributed under the License is distributed on an "AS IS" BASIS, * software distributed under the License is distributed on an
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* See the License for the specific language governing permissions and * KIND, either express or implied. See the License for the
* limitations under the License. * specific language governing permissions and limitations
* under the License.
* ==================================================================== * ====================================================================
*/ */
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
import java.util.Map;
/** /**
* Configured operating system used to start nodes. * Size of a node.
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface Size { public interface Size extends Comparable<Size> {
/**
* provider-specific identifier (m1.small, etc)
*/
String getId();
/**
* Name provided by the provider (Small CPU, etc)
*/
String getName();
/** /**
* Amount of virtual or physical cores provided * Amount of virtual or physical cores provided
@ -44,26 +38,15 @@ public interface Size {
/** /**
* Amount of RAM provided in MB (256M, 1740) * Amount of RAM provided in MB (256M, 1740)
*/ */
Long getRam(); Integer getRam();
/** /**
* Amount of boot disk provided in GB (200) * Amount of boot disk provided in GB (200)
*/ */
Long getDisk(); Integer getDisk();
/** /**
* Amount of total transfer bandwidth in GB * Determines platforms this can support
*/ */
Long getBandwidth(); boolean supportsArchitecture(Architecture architecture);
/**
* Hourly price of this server in USD, estimated if monthly.
*/
Float getPrice();
/**
* Other variables present that the provider supports
*/
Map<String, String> getExtra();
} }

View File

@ -19,8 +19,46 @@
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
/** /**
* Configured operating system used to start nodes.
*
* @author Adrian Cole * @author Adrian Cole
*/ */
public enum Profile { public interface Template extends Cloneable {
SMALLEST, MEDIUM, FASTEST
/**
* configure this template to the smallest size.
*/
Template smallest();
/**
* configure this template to the fastest size.
*/
Template fastest();
/**
* configure this template to the largest size.
*/
Template biggest();
/**
* Configure this template to use a specific operating system image.
*/
Template os(OperatingSystem os);
/**
* Configure this template to start in a specific location
*/
Template inLocation(String location);
/**
* Image that suits the requirements.
*
*/
Image getImage();
/**
* Size that suits the requirements.
*/
Size getSize();
} }

View File

@ -0,0 +1,171 @@
/**
*
* 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.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
/**
* @author Adrian Cole
*/
public class ImageImpl implements Image {
private final String id;
private final String description;
private final OperatingSystem operatingSystem;
private final String version;
private final String location;
private final Architecture architecture;
public ImageImpl(String id, String description, OperatingSystem operatingSystem, String version,
String location, Architecture architecture) {
this.id = id;
this.description = description;
this.operatingSystem = operatingSystem;
this.version = version;
this.location = location;
this.architecture = architecture;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ImageImpl other = (ImageImpl) obj;
if (architecture == null) {
if (other.architecture != null)
return false;
} else if (!architecture.equals(other.architecture))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "ImageImpl [architecture=" + architecture + ", description=" + description + ", id="
+ id + ", location=" + location + ", operatingSystem=" + operatingSystem
+ ", version=" + version + "]";
}
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return id;
}
/**
* {@inheritDoc}
*/
@Override
public String getDescription() {
return description;
}
/**
* {@inheritDoc}
*/
@Override
public OperatingSystem getOperatingSystem() {
return operatingSystem;
}
/**
* {@inheritDoc}
*/
@Override
public String getVersion() {
return version;
}
/**
* {@inheritDoc}
*/
@Override
public String getLocation() {
return location;
}
/**
* {@inheritDoc}
*/
@Override
public Architecture getArchitecture() {
return architecture;
}
}

View File

@ -0,0 +1,138 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.compute.domain.internal;
import java.util.Set;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Size;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
*/
public class SizeImpl implements Size {
private final Integer cores;
private final Integer ram;
private final Integer disk;
private final Set<Architecture> supportedArchitectures = Sets.newHashSet();
public SizeImpl(Integer cores, Integer ram, Integer disk,
Iterable<Architecture> supportedArchitectures) {
this.cores = cores;
this.ram = ram;
this.disk = disk;
Iterables.addAll(this.supportedArchitectures, supportedArchitectures);
}
/**
* {@inheritDoc}
*/
@Override
public Integer getCores() {
return cores;
}
/**
* {@inheritDoc}
*/
@Override
public Integer getRam() {
return ram;
}
/**
* {@inheritDoc}
*/
@Override
public Integer getDisk() {
return disk;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cores == null) ? 0 : cores.hashCode());
result = prime * result + ((disk == null) ? 0 : disk.hashCode());
result = prime * result + ((ram == null) ? 0 : ram.hashCode());
result = prime * result
+ ((supportedArchitectures == null) ? 0 : supportedArchitectures.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SizeImpl other = (SizeImpl) obj;
if (cores == null) {
if (other.cores != null)
return false;
} else if (!cores.equals(other.cores))
return false;
if (disk == null) {
if (other.disk != null)
return false;
} else if (!disk.equals(other.disk))
return false;
if (ram == null) {
if (other.ram != null)
return false;
} else if (!ram.equals(other.ram))
return false;
if (supportedArchitectures == null) {
if (other.supportedArchitectures != null)
return false;
} else if (!supportedArchitectures.equals(other.supportedArchitectures))
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "SizeImpl [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]";
}
/**
* {@inheritDoc}
*/
@Override
public int compareTo(Size o) {
return (this == o) ? 0 : getCores().compareTo(o.getCores());
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsArchitecture(Architecture architecture) {
return supportedArchitectures.contains(architecture);
}
}

View File

@ -28,7 +28,7 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ComputeUtils { public class ComputeUtils {
public static Iterable<ComputeMetadata> filterByName(Iterable<ComputeMetadata> nodes, public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
final String name) { final String name) {
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() { return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
@Override @Override

View File

@ -35,12 +35,12 @@ import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl; import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -73,17 +73,18 @@ public class RimuHostingComputeService implements ComputeService {
this.rhClient = rhClient; this.rhClient = rhClient;
} }
private Map<Image, String> imageNameMap = ImmutableMap.<Image, String> builder().put( private Map<OperatingSystem, String> imageNameMap = ImmutableMap
Image.CENTOS_53, "centos53").put(Image.UBUNTU_90, "ubuntu904").build(); .<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "centos53").put(
private Map<Profile, String> profileNameMap = ImmutableMap.<Profile, String> builder().put( OperatingSystem.UBUNTU, "ubuntu904").build();
Profile.SMALLEST, "MIRO1B").build();
// private Map<Size, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
// Profile.SMALLEST, "MIRO1B").build();
@Override @Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, public CreateNodeResponse runNode(String name, Template template) {
Image image) {
NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap
.get(image), "image not supported: " + image), checkNotNull(profileNameMap .get(template.getImage().getOperatingSystem()), "os not supported: "
.get(profile), "profile not supported: " + profile)); + template.getImage().getOperatingSystem()), "MIRO1B");
return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(), return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(),
serverResponse.getServer().getName(), "default", null, ImmutableMap serverResponse.getServer().getName(), "default", null, ImmutableMap
.<String, String> of(), .<String, String> of(),
@ -138,7 +139,17 @@ public class RimuHostingComputeService implements ComputeService {
} }
@Override @Override
public Map<String, Size> getSizes() { public Template createTemplateInLocation(String location) {
return null;
}
@Override
public Set<? extends Size> listSizes() {
return null;
}
@Override
public Set<? extends Template> listTemplates() {
return null; return null;
} }
} }

View File

@ -19,37 +19,30 @@
package org.jclouds.rimuhosting.miro.compute; package org.jclouds.rimuhosting.miro.compute;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.easymock.EasyMock.expect; import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
import org.jclouds.rimuhosting.miro.data.CreateOptions;
import org.jclouds.rimuhosting.miro.data.NewServerData;
import org.jclouds.rimuhosting.miro.domain.IpAddresses;
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.ssh.ExecResponse; import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient; import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException; import org.jclouds.ssh.SshException;
@ -59,7 +52,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -68,29 +60,34 @@ import com.google.inject.Injector;
*/ */
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest") @Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest")
public class RimuHostingComputeServiceLiveTest { public class RimuHostingComputeServiceLiveTest {
private static final String service = "rimuhosting";
protected SshClient.Factory sshFactory; protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name") + ".rimuhosting"; private String nodeName = System.getProperty("user.name") + service;
private RetryablePredicate<InetSocketAddress> socketTester; private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node; private CreateNodeResponse node;
private ComputeServiceContext context; private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() throws IOException { public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); IOException {
context = new ComputeServiceContextFactory().createContext("rimuhosting", key, key, String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = new ComputeServiceContextFactory().createContext(service, user, password,
ImmutableSet.of(new Log4JLoggingModule()), new Properties()); ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule()); Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
} }
public void testCreate() throws Exception { public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix, Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest();
Profile.SMALLEST, Image.CENTOS_53); node = client.runNode(nodeName, template);
assertNotNull(node.getId()); assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH); assertEquals(node.getLoginType(), LoginType.SSH);
@ -105,7 +102,7 @@ public class RimuHostingComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate") @Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception { public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType()); assertEquals(metadata.getLoginType(), node.getLoginType());
@ -115,13 +112,27 @@ public class RimuHostingComputeServiceLiveTest {
} }
public void testList() throws Exception { public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) { for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null; assert node.getId() != null;
assert node.getLocation() != null; assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE); assertEquals(node.getType(), ComputeType.NODE);
} }
} }
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException { private void sshPing() throws IOException {
try { try {
doCheckKey(); doCheckKey();
@ -155,65 +166,8 @@ public class RimuHostingComputeServiceLiveTest {
@AfterTest @AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException { void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null) if (node != null)
context.getComputeService().destroyNode(node); client.destroyNode(node);
context.close(); context.close();
} }
public void testParseInetAddress() throws UnknownHostException {
Server rhServer = createMock(Server.class);
IpAddresses addresses = createMock(IpAddresses.class);
expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce();
expect(addresses.getPrimaryIp()).andReturn("127.0.0.1");
expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.of("www.yahoo.com"));
replay(rhServer);
replay(addresses);
// assertEquals(Sets
// .newLinkedHashSet(RimuHostingCreateNodeResponse.getPublicAddresses(rhServer)),
// ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress
// .getByName("www.yahoo.com")));
}
@Test(enabled = false)
public void test() throws UnknownHostException {
NewServerResponse nsResponse = createMock(NewServerResponse.class);
Server rhServer = createMock(Server.class);
expect(nsResponse.getServer()).andReturn(rhServer).atLeastOnce();
expect(rhServer.getId()).andReturn(new Long(1));
expect(rhServer.getName()).andReturn("name");
IpAddresses addresses = createMock(IpAddresses.class);
expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce();
expect(addresses.getPrimaryIp()).andReturn("127.0.0.1");
expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.<String> of());
NewServerData data = createMock(NewServerData.class);
expect(nsResponse.getNewInstanceRequest()).andReturn(data).atLeastOnce();
CreateOptions options = createMock(CreateOptions.class);
expect(data.getCreateOptions()).andReturn(options);
expect(options.getPassword()).andReturn("password");
replay(nsResponse);
replay(rhServer);
replay(addresses);
replay(data);
replay(options);
// RimuHostingCreateNodeResponse response = new RimuHostingCreateNodeResponse(nsResponse);
// assertEquals(response.getId(), "1");
// assertEquals(response.getName(), "name");
// assertEquals(response.getPublicAddresses(), ImmutableSet.<InetAddress> of(InetAddress
// .getByName("127.0.0.1")));
// assertEquals(response.getPrivateAddresses(), ImmutableSet.<InetAddress> of());
// assertEquals(response.getLoginPort(), 22);
// assertEquals(response.getLoginType(), LoginType.SSH);
// assertEquals(response.getCredentials(), new Credentials("root", "password"));
}
} }

View File

@ -72,7 +72,7 @@
<target name="create" description="create the node ${jclouds.compute.nodename}" depends="destroy" > <target name="create" description="create the node ${jclouds.compute.nodename}" depends="destroy" >
<compute action="create" provider="${jclouds.compute.url}"> <compute action="create" provider="${jclouds.compute.url}">
<node name="${jclouds.compute.nodename}" image="UBUNTU_JEOS_90" profile="SMALLEST" <node name="${jclouds.compute.nodename}" os="UBUNTU" size="SMALLEST"
hostproperty="host" usernameproperty="username" passwordproperty="password" /> hostproperty="host" usernameproperty="username" passwordproperty="password" />
</compute> </compute>

View File

@ -94,7 +94,7 @@
<property name="location" value="default" /> <property name="location" value="default" />
<target name="create" description="create the node ${nodename}"> <target name="create" description="create the node ${nodename}">
<property name="image" value="UBUNTU_90" /> <property name="os" value="UBUNTU" />
<input <input
message="What do you want to name your node?" message="What do you want to name your node?"
@ -102,7 +102,7 @@
/> />
<compute action="create" provider="${jclouds.compute.url}"> <compute action="create" provider="${jclouds.compute.url}">
<node name="${nodename}" location="${location}" image="${image}" profile="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" /> <node name="${nodename}" location="${location}" os="${os}" size="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
</compute> </compute>
</target> </target>

View File

@ -35,9 +35,9 @@ import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeUtils; import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.http.HttpUtils; import org.jclouds.http.HttpUtils;
@ -187,12 +187,21 @@ public class ComputeTask extends Task {
} }
private void create(ComputeService computeService) { private void create(ComputeService computeService) {
log(String.format("create name: %s, profile: %s, image: %s", nodeElement.getName(), log(String.format("create name: %s, size: %s, os: %s", nodeElement.getName(), nodeElement
nodeElement.getProfile(), nodeElement.getImage())); .getSize(), nodeElement.getOs()));
CreateNodeResponse createdNode = computeService.startNodeInLocation( Template template = computeService.createTemplateInLocation(nodeElement.getLocation());
nodeElement.getLocation(), nodeElement.getName(), Profile.valueOf(nodeElement template.os(OperatingSystem.valueOf(nodeElement.getOs()));
.getProfile().toUpperCase()), Image.valueOf(nodeElement.getImage() if (nodeElement.getSize().equalsIgnoreCase("smallest")) {
.toUpperCase())); template.smallest();
} else if (nodeElement.getSize().equalsIgnoreCase("fastest")) {
template.fastest();
} else if (nodeElement.getSize().equalsIgnoreCase("biggest")) {
template.biggest();
} else {
throw new BuildException("size: " + nodeElement.getSize()
+ " not supported. valid sizes are smallest, fastest, biggest");
}
CreateNodeResponse createdNode = computeService.runNode(nodeElement.getName(), template);
log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdNode.getId(), log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdNode.getId(),
createdNode.getName(), createdNode.getLoginType().toString().toLowerCase(), createdNode.getName(), createdNode.getLoginType().toString().toLowerCase(),
createdNode.getCredentials().account, createdNode.getCredentials().key, createdNode createdNode.getCredentials().account, createdNode.getCredentials().key, createdNode
@ -221,7 +230,7 @@ public class ComputeTask extends Task {
private void destroy(ComputeService computeService) { private void destroy(ComputeService computeService) {
log(String.format("destroy name: %s", nodeElement.getName())); log(String.format("destroy name: %s", nodeElement.getName()));
Iterable<ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
.listNodes(), nodeElement.getName()); .listNodes(), nodeElement.getName());
for (ComputeMetadata node : nodesThatMatch) { for (ComputeMetadata node : nodesThatMatch) {
log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName())); log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName()));
@ -231,7 +240,7 @@ public class ComputeTask extends Task {
private void get(ComputeService computeService) { private void get(ComputeService computeService) {
log(String.format("get name: %s", nodeElement.getName())); log(String.format("get name: %s", nodeElement.getName()));
Iterable<ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
.listNodes(), nodeElement.getName()); .listNodes(), nodeElement.getName());
for (ComputeMetadata node : nodesThatMatch) { for (ComputeMetadata node : nodesThatMatch) {
logDetails(computeService, node); logDetails(computeService, node);

View File

@ -24,8 +24,8 @@ package org.jclouds.tools.ant.taskdefs.compute;
*/ */
public class NodeElement { public class NodeElement {
private String name; private String name;
private String profile; private String size;
private String image; private String os;
private String passwordproperty; private String passwordproperty;
private String keyfi1le; private String keyfi1le;
private String hostproperty; private String hostproperty;
@ -49,22 +49,6 @@ public class NodeElement {
this.name = name; this.name = name;
} }
String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
String getUsernameproperty() { String getUsernameproperty() {
return usernameproperty; return usernameproperty;
} }
@ -124,4 +108,20 @@ public class NodeElement {
return keyfi1le; return keyfi1le;
} }
public void setSize(String size) {
this.size = size;
}
public String getSize() {
return size;
}
public void setOs(String os) {
this.os = os;
}
public String getOs() {
return os;
}
} }

View File

@ -26,7 +26,7 @@ import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
@ -49,17 +49,16 @@ public class VCloudComputeClient {
private final VCloudClient tmClient; private final VCloudClient tmClient;
@Inject @Inject
public VCloudComputeClient(VCloudClient tmClient, public VCloudComputeClient(VCloudClient tmClient, Predicate<String> successTester) {
Predicate<String> successTester) {
this.tmClient = tmClient; this.tmClient = tmClient;
this.taskTester = successTester; this.taskTester = successTester;
} }
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put( private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap
Image.CENTOS_53, "1").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put( .<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "1").put(
Image.UBUNTU_JEOS_90, "11").build(); OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "11").build();
public Map<String, String> start(String name, Image image, int minCores, int minMegs, public Map<String, String> start(String name, OperatingSystem image, int minCores, int minMegs,
long diskSize, Map<String, String> properties) { long diskSize, Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image); checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
String templateId = imageCatalogIdMap.get(image); String templateId = imageCatalogIdMap.get(image);
@ -68,9 +67,9 @@ public class VCloudComputeClient {
.debug( .debug(
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ", ">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
vDCId, name, templateId, minCores, minMegs, diskSize, properties); vDCId, name, templateId, minCores, minMegs, diskSize, properties);
VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, templateId,
templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores) InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(minMegs)
.memory(minMegs).disk(diskSize).productProperties(properties)); .disk(diskSize).productProperties(properties));
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId()); logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
logger.debug(">> deploying vApp(%s)", vAppResponse.getId()); logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
@ -85,7 +84,8 @@ public class VCloudComputeClient {
// "powerOn", VAppStatus.ON); // "powerOn", VAppStatus.ON);
logger.debug("<< on vApp(%s)", vApp.getId()); logger.debug("<< on vApp(%s)", vApp.getId());
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password", null); return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password",
null);
} }
/** /**

View File

@ -28,7 +28,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType; import org.jclouds.vcloud.domain.ResourceType;
@ -59,7 +59,8 @@ public class VCloudComputeClientLiveTest {
private String id; private String id;
private InetAddress privateAddress; private InetAddress privateAddress;
public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll("\\.",""); public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll(
"\\.", "");
private static class Expectation { private static class Expectation {
final long hardDisk; final long hardDisk;
@ -71,20 +72,20 @@ public class VCloudComputeClientLiveTest {
} }
} }
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder() private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
.put(Image.CENTOS_53, .<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.RHEL_53, OperatingSystem.RHEL,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put( OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build(); .build();
private Predicate<InetAddress> addressTester; private Predicate<InetAddress> addressTester;
@Test @Test
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException { IOException {
Image toTest = Image.CENTOS_53; OperatingSystem toTest = OperatingSystem.CENTOS;
String serverName = getCompatibleServerName(toTest); String serverName = getCompatibleServerName(toTest);
int processorCount = 1; int processorCount = 1;
@ -101,10 +102,10 @@ public class VCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON); assertEquals(vApp.getStatus(), VAppStatus.ON);
} }
private String getCompatibleServerName(Image toTest) { private String getCompatibleServerName(OperatingSystem toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE String serverName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, toTest.toString())
.to(CaseFormat.LOWER_CAMEL, toTest.toString()).substring(0, .substring(0,
toTest.toString().length()-1 <= 15 ? toTest.toString().length()-1 : 14); toTest.toString().length() - 1 <= 15 ? toTest.toString().length() - 1 : 14);
return serverName; return serverName;
} }
@ -146,8 +147,8 @@ public class VCloudComputeClientLiveTest {
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
Injector injector = new VCloudContextBuilder(new VCloudPropertiesBuilder( Injector injector = new VCloudContextBuilder(new VCloudPropertiesBuilder(
URI.create(endpoint), account, key).build()).withModules( URI.create(endpoint), account, key).build()).withModules(new Log4JLoggingModule(),
new Log4JLoggingModule(), new JschSshClientModule()).buildInjector(); new JschSshClientModule()).buildInjector();
client = injector.getInstance(VCloudComputeClient.class); client = injector.getInstance(VCloudComputeClient.class);
tmClient = injector.getInstance(VCloudClient.class); tmClient = injector.getInstance(VCloudClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() { addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {

View File

@ -18,15 +18,12 @@
*/ */
package org.jclouds.vcloud.hostingdotcom.compute; package org.jclouds.vcloud.hostingdotcom.compute;
import static com.google.common.base.Preconditions.checkArgument;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Map; import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import org.jclouds.compute.domain.Image;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp; import org.jclouds.vcloud.domain.VApp;
@ -57,34 +54,15 @@ public class HostingDotComVCloudComputeClient {
this.taskTester = successTester; this.taskTester = successTester;
} }
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put( public Map<String, String> start(String vDCId, String name, String templateId, int minCores,
Image.CENTOS_53, "3").build(); int minMegs, long diskSize, Map<String, String> properties) {
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/1"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="Plesk (Linux) 64-bit Template" />
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/2"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="Windows 2008 Datacenter 64 Bit Template" />
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/3"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="Cent OS 64 Bit Template" />
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/4"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="cPanel (Linux) 64 Bit Template" />
public Map<String, String> start(String name, Image image, int minCores, int minMegs,
long diskSize, Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
String templateId = imageCatalogIdMap.get(image);
String vDCId = tmClient.getDefaultVDC().getId();
logger logger
.debug( .debug(
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ", ">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
vDCId, name, templateId, minCores, minMegs, diskSize, properties); vDCId, name, templateId, minCores, minMegs, diskSize, properties);
HostingDotComVApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, HostingDotComVApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name,
templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores) templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(
.memory(minMegs).disk(diskSize).productProperties(properties)); minMegs).disk(diskSize).productProperties(properties));
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId()); logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
logger.debug(">> deploying vApp(%s)", vAppResponse.getId()); logger.debug(">> deploying vApp(%s)", vAppResponse.getId());

View File

@ -28,6 +28,7 @@ import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
@ -38,8 +39,8 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -65,6 +66,9 @@ public class HostingDotComVCloudComputeService implements ComputeService {
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final HostingDotComVCloudComputeClient computeClient; private final HostingDotComVCloudComputeClient computeClient;
private final HostingDotComVCloudClient client; private final HostingDotComVCloudClient client;
private final Set<? extends Image> images;
private final Set<? extends Size> sizes;
private final Provider<Set<HostingDotComVCloudTemplate>> templates;
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put( .<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
@ -74,25 +78,28 @@ public class HostingDotComVCloudComputeService implements ComputeService {
@Inject @Inject
public HostingDotComVCloudComputeService(HostingDotComVCloudClient client, public HostingDotComVCloudComputeService(HostingDotComVCloudClient client,
HostingDotComVCloudComputeClient computeClient) { HostingDotComVCloudComputeClient computeClient, Set<? extends Image> images,
Set<? extends Size> sizes, Provider<Set<HostingDotComVCloudTemplate>> templates) {
this.client = client; this.client = client;
this.computeClient = computeClient; this.computeClient = computeClient;
this.images = images;
this.sizes = sizes;
this.templates = templates;
} }
@Override @Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, public CreateNodeResponse runNode(String name, Template template) {
Image image) { checkNotNull(template.getImage().getLocation(), "location");
if (checkNotNull(location, "location").equalsIgnoreCase("default")) Map<String, String> metaMap = computeClient.start(template.getImage().getLocation(), name,
location = client.getDefaultVDC().getId(); template.getImage().getId(), template.getSize().getCores(), template.getSize()
Map<String, String> metaMap = computeClient.start(name, image, 1, 512, (10l * 1025 * 1024), .getRam(), template.getSize().getDisk(), ImmutableMap.<String, String> of());
ImmutableMap.<String, String> of());
VApp vApp = client.getVApp(metaMap.get("id")); VApp vApp = client.getVApp(metaMap.get("id"));
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(), return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage()
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()), .getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(),
vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22, vAppStatusToNodeState.get(vApp.getStatus()), vApp.getNetworkToAddresses().values(),
LoginType.SSH, new Credentials(metaMap.get("username"), metaMap.get("password")), ImmutableSet.<InetAddress> of(), 22, LoginType.SSH, new Credentials(metaMap
ImmutableMap.<String, String> of()); .get("username"), metaMap.get("password")), ImmutableMap
.<String, String> of());
} }
@Override @Override
@ -105,10 +112,10 @@ public class HostingDotComVCloudComputeService implements ComputeService {
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) { private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
VApp vApp = client.getVApp(id); VApp vApp = client.getVApp(id);
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(),
.getLocation(), ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
.getStatus()), vApp.getNetworkToAddresses().values(), ImmutableSet vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22,
.<InetAddress> of(), 22, LoginType.SSH, ImmutableMap.<String, String> of()); LoginType.SSH, ImmutableMap.<String, String> of());
} }
@Override @Override
@ -132,7 +139,17 @@ public class HostingDotComVCloudComputeService implements ComputeService {
} }
@Override @Override
public Map<String, Size> getSizes() { public Template createTemplateInLocation(String location) {
return null;// TODO return new HostingDotComVCloudTemplate(client, images, sizes, location);
}
@Override
public Set<? extends Size> listSizes() {
return sizes;
}
@Override
public Set<? extends Template> listTemplates() {
return templates.get();
} }
} }

View File

@ -0,0 +1,180 @@
package org.jclouds.vcloud.hostingdotcom.compute;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
public class HostingDotComVCloudTemplate implements Template {
private final HostingDotComVCloudClient client;
private final Set<? extends Image> images;
private final Set<? extends Size> sizes;
private Size size;
private String vDC;
private OperatingSystem operatingSystem;
private transient Image image;
public HostingDotComVCloudTemplate(HostingDotComVCloudClient 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);
}
HostingDotComVCloudTemplate(HostingDotComVCloudClient 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 HostingDotComVCloudTemplate(client, images, sizes, vDC, size, operatingSystem,
image);
}
public String getvDC() {
return vDC;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HostingDotComVCloudTemplate other = (HostingDotComVCloudTemplate) obj;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
if (vDC == null) {
if (other.vDC != null)
return false;
} else if (!vDC.equals(other.vDC))
return false;
return true;
}
@Override
public String toString() {
return "HostingDotComVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
+ ", size=" + size + ", vDC=" + vDC + "]";
}
}

View File

@ -18,16 +18,38 @@
*/ */
package org.jclouds.vcloud.hostingdotcom.compute.config; package org.jclouds.vcloud.hostingdotcom.compute.config;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient; import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeService; import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeService;
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudTemplate;
import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudContextModule; import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudContextModule;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -48,8 +70,70 @@ public class HostingDotComVCloudComputeServiceContextModule extends
@Provides @Provides
@Singleton @Singleton
ComputeServiceContext provideContext(ComputeService computeService, ComputeServiceContext provideContext(ComputeService computeService,
RestContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudAsyncClient> context) { RestContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> context) {
return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudAsyncClient>( return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient>(
computeService, context); computeService, context);
} }
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
@Provides
@Singleton
Set<? extends Image> provideImages(VCloudClient client, LogHolder holder) {
Set<Image> images = Sets.newLinkedHashSet();
holder.logger.debug(">> providing images");
Catalog response = client.getDefaultCatalog();
String vDC = client.getDefaultVDC().getId();
for (NamedResource resource : response.values()) {
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
CatalogItem item = client.getCatalogItem(resource.getId());
OperatingSystem myOs = OperatingSystem.UNKNOWN;
for (OperatingSystem os : OperatingSystem.values()) {
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
myOs = os;
}
}
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
: Architecture.X86_64;
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null,
vDC, arch));
}
}
}
holder.logger.debug("<< images(%d)", images.size());
return images;
}
@Provides
@Singleton
Set<? extends Size> provideSizes(HostingDotComVCloudClient client, Set<? extends Image> images,
LogHolder holder) {
return ImmutableSet.<Size> of(new SizeImpl(1, 512, (int) (10l * 1025 * 1024), ImmutableSet
.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
}
@Provides
@Singleton
Set<HostingDotComVCloudTemplate> provideTemplates(HostingDotComVCloudClient client,
Set<? extends Image> images, Set<? extends Size> sizes, LogHolder holder) {
Set<HostingDotComVCloudTemplate> templates = Sets.newHashSet();
holder.logger.debug(">> generating templates");
String vDC = client.getDefaultVDC().getId();
for (Size size : sizes) {
for (Image image : images) {
templates.add(new HostingDotComVCloudTemplate(client, images, sizes, vDC, size, image
.getOperatingSystem(), image));
}
}
holder.logger.debug("<< templates(%d)", templates.size());
return templates;
}
} }

View File

@ -27,7 +27,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType; import org.jclouds.vcloud.domain.ResourceType;
@ -73,13 +73,9 @@ public class HostingDotComVCloudComputeClientLiveTest {
} }
} }
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder() private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
.put(Image.CENTOS_53, .<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put( new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)"))
Image.RHEL_53,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
.build(); .build();
private Predicate<InetAddress> addressTester; private Predicate<InetAddress> addressTester;
@ -87,7 +83,7 @@ public class HostingDotComVCloudComputeClientLiveTest {
@Test(enabled = true) @Test(enabled = true)
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException { IOException {
Image toTest = Image.CENTOS_53; OperatingSystem toTest = OperatingSystem.CENTOS;
String serverName = getCompatibleServerName(toTest); String serverName = getCompatibleServerName(toTest);
int processorCount = 1; int processorCount = 1;
@ -95,7 +91,8 @@ public class HostingDotComVCloudComputeClientLiveTest {
long disk = 10 * 1025 * 1024; long disk = 10 * 1025 * 1024;
Map<String, String> properties = ImmutableMap.of("foo", "bar"); Map<String, String> properties = ImmutableMap.of("foo", "bar");
id = client.start(serverName, toTest, processorCount, memory, disk, properties).get("id"); id = client.start(hostingClient.getDefaultVDC().getId(), serverName, "3", processorCount,
memory, disk, properties).get("id");
Expectation expectation = expectationMap.get(toTest); Expectation expectation = expectationMap.get(toTest);
VApp vApp = hostingClient.getVApp(id); VApp vApp = hostingClient.getVApp(id);
@ -104,7 +101,7 @@ public class HostingDotComVCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON); assertEquals(vApp.getStatus(), VAppStatus.ON);
} }
private String getCompatibleServerName(Image toTest) { private String getCompatibleServerName(OperatingSystem toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0, .to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
toTest.toString().length() <= 15 ? toTest.toString().length() : 14); toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
@ -148,8 +145,8 @@ public class HostingDotComVCloudComputeClientLiveTest {
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
Injector injector = new HostingDotComVCloudContextBuilder( Injector injector = new HostingDotComVCloudContextBuilder(
new HostingDotComVCloudPropertiesBuilder(account, key).build()) new HostingDotComVCloudPropertiesBuilder(account, key).build()).withModules(
.withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector(); new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
client = injector.getInstance(HostingDotComVCloudComputeClient.class); client = injector.getInstance(HostingDotComVCloudComputeClient.class);
hostingClient = injector.getInstance(HostingDotComVCloudClient.class); hostingClient = injector.getInstance(HostingDotComVCloudClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() { addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {

View File

@ -20,23 +20,28 @@
package org.jclouds.vcloud.hostingdotcom.compute; package org.jclouds.vcloud.hostingdotcom.compute;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
@ -48,6 +53,7 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -59,30 +65,35 @@ import com.google.inject.Injector;
*/ */
@Test(groups = "live", enabled = true, sequential = true, testName = "compute.HostingDotComVCloudComputeServiceLiveTest") @Test(groups = "live", enabled = true, sequential = true, testName = "compute.HostingDotComVCloudComputeServiceLiveTest")
public class HostingDotComVCloudComputeServiceLiveTest { public class HostingDotComVCloudComputeServiceLiveTest {
private static final String service = "hostingdotcom";
private static final OperatingSystem testOS = CENTOS;
protected SshClient.Factory sshFactory; protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name"); private String nodeName = service;
private RetryablePredicate<InetSocketAddress> socketTester; private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node; private CreateNodeResponse node;
private ComputeServiceContext context; private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException { public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = HostingDotComVCloudComputeServiceContextFactory.createContext(user, password, context = new ComputeServiceContextFactory().createContext(service, user, password,
new Log4JLoggingModule()); ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule()); Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
} }
public void testCreate() throws Exception { public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix, Template template = client.createTemplateInLocation("default").os(testOS).smallest();
Profile.SMALLEST, Image.UBUNTU_90); node = client.runNode(nodeName, template);
assertNotNull(node.getId()); assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH); assertEquals(node.getLoginType(), LoginType.SSH);
@ -97,7 +108,7 @@ public class HostingDotComVCloudComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate") @Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception { public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType()); assertEquals(metadata.getLoginType(), node.getLoginType());
@ -107,13 +118,27 @@ public class HostingDotComVCloudComputeServiceLiveTest {
} }
public void testList() throws Exception { public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) { for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null; assert node.getId() != null;
assert node.getLocation() != null; assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE); assertEquals(node.getType(), ComputeType.NODE);
} }
} }
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException { private void sshPing() throws IOException {
try { try {
doCheckKey(); doCheckKey();
@ -147,7 +172,7 @@ public class HostingDotComVCloudComputeServiceLiveTest {
@AfterTest @AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException { void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null) if (node != null)
context.getComputeService().destroyNode(node); client.destroyNode(node);
context.close(); context.close();
} }
} }

View File

@ -1,29 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com> Copyright (C) 2009 Cloud Conscious, LLC.
<info@cloudconscious.com>
==================================================================== ====================================================================
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed
Unless required by applicable law or agreed to in writing, software under the License is distributed on an "AS IS" BASIS, WITHOUT
distributed under the License is distributed on an "AS IS" BASIS, WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
See the License for the specific language governing permissions and and limitations under the License.
limitations under the License.
==================================================================== ====================================================================
-->
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- <!--
For more configuration infromation and examples see the Apache Log4j For more configuration infromation and examples see the Apache
website: http://logging.apache.org/log4j/ Log4j website: http://logging.apache.org/log4j/
--> -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false"> debug="false">
@ -43,9 +42,9 @@
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" /> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!-- <!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n The full pattern: Date MS Priority [Category]
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) (Thread:NDC) Message\n <param name="ConversionPattern"
%m%n"/> value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
--> -->
</layout> </layout>
</appender> </appender>
@ -65,15 +64,13 @@
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" /> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!-- <!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n The full pattern: Date MS Priority [Category]
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) (Thread:NDC) Message\n <param name="ConversionPattern"
%m%n"/> value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
--> -->
</layout> </layout>
</appender> </appender>
<!-- A time/date based rolling appender --> <!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender"> <appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" /> <param name="File" value="target/test-data/jclouds-compute.log" />
@ -89,13 +86,16 @@
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" /> <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!-- <!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n The full pattern: Date MS Priority [Category]
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) (Thread:NDC) Message\n <param name="ConversionPattern"
%m%n"/> value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
--> -->
</layout> </layout>
</appender> </appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
@ -105,10 +105,6 @@
<appender-ref ref="WIREFILE" /> <appender-ref ref="WIREFILE" />
</appender> </appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<!-- ================ --> <!-- ================ -->
<!-- Limit categories --> <!-- Limit categories -->
<!-- ================ --> <!-- ================ -->
@ -123,25 +119,16 @@
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<category name="org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<category name="org.jclouds.predicates.SocketOpen"> <category name="org.jclouds.predicates.SocketOpen">
<priority value="TRACE" /> <priority value="TRACE" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<category name="org.jclouds.vcloud.predicates.TaskSuccess"> <category name="jclouds.compute">
<priority value="TRACE" /> <priority value="TRACE" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCCOMPUTE" />
</category> </category>
<category name="jclouds.http.wire"> <category name="jclouds.http.wire">
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />

View File

@ -31,7 +31,7 @@ import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task; import org.jclouds.vcloud.domain.Task;
@ -68,11 +68,13 @@ public class TerremarkVCloudComputeClient {
this.taskTester = successTester; this.taskTester = successTester;
} }
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put( private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap
Image.CENTOS_53, "6").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put( .<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "6").put(
Image.UBUNTU_JEOS_90, "11").put(Image.WEBAPPVM_93, "29").build(); OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "10").build();
public String start(String name, Image image, int minCores, int minMegs, // .put( OperatingSystem.UBUNTU_JEOS_90, "11").put(OperatingSystem.WEBAPPVM_93, "29")
public String start(String name, OperatingSystem image, int minCores, int minMegs,
Map<String, String> properties) { Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image); checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties); return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties);
@ -80,6 +82,12 @@ public class TerremarkVCloudComputeClient {
public String start(String name, String templateId, int minCores, int minMegs, public String start(String name, String templateId, int minCores, int minMegs,
Map<String, String> properties) { Map<String, String> properties) {
return this.start(tmClient.getDefaultVDC().getId(), name, templateId, minCores, minMegs,
properties);
}
public String start(String vdc, String name, String templateId, int minCores, int minMegs,
Map<String, String> properties) {
String vDCId = tmClient.getDefaultVDC().getId(); String vDCId = tmClient.getDefaultVDC().getId();
logger logger
.debug( .debug(

View File

@ -28,6 +28,7 @@ import java.util.Set;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
@ -38,8 +39,8 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size; import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl; import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl; import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -65,6 +66,9 @@ public class TerremarkVCloudComputeService implements ComputeService {
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final TerremarkVCloudComputeClient computeClient; private final TerremarkVCloudComputeClient computeClient;
private final TerremarkVCloudClient client; private final TerremarkVCloudClient client;
private Set<? extends Image> images;
private Set<? extends Size> sizes;
private Provider<Set<TerremarkVCloudTemplate>> templates;
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put( .<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
@ -74,21 +78,25 @@ public class TerremarkVCloudComputeService implements ComputeService {
@Inject @Inject
public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient, public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient,
TerremarkVCloudComputeClient computeClient) { TerremarkVCloudComputeClient computeClient, Set<? extends Image> images,
Set<? extends Size> sizes, Provider<Set<TerremarkVCloudTemplate>> templates) {
this.client = tmClient; this.client = tmClient;
this.computeClient = computeClient; this.computeClient = computeClient;
this.images = images;
this.sizes = sizes;
this.templates = templates;
} }
@Override @Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile, public CreateNodeResponse runNode(String name, Template template) {
Image image) { checkNotNull(template.getImage().getLocation(), "location");
if (checkNotNull(location, "location").equalsIgnoreCase("default")) String id = computeClient.start(template.getImage().getLocation(), name, template.getImage()
location = client.getDefaultVDC().getId(); .getId(), (int) template.getSize().getCores(), (int) template.getSize().getRam(),
String id = computeClient.start(name, image, 1, 512, ImmutableMap.<String, String> of()); ImmutableMap.<String, String> of());
VApp vApp = client.getVApp(id); VApp vApp = client.getVApp(id);
InetAddress publicIp = computeClient InetAddress publicIp = computeClient
.createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443); .createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443);
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(), return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage().getLocation(), vApp.getLocation(),
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()), ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
ImmutableSet.<InetAddress> of(publicIp), vApp.getNetworkToAddresses().values(), 22, ImmutableSet.<InetAddress> of(publicIp), vApp.getNetworkToAddresses().values(), 22,
LoginType.SSH, new Credentials("vcloud", "p4ssw0rd"), ImmutableMap LoginType.SSH, new Credentials("vcloud", "p4ssw0rd"), ImmutableMap
@ -99,8 +107,8 @@ public class TerremarkVCloudComputeService implements ComputeService {
public NodeMetadata getNodeMetadata(ComputeMetadata node) { public NodeMetadata getNodeMetadata(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not " checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType()); + node.getType());
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(node.getId(), return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(
"node.id")); node.getId(), "node.id"));
} }
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) { private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
@ -133,7 +141,17 @@ public class TerremarkVCloudComputeService implements ComputeService {
} }
@Override @Override
public Map<String, Size> getSizes() { public Template createTemplateInLocation(String location) {
return null;// TODO return new TerremarkVCloudTemplate(client, images, sizes, location);
}
@Override
public Set<? extends Size> listSizes() {
return sizes;
}
@Override
public Set<? extends Template> listTemplates() {
return templates.get();
} }
} }

View File

@ -0,0 +1,178 @@
package org.jclouds.vcloud.terremark.compute;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
public class TerremarkVCloudTemplate implements Template {
private final TerremarkVCloudClient client;
private final Set<? extends Image> images;
private final Set<? extends Size> sizes;
private Size size;
private String vDC;
private OperatingSystem operatingSystem;
private transient Image image;
public TerremarkVCloudTemplate(TerremarkVCloudClient 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);
}
TerremarkVCloudTemplate(TerremarkVCloudClient client, Set<? extends Image> images,
Set<? extends Size> sizes, String location) {
this(client, images, sizes, location, null, OperatingSystem.UBUNTU, null);
}
/**
* {@inheritDoc}
*/
@Override
public Size getSize() {
return size;
}
/**
* {@inheritDoc}
*/
@Override
public Image getImage() {
return image;
}
/**
* {@inheritDoc}
*/
@Override
public Template smallest() {
this.size = Iterables.get(sizes, 0);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template biggest() {
this.size = Iterables.getLast(sizes);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template fastest() {
this.size = Iterables.getLast(sizes);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template inLocation(String location) {
if (location.equalsIgnoreCase("default"))
location = client.getDefaultVDC().getId();
this.vDC = location;// TODO match vdc on template as well arch
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template os(OperatingSystem os) {
this.operatingSystem = os;
this.image = resolveTemplate(images, operatingSystem);
return this;
}
/**
* {@inheritDoc}
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return new TerremarkVCloudTemplate(client, images, sizes, vDC, size, operatingSystem, image);
}
public String getvDC() {
return vDC;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TerremarkVCloudTemplate other = (TerremarkVCloudTemplate) obj;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
if (vDC == null) {
if (other.vDC != null)
return false;
} else if (!vDC.equals(other.vDC))
return false;
return true;
}
@Override
public String toString() {
return "TerremarkVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
+ ", size=" + size + ", vDC=" + vDC + "]";
}
}

View File

@ -18,17 +18,42 @@
*/ */
package org.jclouds.vcloud.terremark.compute.config; package org.jclouds.vcloud.terremark.compute.config;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient; import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient; import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService; import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService;
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudTemplate;
import org.jclouds.vcloud.terremark.config.TerremarkVCloudContextModule; import org.jclouds.vcloud.terremark.config.TerremarkVCloudContextModule;
import org.jclouds.vcloud.terremark.domain.ComputeOptions;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.Provides; import com.google.inject.Provides;
/** /**
@ -53,4 +78,82 @@ public class TerremarkVCloudComputeServiceContextModule extends TerremarkVCloudC
computeService, context); computeService, context);
} }
private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize();
private static class ComputeOptionsToSize implements Function<ComputeOptions, Size> {
@Override
public Size apply(ComputeOptions from) {
return new SizeImpl(from.getProcessorCount(), (int) from.getMemory(), null, ImmutableSet
.<Architecture> of(Architecture.X86_32, Architecture.X86_64));
}
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
@Provides
@Singleton
Set<? extends Image> provideImages(VCloudClient client, LogHolder holder) {
Set<Image> images = Sets.newLinkedHashSet();
holder.logger.debug(">> providing images");
Catalog response = client.getDefaultCatalog();
String vDC = client.getDefaultVDC().getId();
for (NamedResource resource : response.values()) {
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
CatalogItem item = client.getCatalogItem(resource.getId());
OperatingSystem myOs = OperatingSystem.UNKNOWN;
for (OperatingSystem os : OperatingSystem.values()) {
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
myOs = os;
}
}
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
: Architecture.X86_64;
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null,
vDC, arch));
}
}
}
holder.logger.debug("<< images(%d)", images.size());
return images;
}
@Provides
@Singleton
Set<? extends Size> provideSizes(TerremarkVCloudClient client, Set<? extends Image> images,
LogHolder holder) {
Image anyImage = Iterables.get(images, 0);
holder.logger.debug(">> providing sizes");
LinkedHashSet<Size> sizes = Sets.newLinkedHashSet(Iterables.transform(client
.getComputeOptionsOfCatalogItem(anyImage.getId()), sizeConverter));
holder.logger.debug("<< sizes(%d)", sizes.size());
return sizes;
}
@Provides
@Singleton
Set<TerremarkVCloudTemplate> provideTemplates(TerremarkVCloudClient client,
Set<? extends Image> images, Set<? extends Size> sizes, LogHolder holder) {
Set<TerremarkVCloudTemplate> templates = Sets.newHashSet();
holder.logger.debug(">> generating templates");
String vDC = client.getDefaultVDC().getId();
for (Size size : sizes) {
for (Image image : images) {
templates.add(new TerremarkVCloudTemplate(client, images, sizes, vDC, size, image
.getOperatingSystem(), image));
}
}
holder.logger.debug("<< templates(%d)", templates.size());
return templates;
}
} }

View File

@ -27,7 +27,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType; import org.jclouds.vcloud.domain.ResourceType;
@ -73,18 +73,20 @@ public class TerremarkVCloudComputeClientLiveTest {
} }
} }
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder() private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
.put(Image.CENTOS_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")) .<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
.put(Image.RHEL_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")) new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
.put(Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put( OperatingSystem.RHEL,
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build(); new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (64-bit)"))
.build();
// .put(OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
private Predicate<InetAddress> addressTester; private Predicate<InetAddress> addressTester;
@Test @Test
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException, public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException { IOException {
Image toTest = Image.CENTOS_53; OperatingSystem toTest = OperatingSystem.CENTOS;
String serverName = getCompatibleServerName(toTest); String serverName = getCompatibleServerName(toTest);
int processorCount = 1; int processorCount = 1;
@ -100,7 +102,7 @@ public class TerremarkVCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON); assertEquals(vApp.getStatus(), VAppStatus.ON);
} }
private String getCompatibleServerName(Image toTest) { private String getCompatibleServerName(OperatingSystem toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0, .to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
toTest.toString().length() <= 15 ? toTest.toString().length() : 14); toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
@ -115,9 +117,8 @@ public class TerremarkVCloudComputeClientLiveTest {
@Test(dependsOnMethods = "testGetAnyPrivateAddress") @Test(dependsOnMethods = "testGetAnyPrivateAddress")
public void testSshLoadBalanceIp() { public void testSshLoadBalanceIp() {
InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22, InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22, 80,
80, 443, 8080); // / error 500
443, 8080); /// error 500
assert addressTester.apply(publicIp); assert addressTester.apply(publicIp);
// client.exec(publicIp, "uname -a"); // client.exec(publicIp, "uname -a");
} }

View File

@ -20,23 +20,29 @@
package org.jclouds.vcloud.terremark.compute; package org.jclouds.vcloud.terremark.compute;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType; import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse; import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType; import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile; import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen; import org.jclouds.predicates.SocketOpen;
@ -48,6 +54,7 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
@ -59,30 +66,35 @@ import com.google.inject.Injector;
*/ */
@Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest") @Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
public class TerremarkVCloudComputeServiceLiveTest { public class TerremarkVCloudComputeServiceLiveTest {
private static final String service = "terremark";
private static final OperatingSystem testOS = UBUNTU;
protected SshClient.Factory sshFactory; protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name"); private String nodeName = service;
private RetryablePredicate<InetSocketAddress> socketTester; private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node; private CreateNodeResponse node;
private ComputeServiceContext context; private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException { public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = TerremarkVCloudComputeServiceContextFactory.createContext(user, password, context = new ComputeServiceContextFactory().createContext(service, user, password,
new Log4JLoggingModule()); ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule()); Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class); sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class); SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
} }
public void testCreate() throws Exception { public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix, Template template = client.createTemplateInLocation("default").os(testOS).smallest();
Profile.SMALLEST, Image.UBUNTU_90); node = client.runNode(nodeName, template);
assertNotNull(node.getId()); assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22); assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH); assertEquals(node.getLoginType(), LoginType.SSH);
@ -97,7 +109,7 @@ public class TerremarkVCloudComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate") @Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception { public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node); NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId()); assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort()); assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType()); assertEquals(metadata.getLoginType(), node.getLoginType());
@ -107,13 +119,27 @@ public class TerremarkVCloudComputeServiceLiveTest {
} }
public void testList() throws Exception { public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) { for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null; assert node.getId() != null;
assert node.getLocation() != null; assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE); assertEquals(node.getType(), ComputeType.NODE);
} }
} }
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException { private void sshPing() throws IOException {
try { try {
doCheckKey(); doCheckKey();
@ -147,7 +173,7 @@ public class TerremarkVCloudComputeServiceLiveTest {
@AfterTest @AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException { void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null) if (node != null)
context.getComputeService().destroyNode(node); client.destroyNode(node);
context.close(); context.close();
} }
} }

View File

@ -67,6 +67,32 @@
</layout> </layout>
</appender> </appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender"> <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" /> <appender-ref ref="FILE" />
</appender> </appender>
@ -93,6 +119,11 @@
<priority value="DEBUG" /> <priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" /> <appender-ref ref="ASYNCWIRE" />
</category> </category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!--======================= --> <!--======================= -->
<!-- Setup the Root category --> <!-- Setup the Root category -->
<!-- ======================= --> <!-- ======================= -->